Пример #1
0
bool savestate_save(EMUFILE* outstream)
{
#ifdef HAVE_JIT 
	arm_jit_sync();
#endif

	EMUFILE_MEMORY ms;
	EMUFILE* os = outstream;
   os->fseek(32,SEEK_SET); //skip the header
   writechunks(os);

	//save the length of the file
	u32 len = os->ftell();

	u32 comprlen = 0xFFFFFFFF;
	u8* cbuf;

	//dump the header
	outstream->fseek(0,SEEK_SET);
	outstream->fwrite(magic,16);
	write32le(SAVESTATE_VERSION,outstream);
	write32le(EMU_DESMUME_VERSION_NUMERIC(),outstream); //desmume version
	write32le(len,outstream); //uncompressed length
	write32le(comprlen,outstream); //compressed length (-1 if it is not compressed)

	return true;
}
Пример #2
0
	u32	readRom(const u32 pos, const u8 size) 
	{
		if (!fROM) return 0xFFFFFFFF;
		
		fROM->fseek(pos, SEEK_SET);
	
		u32 data = 0xFFFFFFFF;
		u32 readed = fROM->fread(&data, size);
		return data;
	}
Пример #3
0
	void writeSRAM(const u32 pos, const u8 *data, u32 size) 
	{
		if (!fSRAM)
			return;

		fSRAM->fseek(pos, SEEK_SET);

		u32 writed = size;
		fSRAM->fwrite(data, size);
		fSRAM->fflush();
	}
Пример #4
0
	u32 readSRAM(const u32 pos, const u8 size) 
	{
		if (!fSRAM)
			return 0xFFFFFFFF;
			
		fSRAM->fseek(pos, SEEK_SET);

		u32 data = 0xFFFFFFFF;
		u32 readed = fSRAM->fread(&data, size);
		return data;
	}
Пример #5
0
static void DEBUG_dumpMemory_fill(EMUFILE &fp, u32 size)
{
	static std::vector<u8> buf;
	buf.resize(size);
	memset(&buf[0],0,size);
	fp.fwrite(&buf[0],size);
}
Пример #6
0
static bool formatChunk(EMUFILE &inf)
{
	// seek to just after the RIFF header
	inf.fseek(12,SEEK_SET);

	// search for a format chunk
	for (;;)
	{
		char chunk_id[4];
		u32  chunk_length;

		inf.fread(chunk_id, 4);
		if (!inf.read_32LE(chunk_length)) return false;

		// if we found a format chunk, excellent!
		if (memcmp(chunk_id, "fmt ", 4) == 0 && chunk_length >= 16)
		{

			// read format chunk
			u16 format_tag;
			u16 channel_count;
			u32 samples_per_second;
			//u32 bytes_per_second   = read32_le(chunk + 8);
			//u16 block_align        = read16_le(chunk + 12);
			u16 bits_per_sample;

			if (inf.read_16LE(format_tag) != 1) return false;
			if (inf.read_16LE(channel_count) != 1) return false;
			if (inf.read_32LE(samples_per_second) != 1) return false;
			inf.fseek(6,SEEK_CUR);
			if (inf.read_16LE(bits_per_sample) != 1) return false;

			chunk_length -= 16;

			// format_tag must be 1 (WAVE_FORMAT_PCM)
			// we only support mono 8bit
			if (format_tag != 1 ||
				channel_count != 1 ||
				bits_per_sample != 8)
			{
					MessageBox(0,"not a valid RIFF WAVE file; must be 8bit mono pcm",0,0);
					return false;
			}

			return true;
		}

		inf.fseek(chunk_length,SEEK_CUR);
	}
	return false;
}
Пример #7
0
	u32 scanSaveTypeGBA()
	{
		if (!fROM) return 0xFF;

		fROM->fseek(0, SEEK_SET);
		int size = fROM->size();

		int lastpct=1;

		int len = fROM->size();
		for(;;)
		{
			u32 tmp;
			u32 readed = fROM->fread(&tmp, 4);

			int pos = fROM->ftell();
			int currPct = pos*100/(size-1);
			for(int i=lastpct;i<currPct;i++)
			{
				if(i%10==0)
					printf(" %d%%\n",i/10*10);
				else printf(".");
				lastpct = currPct;
			}

			if (readed < 4) 
				break;

			if(pos >= len)
				break;


			switch (tmp)
			{
				case EEPROM:
					return 1;
				case SRAM_:
					return 2;
				case FLASH:
				{
					u32 tmp = fROM->read32le();
					return ((tmp == FLASH1M_)?3:5);
				}
				case SIIRTC_V:
					return 4;
			}
		}

		return 0xFF;
	}
Пример #8
0
void BackupDevice::flush()
{
	//never use save files if we are in movie mode
	if(isMovieMode) return;

	if (filename.length() == 0) return;

	EMUFILE* outf = new EMUFILE_FILE(filename.c_str(),"wb");
	if(!outf->fail())
	{
		if(data.size()>0)
			outf->fwrite(&data[0],data.size());
		
		//write the footer. we use a footer so that we can maximize the chance of the
		//save file being recognized as a raw save file by other emulators etc.
		
		//first, pad up to the next largest known save size.
		u32 size = data.size();
		u32 padSize = pad_up_size(size);

		for(u32 i=size;i<padSize;i++)
			outf->fputc(kUninitializedSaveDataValue);

		//this is just for humans to read
		outf->fprintf("|<--Snip above here to create a raw sav by excluding this DeSmuME savedata footer:");

		//and now the actual footer
		write32le(size,outf); //the size of data that has actually been written
		write32le(padSize,outf); //the size we padded it to
		write32le(info.type,outf); //save memory type
		write32le(addr_size,outf);
		write32le(info.size,outf); //save memory size
		write32le(0,outf); //version number
		outf->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save

		delete outf;
	}
	else
	{
		delete outf;
		printf("Unable to open savefile %s\n", filename.c_str());
	}
}
Пример #9
0
static bool dataChunk(EMUFILE &inf)
{
	bool found = false;

	// seek to just after the RIFF header
	inf.fseek(12,SEEK_SET);

	// search for a format chunk
	for (;;)
	{
		char chunk_id[4];
		u32  chunk_length;

		if (inf.eof()) return found;
		if (inf.fread(chunk_id, 4) != 4) return found;
		if (!inf.read_32LE(chunk_length)) return found;

		// if we found a data chunk, excellent!
      if (memcmp(chunk_id, "data", 4) == 0)
	  {
		  found = true;
		  u8 *temp = new u8[chunk_length];
		  if (inf.fread(temp,chunk_length) != chunk_length)
		  {
			  delete[] temp;
			  return false;
		  }
		  newWavData.fwrite(temp,chunk_length);
		  delete[] temp;
		  chunk_length = 0;
	  }

	  inf.fseek(chunk_length,SEEK_CUR);
	}

	return found;
}
Пример #10
0
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
{
	// reinit memory_savestate
	// memory_savestate is global variable which already has its vector of bytes, so no need to allocate memory every time we use save/loadstate
	memory_savestate.set_len(0);	// this also seeks to the beginning
	memory_savestate.unfail();

	EMUFILE* os = &memory_savestate;

	uint32 totalsize = 0;

	FCEUPPU_SaveState();
	FCEUSND_SaveState();
	totalsize=WriteStateChunk(os,1,SFCPU);
	totalsize+=WriteStateChunk(os,2,SFCPUC);
	totalsize+=WriteStateChunk(os,3,FCEUPPU_STATEINFO);
	totalsize+=WriteStateChunk(os,31,FCEU_NEWPPU_STATEINFO);
	totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
	totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
	if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED))
	{
		totalsize+=WriteStateChunk(os,6,FCEUMOV_STATEINFO);

		//MBG TAS Editor HACK HACK HACK!
		//do not save the movie state if we are in Taseditor! That would be a huge waste of time and space!
		if(!FCEUMOV_Mode(MOVIEMODE_TASEDITOR))
		{
			os->fseek(5,SEEK_CUR);
			int size = FCEUMOV_WriteState(os);
			os->fseek(-(size+5),SEEK_CUR);
			os->fputc(7);
			write32le(size, os);
			os->fseek(size,SEEK_CUR);

			totalsize += 5 + size;
		}
	}
	// save back buffer
	{
		extern uint8 *XBackBuf;
		uint32 size = 256 * 256 + 8;
		os->fputc(8);
		write32le(size, os);
		os->fwrite((char*)XBackBuf,size);
		totalsize += 5 + size;
	}

	if(SPreSave) SPreSave();
	totalsize+=WriteStateChunk(os,0x10,SFMDATA);
	if(SPreSave) SPostSave();

	//save the length of the file
	int len = memory_savestate.size();

	//sanity check: len and totalsize should be the same
	if(len != totalsize)
	{
		FCEUD_PrintError("sanity violation: len != totalsize");
		return false;
	}

	int error = Z_OK;
	uint8* cbuf = (uint8*)memory_savestate.buf();
	uLongf comprlen = -1;
	if(compressionLevel != Z_NO_COMPRESSION && (compressSavestates || FCEUMOV_Mode(MOVIEMODE_TASEDITOR)))
	{
		// worst case compression: zlib says "0.1% larger than sourceLen plus 12 bytes"
		comprlen = (len>>9)+12 + len;
		if (compressed_buf.size() < comprlen) compressed_buf.resize(comprlen);
		cbuf = &compressed_buf[0];
		// do compression
		error = compress2(cbuf, &comprlen, (uint8*)memory_savestate.buf(), len, compressionLevel);
	}
Пример #11
0
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
{
	//a temp memory stream. we'll dump some data here and then compress
	//TODO - support dumping directly without compressing to save a buffer copy

	EMUFILE_MEMORY ms;
	EMUFILE* os = &ms;

	uint32 totalsize = 0;

	FCEUPPU_SaveState();
	FCEUSND_SaveState();
	totalsize=WriteStateChunk(os,1,SFCPU);
	totalsize+=WriteStateChunk(os,2,SFCPUC);
	totalsize+=WriteStateChunk(os,3,FCEUPPU_STATEINFO);
	totalsize+=WriteStateChunk(os,31,FCEU_NEWPPU_STATEINFO);
	totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
	totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
	if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED))
	{
		totalsize+=WriteStateChunk(os,6,FCEUMOV_STATEINFO);

		//MBG tasedit HACK HACK HACK!
		//do not save the movie state if we are in tasedit! that is a huge waste of time and space!
		if(!FCEUMOV_Mode(MOVIEMODE_TASEDIT))
		{
			os->fseek(5,SEEK_CUR);
			int size = FCEUMOV_WriteState(os);
			os->fseek(-(size+5),SEEK_CUR);
			os->fputc(7);
			write32le(size, os);
			os->fseek(size,SEEK_CUR);

			totalsize += 5 + size;
		}
	}
	// save back buffer
	{
		extern uint8 *XBackBuf;
		uint32 size = 256 * 256 + 8;
		os->fputc(8);
		write32le(size, os);
		os->fwrite((char*)XBackBuf,size);
		totalsize += 5 + size;
	}

	if(SPreSave) SPreSave();
	totalsize+=WriteStateChunk(os,0x10,SFMDATA);
	if(SPreSave) SPostSave();

	//save the length of the file
	int len = ms.size();

	//sanity check: len and totalsize should be the same
	if(len != totalsize)
	{
		FCEUD_PrintError("sanity violation: len != totalsize");
		return false;
	}

	int error = Z_OK;
	uint8* cbuf = (uint8*)ms.buf();
	uLongf comprlen = -1;
	if(compressionLevel != Z_NO_COMPRESSION && compressSavestates)
	{
		//worst case compression.
		//zlib says "0.1% larger than sourceLen plus 12 bytes"
		comprlen = (len>>9)+12 + len;
		cbuf = new uint8[comprlen];
		error = compress2(cbuf,&comprlen,(uint8*)ms.buf(),len,compressionLevel);
	}
Пример #12
0
bool mic_loadstate(EMUFILE &is, int size)
{
	is.fseek(size, SEEK_CUR);
	return true;
}
Пример #13
0
void mic_savestate(EMUFILE &os)
{
	os.write_32LE(-1);
}
Пример #14
0
	virtual void connect()
	{
		Close();
		romSize = 0;
		sramSize = 0;
		
		if (gameInfo.romsize == 0)
		{
			return;
		}
		
		if (GBACartridge_RomPath.empty())
		{
			return;
		}
		
		if (!strcasecmp(GBACartridge_RomPath.c_str(), "self"))
		{
			GBACartridge_RomPath = path.path;
			GBACartridge_SRAMPath = Path::GetFileNameWithoutExt(GBACartridge_RomPath) + "." + GBA_SRAM_FILE_EXT;
		}
		
		printf("GBASlot opening ROM: %s\n", GBACartridge_RomPath.c_str());
		EMUFILE_FILE *inf = new EMUFILE_FILE(GBACartridge_RomPath, "rb");
		inf->EnablePositionCache();
		fROM = inf;
		if (fROM->fail())
		{
			printf(" - Failed\n");
			Close();
			
			return;
		}
		
		romSize = fROM->size();
		printf(" - Success (%u bytes)\n", romSize);
		
		// Load the GBA cartridge SRAM.
		inf = new EMUFILE_FILE(GBACartridge_SRAMPath, "rb+");
		fSRAM = inf;
		if(fSRAM->fail())
		{
			delete fSRAM;
			fSRAM = NULL;
			printf("GBASlot did not load associated SRAM.\n");
		}
		else
		{
			inf->EnablePositionCache();
			sramSize = fSRAM->size();
			printf("Scanning GBA rom to ID save type\n");
			saveType = scanSaveTypeGBA();
			printf("\nGBASlot found SRAM (%s - %u bytes) at:\n%s\n", (saveType == 0xFF)?"Unknown":saveTypes[saveType], sramSize, GBACartridge_SRAMPath.c_str());
			gbaFlash.size = sramSize;
			if (gbaFlash.size <= (64 * 1024))
			{
				gbaFlash.idDevice = 0x1B;
				gbaFlash.idManufacturer = 0x32;
			}
			else
			{
				gbaFlash.idDevice = 0x09;
				gbaFlash.idManufacturer = 0xC2;
			}
			gbaFlash.state = 0;
		}
	}
Пример #15
0
void DEBUG_dumpMemory(EMUFILE &fp)
{
	fp.fseek(0x000000,SEEK_SET); fp.fwrite(MMU.MAIN_MEM,0x800000); //arm9 main mem (8192K)
	fp.fseek(0x900000,SEEK_SET); fp.fwrite(MMU.ARM9_DTCM,0x4000); //arm9 DTCM (16K)
	fp.fseek(0xA00000,SEEK_SET); fp.fwrite(MMU.ARM9_ITCM,0x8000); //arm9 ITCM (32K)
	fp.fseek(0xB00000,SEEK_SET); fp.fwrite(MMU.ARM9_LCD,0xA4000); //LCD mem 656K
	fp.fseek(0xC00000,SEEK_SET); fp.fwrite(MMU.ARM9_VMEM,0x800); //OAM
	fp.fseek(0xD00000,SEEK_SET); fp.fwrite(MMU.ARM7_ERAM,0x10000); //arm7 WRAM (64K)
	fp.fseek(0xE00000,SEEK_SET); fp.fwrite(MMU.ARM7_WIRAM,0x10000); //arm7 wifi RAM ?
	fp.fseek(0xF00000,SEEK_SET); fp.fwrite(MMU.SWIRAM,0x8000); //arm9/arm7 shared WRAM (32KB)
}