bool retro_serialize(void *data, size_t size) { EMUFILE_MEMORY state; savestate_save(&state); if(state.size() <= size) { memcpy(data, state.buf(), state.size()); return true; } return false; }
bool VFAT::build(const char* path, int extra_MB) { dataSectors = 0; currVirtPath = ""; currPath = path; list_files(path, count_ListCallback); dataSectors += 8; //a few for reserved sectors, etc. dataSectors += extra_MB*1024*1024/512; //add extra write space //dataSectors += 16*1024*1024/512; //add 16MB worth of write space. this is probably enough for anyone, but maybe it should be configurable. //we could always suggest to users to add a big file to their directory to overwrite (that would cause the image to get padded) //this seems to be the minimum size that will turn into a solid fat32 if(dataSectors<36*1024*1024/512) dataSectors = 36*1024*1024/512; if(dataSectors>=(0x80000000>>9)) { printf("error allocating memory for fat (%d KBytes)\n",(dataSectors*512)/1024); printf("total fat sizes > 2GB are never going to work\n"); } delete file; try { file = new EMUFILE_MEMORY(dataSectors*512); } catch(std::bad_alloc) { printf("error allocating memory for fat (%d KBytes)\n",(dataSectors*512)/1024); printf("(out of memory)\n"); return false; } //debug.. //file = new EMUFILE_FILE("c:\\temp.ima","rb+"); //format the disk { EmuFat fat(file); EmuFatVolume vol; u8 ok = vol.init(&fat); vol.formatNew(dataSectors); //ensure we are working in memory, just in case we were testing with a disk file. //libfat will need to go straight to memory (for now; we could easily change it to work with the disk) file = file->memwrap(); } EMUFILE_MEMORY* memf = (EMUFILE_MEMORY*)file; //setup libfat and write all the files through it LIBFAT::Init(memf->buf(),memf->size()); list_files(path, build_ListCallback); LIBFAT::Shutdown(); return true; }
bool LoadSample(const char *name) { SampleLoaded = 0; if (!name) return true; EMUFILE_FILE inf(name,"rb"); if (inf.fail()) return false; //wav reading code adapted from AUDIERE (LGPL) // read the RIFF header u8 riff_id[4]; u32 riff_length; u8 riff_datatype[4]; inf.fread(riff_id, 4); inf.read_32LE(riff_length); inf.fread(riff_datatype, 4); if (inf.size() < 12 || memcmp(riff_id, "RIFF", 4) != 0 || riff_length == 0 || memcmp(riff_datatype, "WAVE", 4) != 0) { MessageBox(0,"not a valid RIFF WAVE file",0,0); return false; } if (!formatChunk(inf)) return false; if (!dataChunk(inf)) { MessageBox(0,"not a valid WAVE file. some unknown problem.",0,0); return false; } delete[] samplebuffer; samplebuffersize = (int)newWavData.size(); samplebuffer = new char[samplebuffersize]; memcpy(samplebuffer,newWavData.buf(),samplebuffersize); new(&newWavData) EMUFILE_MEMORY(); SampleLoaded=1; return true; }
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); }
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); }
int SaveStateEmbed(char *file) { GPUFreeze_t *gpufP; int Size; unsigned char *pMem; EMUFILE_FILE ef(file, "ab"); if (ef.fail()) return -1; EMUFILE *f = &ef; gzwrite(f, (void*)PSXjinHeader, 32); pMem = (unsigned char *) malloc(128*96*3); if (pMem == NULL) return -1; //GPU_getScreenPic(pMem); memset(pMem,0,128*96*3); int tag = 'ExPs'; gzwrite(f, &tag, 4); Size = exceptionPatches.size(); gzwrite(f, &Size, 4); for (int i = 0; i < Size; i++) { gzwrite(f, &exceptionPatches[i].first, 4); gzwrite(f, &exceptionPatches[i].second, 4); } gzwrite(f, pMem, 128*96*3-4-4-Size*4*2); free(pMem); gzwrite(f, psxM, 0x00200000); gzwrite(f, psxP, 0x00010000); gzwrite(f, psxR, 0x00080000); gzwrite(f, psxH, 0x00010000); gzwrite(f, (void*)&psxRegs, sizeof(psxRegs)); if (Config.HLE) psxBiosFreeze(1); // gpu gpufP = (GPUFreeze_t *) malloc(sizeof(GPUFreeze_t)); gpufP->ulFreezeVersion = 1; GPUfreeze(1, gpufP); void* temp = gpufP->extraData; gpufP->extraData = 0; gzwrite(f, gpufP, sizeof(GPUFreeze_t)); gzwrite(f, temp, gpufP->extraDataSize); GPUfreeze(3, gpufP); free(gpufP); sioFreeze(f, 1); cdrFreeze(f, 1); psxHwFreeze(f, 1); CDRisoFreeze(f,1); psxRcntFreeze(f, 1); mdecFreeze(f, 1); //TODO - no movie state? are you sure? // spu EMUFILE_MEMORY memfile; SPUfreeze_new(&memfile); Size = memfile.size(); gzwrite(f, &Size, 4); gzwrite(f, memfile.buf(),Size); return 0; }
int SaveStateEmufile(EMUFILE *f) { GPUFreeze_t *gpufP; int Size; unsigned char *pMem; gzwrite(f, (void*)PSXjinHeader, 32); pMem = (unsigned char *) malloc(128*96*3); if (pMem == NULL) return -1; memset(pMem,0,128*96*3); // Ugh. We need to store this information, but in a backwards-compatible fashion. Do this // by (ab)using the gap previously occupied by GPU_getScreenPic. The data is tagged so it // can be detected on savestate load int tag = 'ExPs'; gzwrite(f, &tag, 4); Size = exceptionPatches.size(); gzwrite(f, &Size, 4); for (int i = 0; i < Size; i++) { gzwrite(f, &exceptionPatches[i].first, 4); gzwrite(f, &exceptionPatches[i].second, 4); } gzwrite(f, pMem, 128*96*3-4-4-Size*4*2); free(pMem); gzwrite(f, psxM, 0x00200000); gzwrite(f, psxP, 0x00010000); gzwrite(f, psxR, 0x00080000); gzwrite(f, psxH, 0x00010000); gzwrite(f, (void*)&psxRegs, sizeof(psxRegs)); if (Config.HLE) psxBiosFreeze(1); // gpu gpufP = (GPUFreeze_t *) malloc(sizeof(GPUFreeze_t)); gpufP->ulFreezeVersion = 1; GPUfreeze(1, gpufP); void* temp = gpufP->extraData; gpufP->extraData = 0; gzwrite(f, gpufP, sizeof(GPUFreeze_t)); gzwrite(f, temp, gpufP->extraDataSize); GPUfreeze(3, gpufP); free(gpufP); sioFreeze(f, 1); cdrFreeze(f, 1); psxHwFreeze(f, 1); CDRisoFreeze(f,1); psxRcntFreeze(f, 1); mdecFreeze(f, 1); PadFreeze(f, 1); MovieFreeze(f, 1); EMUFILE_MEMORY memfile; SPUfreeze_new(&memfile); Size = memfile.size(); gzwrite(f, &Size, 4); gzwrite(f, memfile.buf(),Size); return 0; }