Example #1
0
int LoadNSF(MDFNFILE *fp)
{
 NSF_HEADER NSFHeader;

 fp->rewind();
 fp->fread(&NSFHeader, 1, 0x80);

 // NULL-terminate strings just in case.
 NSFHeader.GameName[31] = NSFHeader.Artist[31] = NSFHeader.Copyright[31] = 0;

 NSFInfo->GameName = (UTF8*)MDFN_RemoveControlChars(strdup((char *)NSFHeader.GameName));
 NSFInfo->Artist = (UTF8 *)MDFN_RemoveControlChars(strdup((char *)NSFHeader.Artist));
 NSFInfo->Copyright = (UTF8 *)MDFN_RemoveControlChars(strdup((char *)NSFHeader.Copyright));

 MDFN_trim((char*)NSFInfo->GameName);
 MDFN_trim((char*)NSFInfo->Artist);
 MDFN_trim((char*)NSFInfo->Copyright);

 NSFInfo->LoadAddr = NSFHeader.LoadAddressLow | (NSFHeader.LoadAddressHigh << 8);
 NSFInfo->InitAddr = NSFHeader.InitAddressLow | (NSFHeader.InitAddressHigh << 8);
 NSFInfo->PlayAddr = NSFHeader.PlayAddressLow | (NSFHeader.PlayAddressHigh << 8);

 NSFInfo->NSFSize = fp->Size() - 0x80;

 NSFInfo->NSFMaxBank = ((NSFInfo->NSFSize+(NSFInfo->LoadAddr&0xfff)+4095)/4096);
 NSFInfo->NSFMaxBank = round_up_pow2(NSFInfo->NSFMaxBank);

 if(!(NSFInfo->NSFDATA=(uint8 *)MDFN_malloc(NSFInfo->NSFMaxBank*4096, _("NSF data"))))
  return 0;

 fp->fseek(0x80, SEEK_SET);

 memset(NSFInfo->NSFDATA, 0x00, NSFInfo->NSFMaxBank*4096);
 fp->fread(NSFInfo->NSFDATA+(NSFInfo->LoadAddr&0xfff), 1, NSFInfo->NSFSize);
 
 NSFInfo->NSFMaxBank--;

 NSFInfo->VideoSystem = NSFHeader.VideoSystem;
 NSFInfo->SoundChip = NSFHeader.SoundChip;
 NSFInfo->TotalSongs = NSFHeader.TotalSongs;

 if(NSFHeader.StartingSong == 0)
  NSFHeader.StartingSong = 1;

 NSFInfo->StartingSong = NSFHeader.StartingSong - 1;
 memcpy(NSFInfo->BankSwitch, NSFHeader.BankSwitch, 8);

 return(1);
}
Example #2
0
static bool LoadCPalette(const char *syspalname, uint8 **ptr, uint32 num_entries)
{
 std::string colormap_fn = MDFN_MakeFName(MDFNMKF_PALETTE, 0, syspalname).c_str();

 MDFN_printf(_("Loading custom palette from \"%s\"...\n"),  colormap_fn.c_str());
 MDFN_indent(1);

 *ptr = NULL;
 try
 {
  FileStream fp(colormap_fn.c_str(), FileStream::MODE_READ);

  if(!(*ptr = (uint8 *)MDFN_malloc(num_entries * 3, _("custom color map"))))
  {
   MDFN_indent(-1);
   return(false);
  }

  fp.read(*ptr, num_entries * 3);
 }
 catch(MDFN_Error &e)
 {
  if(*ptr)
  {
   MDFN_free(*ptr);
   *ptr = NULL;
  }

  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  return(e.GetErrno() == ENOENT);        // Return fatal error if it's an error other than the file not being found.
 }
 catch(std::exception &e)
 {
  if(*ptr)
  {
   MDFN_free(*ptr);
   *ptr = NULL;
  }

  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  return(false);
 }

 MDFN_indent(-1);

 return(true);
}
// This function should ALWAYS close the system file "descriptor"(gzip library, zip library, or FILE *) it's given,
// even if it errors out.
bool MDFNFILE::MakeMemWrapAndClose(void *fp)
{
   location = 0;

   ::fseek((FILE *)fp, 0, SEEK_END);
   f_size = ::ftell((FILE *)fp);
   ::fseek((FILE *)fp, 0, SEEK_SET);

   if (!(f_data = (uint8*)MDFN_malloc(f_size, _("file read buffer"))))
      goto fail;
   ::fread(f_data, 1, f_size, (FILE *)fp);

   return TRUE;
fail:
   fclose((FILE*)fp);
   return FALSE;
}
Example #4
0
void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status)
{
 gzFile fp;
 uint32 StateShowPBWidth;
 uint32 StateShowPBHeight;
 uint8 *previewbuffer = NULL;

 fp = gzopen(filename, "rb");
 if(fp)
 {
  uint8 header[32];

  gzread(fp, header, 32);
  uint32 width = MDFN_de32lsb(header + 24);
  uint32 height = MDFN_de32lsb(header + 28);

  if(width > 1024) width = 1024;
  if(height > 1024) height = 1024;

  if(!(previewbuffer = (uint8 *)MDFN_malloc(3 * width * height, _("Save state preview buffer"))))
  {
   StateShowPBWidth = 0;
   StateShowPBHeight = 0;
  }
  else
  {
   gzread(fp, previewbuffer, 3 * width * height);

   StateShowPBWidth = width;
   StateShowPBHeight = height;
  }
  gzclose(fp);
 }
 else
 {
  StateShowPBWidth = MDFNGameInfo->nominal_width;
  StateShowPBHeight = MDFNGameInfo->nominal_height;
 }

 status->gfx = previewbuffer;
 status->w = StateShowPBWidth;
 status->h = StateShowPBHeight;
}
Example #5
0
int Mapper112_Init(CartInfo *info)
{
 SetWriteHandler(0x8000,0xffff,Mapper112_write);
 SetReadHandler(0x6000, 0xFFFF, CartBR);
 SetWriteHandler(0x6000, 0x7FFF, CartBW);
 info->Power = Power;
 info->Close = Close;
 info->StateAction = StateAction;

 if(!(WRAM = (uint8 *)MDFN_malloc(8192,"WRAM")))
  return(0);

 SetupCartPRGMapping(0x10, WRAM, 8192, 1);

 if(info->battery)
 {
  info->SaveGame[0] = WRAM;
  info->SaveGameLen[0] = 8192;
 }
 return(1);
}
Example #6
0
static int Load(const char *name, MDFNFILE *fp)
{
 if(!(ngpc_rom.data = (uint8 *)MDFN_malloc(GET_FSIZE_PTR(fp), _("Cart ROM"))))
  return(0);

 ngpc_rom.length = GET_FSIZE_PTR(fp);
 memcpy(ngpc_rom.data, GET_FDATA_PTR(fp), GET_FSIZE_PTR(fp));

 md5_context md5;
 md5.starts();
 md5.update(ngpc_rom.data, ngpc_rom.length);
 md5.finish(MDFNGameInfo->MD5);

 rom_loaded();
 MDFN_printf(_("ROM:       %dKiB\n"), (ngpc_rom.length + 1023) / 1024);
 MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());

 MDFNMP_Init(1024, 1024 * 1024 * 16 / 1024);

 NGPGfx = new NGPGFX_CLASS();

 MDFNGameInfo->fps = (uint32)((uint64)6144000 * 65536 * 256 / 515 / 198); // 3072000 * 2 * 10000 / 515 / 198
 MDFNGameInfo->GameSetMD5Valid = FALSE;

 MDFNNGPCSOUND_Init();

 MDFNMP_AddRAM(16384, 0x4000, CPUExRAM);

 SetFRM(); // Set up fast read memory mapping

 bios_install();

 //main_timeaccum = 0;
 z80_runtime = 0;

 reset();

 return(1);
}
Example #7
0
bool MDFNFILE::ApplyIPS(FILE *ips)
{
 uint8 header[5];
 uint32 count = 0;
 
 //MDFN_printf(_("Applying IPS file \"%s\"...\n"), path);

 MDFN_indent(1);
 if(::fread(header, 1, 5, ips) != 5)
 {
  ErrnoHolder ene(errno);

  MDFN_PrintError(_("Error reading IPS file header: %s"), ene.StrError());
  MDFN_indent(-1);
  return(0);
 }

 if(memcmp(header, "PATCH", 5))
 {
  MDFN_PrintError(_("IPS file header is invalid."));
  MDFN_indent(-1);
  return(0);
 }

 #ifdef HAVE_MMAP
 // If the file is mmap()'d, move it to malloc()'d RAM
 if(is_mmap)
 {
  void *tmp_ptr = MDFN_malloc(f_size, _("file read buffer"));
  if(!tmp_ptr)
  {
   //Close();
   //fclose(ipsfile);
   return(0);
  }
  memcpy(tmp_ptr, f_data, f_size);

  munmap(f_data, f_size);

  is_mmap = FALSE;
  f_data = (uint8 *)tmp_ptr;
 }
 #endif

 while(::fread(header, 1, 3, ips) == 3)
 {
  uint32 offset = (header[0] << 16) | (header[1] << 8) | header[2];
  uint8 patch_size_raw[2];
  uint32 patch_size;
  bool rle = false;

  if(!memcmp(header, "EOF", 3))
  {
   MDFN_printf(_("IPS EOF:  Did %d patches\n\n"), count);
   MDFN_indent(-1);
   return(1);
  }

  if(::fread(patch_size_raw, 1, 2, ips) != 2)
  {
   ErrnoHolder ene(errno);
   MDFN_PrintError(_("Error reading IPS patch length: %s"), ene.StrError());
   return(0);
  }

  patch_size = MDFN_de16msb(patch_size_raw);

  if(!patch_size)	/* RLE */
  {
   if(::fread(patch_size_raw, 1, 2, ips) != 2)
   {
    ErrnoHolder ene(errno);
    MDFN_PrintError(_("Error reading IPS RLE patch length: %s"), ene.StrError());
    return(0);
   }

   patch_size = MDFN_de16msb(patch_size_raw);

   // Is this right?
   if(!patch_size)
    patch_size = 65536;

   rle = true;
   //MDFN_printf("  Offset: %8d  Size: %5d RLE\n",offset, patch_size);
  }

  if((offset + patch_size) > f_size)
  {
   uint8 *tmp;

   //printf("%d\n", offset + patch_size, f_size);

   if((offset + patch_size) > MaxROMImageSize)
   {
    MDFN_PrintError(_("ROM image will be too large after IPS patch; maximum size allowed is %llu bytes."), (unsigned long long)MaxROMImageSize);
    return(0);
   }

   if(!(tmp = (uint8 *)MDFN_realloc(f_data, offset + patch_size, _("file read buffer"))))
    return(0);

   // Zero newly-allocated memory
   memset(tmp + f_size, 0, (offset + patch_size) - f_size);

   f_size = offset + patch_size;
   f_data = tmp;
  }


  if(rle)
  {
   const int b = ::fgetc(ips);
   uint8 *start = f_data + offset;

   if(EOF == b)
   {
    ErrnoHolder ene(errno);

    MDFN_PrintError(_("Error reading IPS RLE patch byte: %s"), ene.StrError());

    return(0);
   }

   while(patch_size--)
   {
    *start=b;
    start++;
   }

  }
  else		/* Normal patch */
  {
   //MDFN_printf("  Offset: %8d  Size: %5d\n", offset, patch_size);
   if(::fread(f_data + offset, 1, patch_size, ips) != patch_size)
   {
    ErrnoHolder ene(errno);

    MDFN_PrintError(_("Error reading IPS patch: %s"), ene.StrError());
    return(0);
   }
  }
  count++;
 }
 ErrnoHolder ene(errno);

 //MDFN_printf(_("Warning:  IPS ended without an EOF chunk.\n"));
 //MDFN_printf(_("IPS EOF:  Did %d patches\n\n"), count);
 MDFN_indent(-1);

 MDFN_PrintError(_("Error reading IPS patch header: %s"), ene.StrError());
 return(0);

 //return(1);
}
Example #8
0
// This function should ALWAYS close the system file "descriptor"(gzip library, zip library, or FILE *) it's given,
// even if it errors out.
bool MDFNFILE::MakeMemWrap(void *tz, int type)
{
 bool ret = FALSE;

 #ifdef HAVE_MMAP
 is_mmap = FALSE;
 #endif
 location = 0;

 if(type == MDFN_FILETYPE_PLAIN)
 {
  ::fseek((FILE *)tz, 0, SEEK_END);
  f_size = ::ftell((FILE *)tz);
  ::fseek((FILE *)tz, 0, SEEK_SET);

  if(size > MaxROMImageSize)
  {
   MDFN_PrintError(_("ROM image is too large; maximum size allowed is %llu bytes."), (unsigned long long)MaxROMImageSize);
   goto doret;
  }

  #ifdef HAVE_MMAP
  if((void *)-1 != (f_data = (uint8 *)mmap(NULL, size, PROT_READ, MAP_SHARED, fileno((FILE *)tz), 0)))
  {
   //puts("mmap'ed");
   is_mmap = TRUE;
   #ifdef HAVE_MADVISE
   if(0 == madvise(f_data, size, MADV_SEQUENTIAL | MADV_WILLNEED))
   {
    //puts("madvised");
   }
   #endif
  }
  else
  {
  #endif
   if(!(f_data = (uint8*)MDFN_malloc(size, _("file read buffer"))))
   {
    goto doret;
   }
   if((int64)::fread(f_data, 1, size, (FILE *)tz) != size)
   {
    free(f_data);
    goto doret;
   }
  #ifdef HAVE_MMAP
  }
  #endif
 }
 else if(type == MDFN_FILETYPE_GZIP)
 {
  uint32_t cur_size = 0;
  uint32_t cur_alloced = 65536;
  int howmany;

  if(!(f_data = (uint8*)MDFN_malloc(cur_alloced, _("file read buffer"))))
  {
   goto doret;
  }

  while((howmany = gzread(tz, f_data + cur_size, cur_alloced - cur_size)) > 0)
  {
   cur_size += howmany;
   cur_alloced <<= 1;
   if(!(f_data = (uint8 *)MDFN_realloc(f_data, cur_alloced, _("file read buffer")))) 
   {
    goto doret;
   }
  }

  if(!(f_data = (uint8 *)MDFN_realloc(f_data, cur_size, _("file read buffer")))) 
  {
   goto doret;
  }

  f_size = cur_size;
 }
 else if(type == MDFN_FILETYPE_ZIP)
 {
  unz_file_info ufo; 
  unzGetCurrentFileInfo(tz, &ufo, 0, 0, 0, 0, 0, 0);

  f_size = ufo.uncompressed_size;

  if(size > MaxROMImageSize)
  {
   MDFN_PrintError(_("ROM image is too large; maximum size allowed is %llu bytes."), (unsigned long long)MaxROMImageSize);
   goto doret;
  }

  if(!(f_data=(uint8 *)MDFN_malloc(ufo.uncompressed_size, _("file read buffer"))))
  {
   goto doret;
  }

  unzReadCurrentFile(tz, f_data, ufo.uncompressed_size);
 }

 ret = TRUE;

 doret:
 if(type == MDFN_FILETYPE_PLAIN)
 {
  fclose((FILE *)tz);
 }
 else if(type == MDFN_FILETYPE_GZIP)
 {
  gzclose(tz);
 }
 else if(type == MDFN_FILETYPE_ZIP)
 {
  unzCloseCurrentFile(tz);
  unzClose(tz);
 }

 return(ret);
}
Example #9
0
void HuC_Load(const uint8 *data, uint32 len, uint32 crc32)
{
 try
 {
	 uint32 sf2_threshold = 2048 * 1024;
	 uint32 sf2_required_size = 2048 * 1024 + 512 * 1024;
	 uint32 m_len = (len + 8191)&~8191;
	 bool sf2_mapper = FALSE;

	 if(m_len >= sf2_threshold)
	 {
		sf2_mapper = TRUE;

		if(m_len != sf2_required_size)
		 m_len = sf2_required_size;
	 }

	 IsPopulous = 0;
	 PCE_IsCD = 0;

	 md5_context md5;
	 md5.starts();
	 md5.update(data, len);
	 md5.finish(MDFNGameInfo->MD5);

	 MDFN_printf(_("ROM:       %dKiB\n"), (len + 1023) / 1024);
	 MDFN_printf(_("ROM CRC32: 0x%04x\n"), crc32);
	 MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());

	 HuCROM = (uint8 *)MDFN_malloc(m_len, _("HuCard ROM"));

	 memset(HuCROM, 0xFF, m_len);
	 memcpy(HuCROM, data, (m_len < len) ? m_len : len);

	 memset(ROMSpace, 0xFF, 0x88 * 8192 + 8192);

	 if(m_len == 0x60000)
	 {
		memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x20 * 8192);
		memcpy(ROMSpace + 0x20 * 8192, HuCROM, 0x20 * 8192);
		memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
		memcpy(ROMSpace + 0x50 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
		memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
		memcpy(ROMSpace + 0x70 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
	 }
	 else if(m_len == 0x80000)
	 {
		memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x40 * 8192);
		memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192);
		memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192);
	 }
	 else
	 {
		memcpy(ROMSpace + 0x00 * 8192, HuCROM, (m_len < 1024 * 1024) ? m_len : 1024 * 1024);
	 }

	 for(int x = 0x00; x < 0x80; x++)
	 {
		HuCPUFastMap[x] = ROMSpace;
		PCERead[x] = HuCRead;
	 }

	 if(!memcmp(HuCROM + 0x1F26, "POPULOUS", strlen("POPULOUS")))
	 {
		uint8 *PopRAM = ROMSpace + 0x40 * 8192;
		gzFile fp;

		memset(PopRAM, 0xFF, 32768);
		if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
		{
		 gzread(fp, PopRAM, 32768);
		 gzclose(fp);
		}

		IsPopulous = 1;

		MDFN_printf("Populous\n");

		for(int x = 0x40; x < 0x44; x++)
		{
		 HuCPUFastMap[x] = &PopRAM[(x & 3) * 8192] - x * 8192;
		 PCERead[x] = HuCRead;
		 PCEWrite[x] = HuCRAMWrite;
		}
		MDFNMP_AddRAM(32768, 0x40 * 8192, PopRAM);
	 }
	 else
	 {
		gzFile fp;

		memset(SaveRAM, 0x00, 2048);
		memcpy(SaveRAM, BRAM_Init_String, 8);    // So users don't have to manually intialize the file cabinet
																									// in the CD BIOS screen.
		if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
		{
		 gzread(fp, SaveRAM, 2048);
		 gzclose(fp);
		}
		PCEWrite[0xF7] = SaveRAMWrite;
		PCERead[0xF7] = SaveRAMRead;
		MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM);
	 }

	 // 0x1A558
	 //if(len >= 0x20000 && !memcmp(HuCROM + 0x1A558, "STREET FIGHTER#", strlen("STREET FIGHTER#")))
	 if(sf2_mapper)
	 {
		for(int x = 0x40; x < 0x80; x++)
		{
		 // FIXME: PCE_FAST
		 HuCPUFastMap[x] = NULL; // Make sure our reads go through our read function, and not a table lookup
		 PCERead[x] = HuCSF2Read;
		}
		PCEWrite[0] = HuCSF2Write;
		MDFN_printf("Street Fighter 2 Mapper\n");
		HuCSF2Latch = 0;
	 }
 }
 catch(...)
 {
	Cleanup();
	throw;
 }
}
Example #10
0
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);
}
Example #11
0
bool NSFLoad(const char *name, MDFNFILE *fp, NESGameType *gt)
{
 char magic[5];
 int x;

 if(!(NSFInfo = (NSFINFO *)MDFN_malloc(sizeof(NSFINFO), _("NSF header"))))
 {
  return(0);
 }
 memset(NSFInfo, 0, sizeof(NSFINFO));

 fp->rewind();
 fp->fread(magic, 1, 5);

 if(!memcmp(magic, "NESM\x1a", 5))
 {
  if(!LoadNSF(fp))
  {
   FreeNSF();
   return(0);
  }
 }
 else if(!memcmp(magic, "NSFE", 4))
 {
  if(!LoadNSFE(NSFInfo, fp->data, fp->Size(), 0))
  {
   FreeNSF();
   return(0);
  }
 }
 else
 {
  FreeNSF();
  return(FALSE);
 }

 if(NSFInfo->LoadAddr < 0x6000)
 {
  MDFNI_printf(_("Load address is invalid!"));
  FreeNSF();
  return(0);
 }

 if(NSFInfo->TotalSongs < 1)
 {
  MDFNI_printf(_("Total number of songs is less than 1!"));
  FreeNSF();
  return(0);
 }

 BSon = 0;
 for(x=0;x<8;x++)
  BSon |= NSFInfo->BankSwitch[x];

 MDFNGameInfo->GameType = GMT_PLAYER;

 if(NSFInfo->GameName)
  MDFNGameInfo->name = (UTF8*)strdup((char*)NSFInfo->GameName);

 for(x=0;;x++)
 {
  if(NSFROM[x]==0x20)
  {
   NSFROM[x+1]=NSFInfo->InitAddr&0xFF;
   NSFROM[x+2]=NSFInfo->InitAddr>>8;
   NSFROM[x+8]=NSFInfo->PlayAddr&0xFF;
   NSFROM[x+9]=NSFInfo->PlayAddr>>8;
   break;
  }
 }
Example #12
0
int MDFN_SavePNGSnapshot(const char *fname, uint32 *fb, const MDFN_Rect *rect, uint32 pitch)
{
 int x, y;
 FILE *pp=NULL;
 uint8 *compmem = NULL;
 uLongf compmemsize = (uLongf)( (rect->h * (rect->w + 1) * 3 * 1.001 + 1) + 12 );

 if(!(compmem=(uint8 *)MDFN_malloc(compmemsize, _("PNG compression buffer"))))
  return 0;

 if(!(pp=fopen(fname, "wb")))
 {
  return 0;
 }
 {
  static uint8 header[8]={137,80,78,71,13,10,26,10};
  if(fwrite(header,8,1,pp)!=1)
   goto PNGerr;
 }

 {
  uint8 chunko[13];

  chunko[0] = rect->w >> 24;		// Width
  chunko[1] = rect->w >> 16;
  chunko[2] = rect->w >> 8;
  chunko[3] = rect->w;

  chunko[4] = rect->h >> 24;		// Height
  chunko[5] = rect->h >> 16;
  chunko[6] = rect->h >> 8;
  chunko[7] = rect->h;

  chunko[8]=8;				// 8 bits per sample(24 bits per pixel)
  chunko[9]=2;				// Color type; RGB triplet
  chunko[10]=0;				// compression: deflate
  chunko[11]=0;				// Basic adapative filter set(though none are used).
  chunko[12]=0;				// No interlace.

  if(!WritePNGChunk(pp,13,"IHDR",chunko))
   goto PNGerr;
 }

 {
  uint8 *tmp_buffer;
  uint8 *tmp_inc;
  tmp_inc = tmp_buffer = (uint8 *)malloc((rect->w * 3 + 1) * rect->h);

  for(y=0;y<rect->h;y++)
  {
   *tmp_inc = 0;
   tmp_inc++;
   for(x=0;x<rect->w;x++)
   {
    int r,g,b;
    DECOMP_COLOR(*(uint32 *)((uint8 *)fb + (y + rect->y) * pitch + (x + rect->x) * 4), r, g, b);
    tmp_inc[0] = r;
    tmp_inc[1] = g;
    tmp_inc[2] = b;
    tmp_inc += 3;
   }
  }

  if(compress(compmem, &compmemsize, tmp_buffer, rect->h * (rect->w * 3 + 1))!=Z_OK)
  {
   if(tmp_buffer) free(tmp_buffer);
   goto PNGerr;
  }
  if(tmp_buffer) free(tmp_buffer);
  if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
   goto PNGerr;
 }
 if(!WritePNGChunk(pp,0,"IEND",0))
  goto PNGerr;

 free(compmem);
 fclose(pp);

 return 1;

 PNGerr:
 if(compmem)
  free(compmem);
 if(pp)
  fclose(pp);
 return(0);
}