コード例 #1
0
ファイル: cart.cpp プロジェクト: gammy/wiimednafen
LYNX_HEADER CCart::DecodeHeader(const uint8 *data)
{
 LYNX_HEADER header;

 memcpy(header.magic, data, 4);
 data += 4;

 header.page_size_bank0 = MDFN_de16lsb(data);
 data += 2;

 header.page_size_bank1 = MDFN_de16lsb(data);
 data += 2;

 header.version = MDFN_de16lsb(data);
 data += 2;

 memcpy(header.cartname, data, 32);
 data += 32;

 memcpy(header.manufname, data, 16);
 data += 16;

 header.rotation = *data;
 data++;

 memcpy(header.spare, data, 5);
 data += 5;

 return(header);
}
コード例 #2
0
ファイル: gamepad.cpp プロジェクト: BadyRaty/Mednafen-Core
 virtual void Frame(const void *data)
 {
  uint16 new_buttons = MDFN_de16lsb((uint8 *)data);
  bool mode_changed = false;

  if((old_raw_buttons ^ new_buttons) & (1 << 12) & new_buttons)
  {
   mode1 = !mode1;
   mode_changed = true;
  }

  if((old_raw_buttons ^ new_buttons) & (1 << 14) & new_buttons)
  {
   mode2 = !mode2;
   mode_changed = true;
  }

  if(mode_changed)
   MDFN_DispMessage(_("Pad %d - MODE 1: %s, MODE 2: %s"), which + 1, (mode1 ? "B" : "A"), (mode2 ? "B" : "A"));

  buttons = new_buttons & ~( (1 << 12) | (1 << 14));
  buttons |= mode1 << 12;
  buttons |= mode2 << 14;

  old_raw_buttons = new_buttons;
  //printf("%d %08x\n", which, buttons);
 }
コード例 #3
0
ファイル: unif.cpp プロジェクト: Oggom/mednafen-git
static void DINF(Stream *fp)
{
 union
 {
  struct
  {
   char name[100];
   uint8 raw_date[4];
   char method[100];
  };
  uint8 raw[100 + 4 + 100];
 } dinf;
 uint8 d, m;
 uint16 y;

 fp->read(dinf.raw, sizeof(dinf.raw));

 d = dinf.raw_date[0];
 m = dinf.raw_date[1];
 y = MDFN_de16lsb(&dinf.raw_date[2]);

 dinf.name[99] = dinf.method[99] = 0;

 MDFN_RemoveControlChars(dinf.name);
 MDFN_RemoveControlChars(dinf.method);

 MDFN_printf(_("Dumped by: %s\n"), dinf.name);
 MDFN_printf(_("Dumped with: %s\n"), dinf.method);
 {
  const char* months[12]={_("January"),_("February"),_("March"),_("April"),_("May"),_("June"),_("July"),
		    _("August"),_("September"),_("October"),_("November"),_("December")};
  MDFN_printf(_("Dumped on: %s %d, %d\n"),months[(m-1)%12],d,y);
 }
}
コード例 #4
0
ファイル: file.cpp プロジェクト: RobertSzkutak/mednafenPSP
int MDFNFILE::read16le(uint16 *val)
{
 if((location + 2) > size)
  return 0;

 *val = MDFN_de16lsb(data + location);

 location += 2;

 return(1);
}
コード例 #5
0
ファイル: gamepad.cpp プロジェクト: gameblabla/mednafen-gcw
 virtual void TransformInput(uint8* data, const bool DisableSR) override
 {
  if(DisableSR)
  {
   uint16 tmp = MDFN_de16lsb(data);

   if((tmp & 0xC0) == 0xC0)
    tmp &= ~0xC0;

   MDFN_en16lsb(data, tmp);
  }
 }
コード例 #6
0
ファイル: dualanalog.cpp プロジェクト: Oggom/mednafen-git
void InputDevice_DualAnalog::UpdateInput(const void *data)
{
 uint8 *d8 = (uint8 *)data;

 buttons[0] = d8[0];
 buttons[1] = d8[1];

 for(int stick = 0; stick < 2; stick++)
 {
  for(int axis = 0; axis < 2; axis++)
  {
   const uint8* aba = &d8[2] + stick * 8 + axis * 4;
   int32 tmp;

   tmp = 32768 + MDFN_de16lsb(&aba[0]) - ((int32)MDFN_de16lsb(&aba[2]) * 32768 / 32767);
   tmp >>= 8;

   axes[stick][axis] = tmp;
  }
 }

 //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);
}
コード例 #7
0
ファイル: powerpad.cpp プロジェクト: k1ll/mednafen-git
void UpdatePP(int w, void *data)
{
    static const unsigned char shifttable[2][12] =
    {
        {8,9,0,1,11,7,4,2,10,6,5,3},
        {1,0,9,8,2,4,7,11,3,5,6,10}
    };
    const uint16 ind16 = MDFN_de16lsb((uint8*)data);

    pprdata[w] = 0;
    for(int x = 0; x < 12; x++)
    {
        pprdata[w] |= ((ind16 >> x) & 1) << shifttable[side][x];
    }
}
コード例 #8
0
ファイル: rom.cpp プロジェクト: Oggom/mednafen-git
static void rom_display_header(void)
{
	MDFN_printf(_("Name:    %s\n"), ngpc_rom.name);
	MDFN_printf(_("System:  "));

	if(rom_header->mode & 0x10)
	 MDFN_printf(_("Color"));
	else
	 MDFN_printf(_("Greyscale"));

	MDFN_printf("\n");

        MDFN_printf(_("Catalog:  %u (sub %u)\n"),
                             MDFN_de16lsb(rom_header->catalog),
                             rom_header->subCatalog);

        //Starting PC
        MDFN_printf(_("Starting PC:  0x%06X\n"), MDFN_de32lsb(rom_header->startPC) & 0xFFFFFF);
}
コード例 #9
0
ファイル: hes.cpp プロジェクト: gammy/wiimednafen
int PCE_HESLoad(const uint8 *buf, uint32 size)
{
 uint32 LoadAddr, LoadSize;
 uint32 CurPos;
 uint16 InitAddr;
 uint8 StartingSong;
 int TotalSongs;

 InitAddr = MDFN_de16lsb(&buf[0x6]);

 CurPos = 0x10;
 
 if(!(rom = (uint8 *)MDFN_malloc(0x88 * 8192, _("HES ROM"))))
 {
  return(0);
 }

 if(!(rom_backup = (uint8 *)MDFN_malloc(0x88 * 8192, _("HES ROM"))))
 {
  return(0);
 }

 memset(rom, 0, 0x88 * 8192);
 memset(rom_backup, 0, 0x88 * 8192);

 while(CurPos < (size - 0x10))
 {
  LoadSize = MDFN_de32lsb(&buf[CurPos + 0x4]);
  LoadAddr = MDFN_de32lsb(&buf[CurPos + 0x8]);

  //printf("Size: %08x(%d), Addr: %08x, La: %02x\n", LoadSize, LoadSize, LoadAddr, LoadAddr / 8192);

  CurPos += 0x10;

  if(((uint64)LoadSize + CurPos) > size)
  {
   uint32 NewLoadSize = size - CurPos;

   MDFN_printf(_("Warning:  HES is trying to load more data than is present in the file(%u attempted, %u left)!\n"), LoadSize, NewLoadSize);

   LoadSize = NewLoadSize;
  }

  // 0x88 * 8192 = 0x110000
  if(((uint64)LoadAddr + LoadSize) > 0x110000)
  {
   MDFN_printf(_("Warning:  HES is trying to load data past boundary.\n"));

   if(LoadAddr >= 0x110000)
    break;

   LoadSize = 0x110000 - LoadAddr;
  }

  memcpy(rom + LoadAddr, &buf[CurPos], LoadSize);
  CurPos += LoadSize;
 }

 for(int x = 0; x < 8; x++)
  mpr_start[x] = buf[0x8 + x];

 memcpy(rom_backup, rom, 0x88 * 8192);

 CurrentSong = StartingSong = buf[5];
 TotalSongs = 256;

 memset(IBP_Bank, 0, 0x2000);

 uint8 *IBP_WR = IBP_Bank + 0x1C00;

 for(int i = 0; i < 8; i++)
 {
  *IBP_WR++ = 0xA9;             // LDA (immediate)
  *IBP_WR++ = mpr_start[i];
  *IBP_WR++ = 0x53;             // TAM
  *IBP_WR++ = 1 << i;
 }

 *IBP_WR++ = 0xAD;              // LDA(absolute)
 *IBP_WR++ = 0x00;              //
 *IBP_WR++ = 0x1D;              //
 *IBP_WR++ = 0x20;               // JSR
 *IBP_WR++ = InitAddr;           //  JSR target LSB
 *IBP_WR++ = InitAddr >> 8;      //  JSR target MSB
 *IBP_WR++ = 0x58;               // CLI
 *IBP_WR++ = 0xFC;               // (Mednafen Special)
 *IBP_WR++ = 0x80;               // BRA
 *IBP_WR++ = 0xFD;               //  -3

 Player_Init(TotalSongs, NULL, NULL, NULL, NULL); //UTF8 **snames);

 for(int x = 0; x < 0x80; x++)
 {
  HuCPUFastMap[x] = rom;
  PCERead[x] = HESROMRead;
  PCEWrite[x] = HESROMWrite;
 }

 HuCPUFastMap[0xFF] = IBP_Bank - (0xFF * 8192);

 // FIXME:  If a HES rip tries to execute a SCSI command, the CD emulation code will probably crash.  Obviously, a HES rip shouldn't do this,
 // but Mednafen shouldn't crash either. ;)
 PCE_IsCD = 1;
 PCE_InitCD();

 ROMWriteWarningGiven = FALSE;

 return(1);
}
コード例 #10
0
ファイル: gamepad.cpp プロジェクト: gameblabla/mednafen-gcw
 virtual void Frame(const void *data) override
 {
  buttons = MDFN_de16lsb((uint8 *)data);
 }
コード例 #11
0
ファイル: nsfe.cpp プロジェクト: BadyRaty/Mednafen-Core
void LoadNSFE(NSFINFO *nfe, const uint8 *buf, int32 size, int info_only)
{
    const uint8 *nbuf = 0;

    size -= 4;
    buf += 4;

    while(size)
    {
        uint32 chunk_size;
        uint8 tb[4];

        if(size < 4)
            throw MDFN_Error(0, _("Unexpected EOF while reading NSFE."));

        chunk_size = MDFN_de32lsb(buf);

        size -= 4;
        buf += 4;
        if(size < 4)
            throw MDFN_Error(0, _("Unexpected EOF while reading NSFE."));

        memcpy(tb, buf, 4);

        buf += 4;
        size -= 4;

        if((int32)chunk_size < 0 || (int32)chunk_size > size)
            throw MDFN_Error(0, _("NSFE chunk \"%.4s\" size(%u) is invalid."), (char*)&tb[0], chunk_size);

        //printf("\nChunk: %.4s %d\n", tb, chunk_size);
        if(!memcmp(tb, "INFO", 4))
        {
            if(chunk_size < 8)
                throw MDFN_Error(0, _("NSFE chunk \"%.4s\" size(%u) is invalid."), (char*)&tb[0], chunk_size);

            nfe->LoadAddr = MDFN_de16lsb(buf);
            buf+=2;
            size-=2;

            nfe->InitAddr = MDFN_de16lsb(buf);
            buf+=2;
            size-=2;

            nfe->PlayAddr = MDFN_de16lsb(buf);
            buf+=2;
            size-=2;

            nfe->VideoSystem = *buf;
            buf++;
            size--;
            nfe->SoundChip = *buf;
            buf++;
            size--;

            chunk_size-=8;

            if(chunk_size) {
                nfe->TotalSongs = *buf;
                buf++;
                size--;
                chunk_size--;
            }
            else nfe->TotalSongs = 1;

            if(chunk_size) {
                nfe->StartingSong = *buf;
                buf++;
                size--;
                chunk_size--;
            }
            else nfe->StartingSong = 0;

            nfe->SongNames = (char **)malloc(sizeof(char *) * nfe->TotalSongs);
            memset(nfe->SongNames, 0, sizeof(char *) * nfe->TotalSongs);

            nfe->SongLengths = (int32 *)malloc(sizeof(int32) * nfe->TotalSongs);
            nfe->SongFades = (int32 *)malloc(sizeof(int32) * nfe->TotalSongs);
            {
                int x;
                for(x=0; x<nfe->TotalSongs; x++) {
                    nfe->SongLengths[x] = -1;
                    nfe->SongFades[x] = -1;
                }
            }
        }
        else if(!memcmp(tb, "DATA", 4))
        {
            nfe->NSFSize=chunk_size;
            nbuf = buf;
        }
        else if(!memcmp(tb, "BANK", 4))
        {
            memcpy(nfe->BankSwitch, buf, (chunk_size > 8) ? 8 : chunk_size);
        }
        else if(!memcmp(tb, "NEND", 4))
        {
            if(chunk_size != 0)
                throw MDFN_Error(0, _("NSFE chunk \"%.4s\" size(%u) is invalid."), (char*)&tb[0], chunk_size);
            else if(!nbuf)
                throw MDFN_Error(0, _("NEND reached without preceding DATA chunk."));
            else
            {
                nfe->NSFMaxBank = ((nfe->NSFSize+(nfe->LoadAddr&0xfff)+4095)/4096);
                nfe->NSFMaxBank = round_up_pow2(nfe->NSFMaxBank);

                if(!info_only)
                {
                    if(!(nfe->NSFDATA=(uint8 *)malloc(nfe->NSFMaxBank*4096)))
                        throw MDFN_Error(errno, _("Error allocating memory."));

                    memset(nfe->NSFDATA,0x00,nfe->NSFMaxBank*4096);
                    memcpy(nfe->NSFDATA+(nfe->LoadAddr&0xfff),nbuf,nfe->NSFSize);

                    nfe->NSFRawData = nfe->NSFDATA + (nfe->LoadAddr & 0xFFF);
                    nfe->NSFRawDataSize = nfe->NSFSize;
                }
                nfe->NSFMaxBank--;
                return;
            }
        }
        else if(!memcmp(tb, "tlbl", 4))
        {
            int songcount = 0;

            if(!nfe->TotalSongs)
                throw MDFN_Error(0, _("NSFE chunk \"%.4s\" is out of order."));	// Out of order chunk.

            while(chunk_size > 0)
            {
                int slen = strlen((char *)buf);

                nfe->SongNames[songcount++] = (char*)MDFN_RemoveControlChars(strdup((char *)buf));

                buf += slen + 1;
                chunk_size -= slen + 1;
            }
        }
        else if(!memcmp(tb, "time", 4))
        {
            int count = chunk_size / 4;
            int ws = 0;
            chunk_size -= count * 4;

            while(count--)
            {
                nfe->SongLengths[ws] = (int32)MDFN_de32lsb(buf);
                //printf("%d\n",fe->SongLengths[ws]/1000);
                buf += 4;
                ws++;
            }
        }
        else if(!memcmp(tb, "fade", 4))
        {
            int count = chunk_size / 4;
            int ws = 0;
            chunk_size -= count * 4;

            while(count--)
            {
                nfe->SongFades[ws] = (int32)MDFN_de32lsb(buf);
                //printf("%d\n",fe->SongFades[ws]);
                buf += 4;
                ws++;
            }
        }
        else if(!memcmp(tb, "auth", 4))
        {
            int which = 0;
            while(chunk_size > 0)
            {
                int slen = strlen((char *)buf);

                if(!which) nfe->GameName = (char*)MDFN_RemoveControlChars(strdup((char *)buf));
                else if(which == 1) nfe->Artist = (char*)MDFN_RemoveControlChars(strdup((char *)buf));
                else if(which == 2) nfe->Copyright = (char*)MDFN_RemoveControlChars(strdup((char *)buf));
                else if(which == 3) nfe->Ripper = (char*)MDFN_RemoveControlChars(strdup((char *)buf));

                which++;
                buf += slen +1;
                chunk_size -= slen + 1;
            }
        }
        else if(tb[0] >= 'A' && tb[0] <= 'Z') /* Unrecognized mandatory chunk */
        {
            throw MDFN_Error(0, _("NSFE unrecognized mandatory chunk \"%.4s\"."), (char*)&tb[0]);
        }

        buf += chunk_size;
        size -= chunk_size;
    }
}
コード例 #12
0
ファイル: dualshock.cpp プロジェクト: gameblabla/mednafen-gcw
void InputDevice_DualShock::UpdateInput(const void *data)
{
 uint8 *d8 = (uint8 *)data;
 uint8* const rumb_dp = &d8[3 + 16];

 buttons[0] = d8[0];
 buttons[1] = d8[1];
 cur_ana_button_state = d8[2] & 0x01;

 for(int stick = 0; stick < 2; stick++)
 {
  for(int axis = 0; axis < 2; axis++)
  {
   const uint8* aba = &d8[3] + stick * 8 + axis * 4;
   int32 tmp;

   tmp = 32767 + MDFN_de16lsb(&aba[0]) - MDFN_de16lsb(&aba[2]);
   tmp = (tmp * 0x100) / 0xFFFF;

   axes[stick][axis] = tmp;
  }
 }

 //printf("%3d:%3d, %3d:%3d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);

 //printf("RUMBLE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", rumble_magic[0], rumble_magic[1], rumble_magic[2], rumble_magic[3], rumble_magic[4], rumble_magic[5]);
 //printf("%d, 0x%02x 0x%02x\n", da_rumble_compat, rumble_param[0], rumble_param[1]);

 if(da_rumble_compat == false)
 {
  uint8 sneaky_weaky = 0;

  if(rumble_param[0] == 0x01)
   sneaky_weaky = 0xFF;

  MDFN_en16lsb(rumb_dp, (sneaky_weaky << 0) | (rumble_param[1] << 8));
 }
 else
 {
  uint8 sneaky_weaky = 0;

  if(((rumble_param[0] & 0xC0) == 0x40) && ((rumble_param[1] & 0x01) == 0x01))
   sneaky_weaky = 0xFF;

  MDFN_en16lsb(rumb_dp, sneaky_weaky << 0);
 }

 //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);

 //
 //
 //
 CheckManualAnaModeChange();

 //
 // Encode analog mode state last.
 //
 d8[2] &= ~0x6;
 d8[2] |= (analog_mode ? 0x02 : 0x00);
 d8[2] |= (analog_mode_locked ? 0x04 : 0x00);
}
コード例 #13
0
static INLINE void RunCDDA(uint32 system_timestamp, int32 run_time)
{
 if(cdda.CDDAStatus == CDDASTATUS_PLAYING)
 {
  int32 sample[2];

  cdda.CDDADiv -= run_time << 16;

  while(cdda.CDDADiv <= 0)
  {
   const uint32 synthtime = ((system_timestamp + (cdda.CDDADiv >> 16))) / cdda.CDDATimeDiv;

   cdda.CDDADiv += cdda.CDDADivAcc;

   //MDFN_DispMessage("%d %d %d\n", read_sec_start, read_sec, read_sec_end);

   if(cdda.CDDAReadPos == 588)
   {
    if(read_sec >= read_sec_end)
    {
     switch(cdda.PlayMode)
     {
      case PLAYMODE_SILENT:
      case PLAYMODE_NORMAL:
       cdda.CDDAStatus = CDDASTATUS_STOPPED;
       break;

      case PLAYMODE_INTERRUPT:
       cdda.CDDAStatus = CDDASTATUS_STOPPED;
       CDIRQCallback(PCECD_Drive_IRQ_DATA_TRANSFER_DONE);
       break;

      case PLAYMODE_LOOP:
       read_sec = read_sec_start;
       break;
     }

     // If CDDA playback is stopped, break out of our while(CDDADiv ...) loop and don't play any more sound!
     if(cdda.CDDAStatus == CDDASTATUS_STOPPED)
      break;
    }

    // Don't play past the user area of the disc.
    if(read_sec >= toc.tracks[100].lba)
    {
     cdda.CDDAStatus = CDDASTATUS_STOPPED;
     break;
    }

    if(cd.TrayOpen)
    {
     cdda.CDDAStatus = CDDASTATUS_STOPPED;

     #if 0
     cd.data_transfer_done = FALSE;
     cd.key_pending = SENSEKEY_NOT_READY;
     cd.asc_pending = ASC_MEDIUM_NOT_PRESENT;
     cd.ascq_pending = 0x00;
     cd.fru_pending = 0x00;
     SendStatusAndMessage(STATUS_CHECK_CONDITION, 0x00);
     #endif

     break;
    }


    cdda.CDDAReadPos = 0;

    {
     uint8 tmpbuf[2352 + 96];

     Cur_CDIF->ReadRawSector(tmpbuf, read_sec);	//, read_sec_end, read_sec_start);

     for(int i = 0; i < 588 * 2; i++)
      cdda.CDDASectorBuffer[i] = MDFN_de16lsb(&tmpbuf[i * 2]);

     memcpy(cd.SubPWBuf, tmpbuf + 2352, 96);
    }
    GenSubQFromSubPW();
    read_sec++;
   } // End    if(CDDAReadPos == 588)

   // If the last valid sub-Q data decoded indicate that the corresponding sector is a data sector, don't output the
   // current sector as audio.
   sample[0] = sample[1] = 0;

   if(!(cd.SubQBuf_Last[0] & 0x40) && cdda.PlayMode != PLAYMODE_SILENT)
   {
    sample[0] = (cdda.CDDASectorBuffer[cdda.CDDAReadPos * 2 + 0] * cdda.CDDAVolume) >> 16;
    sample[1] = (cdda.CDDASectorBuffer[cdda.CDDAReadPos * 2 + 1] * cdda.CDDAVolume) >> 16;
   }

   if(!(cdda.CDDAReadPos % 6))
   {
    int subindex = cdda.CDDAReadPos / 6 - 2;

    if(subindex >= 0)
     CDStuffSubchannels(cd.SubPWBuf[subindex], subindex);
    else // The system-specific emulation code should handle what value the sync bytes are.
     CDStuffSubchannels(0x00, subindex);
   }

   if(sbuf[0] && sbuf[1])
   {
    cdda.CDDASynth.offset_inline(synthtime, sample[0] - cdda.last_sample[0], sbuf[0]);
    cdda.CDDASynth.offset_inline(synthtime, sample[1] - cdda.last_sample[1], sbuf[1]);
   }

   cdda.last_sample[0] = sample[0];
   cdda.last_sample[1] = sample[1];

   cdda.CDDAReadPos++;
  }
コード例 #14
0
ファイル: SPCReader.cpp プロジェクト: libretro/mednafen-git
SPCReader::SPCReader(Stream* fp)
{
#if 0
 reg_pc = 0x430;
 reg_a = 0;
 reg_x = 0;
 reg_y = 0;
 reg_psw = 0;
 reg_sp = 0xFF;

 memset(apuram, 0x00, sizeof(apuram));
 memset(dspregs, 0x00, sizeof(dspregs));
 dspregs[0x6C] = 0xE0;

 fp->read(&apuram[0x400], 0x1000);
 return;
#endif

 if(!TestMagic(fp))
  throw MDFN_Error(0, _("Not a valid SPC file!"));

 uint8 header[0x100];

 fp->rewind();
 fp->read(header, sizeof(header));

 reg_pc = MDFN_de16lsb(&header[0x25]);
 reg_a = header[0x27];
 reg_x = header[0x28];
 reg_y = header[0x29];
 reg_psw = header[0x2A];
 reg_sp = header[0x2B];

 fp->read(apuram, 65536);
 fp->read(dspregs, 0x80);
 fp->seek(0x101C0, SEEK_SET);
 fp->read(apuram + 0xFFC0, 0x40);

 if(header[0x23] == 0x1A)
 {
  bool binary_tags = true;

  if(header[0xA0] == '/' && header[0xA3] == '/')
   binary_tags = false;

  if(header[0xD2] >= '0' && header[0xD2] <= '9' && header[0xD3] == 0x00)
   binary_tags = false;

  fp->seek(0x2E, SEEK_SET);

  song_name = GrabString(fp, 32);
  game_name = GrabString(fp, 32);

  fp->seek(binary_tags ? 0xB0 : 0xB1, SEEK_SET);
  artist_name = GrabString(fp, 32);
 }

 //
 //
 //
#if 0
 fp->seek(0x10200, SEEK_SET);
 uint8 xid_header[8];

 if(fp->read(xid_header, sizeof(xid_header), false) == sizeof(xid_header) && !memcmp(xid_header, "xid6", 4))
 {
  uint8 sub_header[4];

  while(fp->read(sub_header, sizeof(sub_header), false) == sizeof(sub_header))
  {
   const uint8 id = sub_header[0];
   const uint8 type = sub_header[1];
   uint16 len = MDFN_de16lsb(&sub_header[2]);

   printf("ID: 0x%02x, Type: 0x%02x, Len: 0x%04x\n", id, type, len);

   if(type == 1 && len > 4)
    len = (len + 3) &~ 3;

   switch(id)
   {
    default:
	if(type)
	 fp->seek(len, SEEK_CUR);
	break;
 
    case 0x01: song_name = GrabString(fp, len); break;
    case 0x02: game_name = GrabString(fp, len); break;
    case 0x03: artist_name = GrabString(fp, len); break;
   }
  }
 }
#endif
}