bool BackupDevice::export_no_gba(const char* fname) { std::vector<u8> data(fsize); u32 pos = fpMC->ftell(); fpMC->fseek(0, SEEK_SET); fread((char*)&data[0], 1, fsize, fpMC->get_fp()); fpMC->fseek(pos, SEEK_SET); FILE* outf = fopen(fname,"wb"); if(!outf) return false; u32 size = data.size(); u32 padSize = pad_up_size(size); if(data.size()>0) fwrite(&data[0],1,size,outf); for(u32 i=size;i<padSize;i++) fputc(0xFF,outf); if (padSize < 512 * 1024) { for(u32 i=padSize; i<512 * 1024; i++) fputc(0xFF,outf); } fclose(outf); return true; }
//======================================================================= end //======================================================================= //======================================================================= no$GBA bool BackupDevice::export_raw(const char* filename) { size_t elements_read; std::vector<u8> data(fsize); u32 pos = fpMC->ftell(); fpMC->fseek(0, SEEK_SET); elements_read = fread(&data[0], 1, fsize, fpMC->get_fp()); if (elements_read != fsize) printf( "Expected %u bytes from saved state but read %lu.\n", fsize, elements_read ); fpMC->fseek(pos, SEEK_SET); FILE* outf = fopen(filename,"wb"); if(!outf) return false; u32 size = data.size(); u32 padSize = pad_up_size(size); if(data.size()>0) fwrite(&data[0],1,size,outf); for(u32 i=size;i<padSize;i++) fputc(uninitializedValue,outf); fclose(outf); return true; }
bool BackupDevice::save_raw(const char* filename) { FILE* outf = fopen(filename,"wb"); if(!outf) return false; u32 size = data.size(); u32 padSize = pad_up_size(size); if(data.size()>0) fwrite(&data[0],1,size,outf); for(u32 i=size;i<padSize;i++) fputc(kUninitializedSaveDataValue,outf); fclose(outf); return true; }
void BackupDevice::ensure(u32 addr, u8 val, EMUFILE_FILE *fpOut) { if (!fpOut && (addr < fsize)) return; EMUFILE_FILE *fp = fpOut?fpOut:fpMC; #ifndef _DONT_SAVE_BACKUP fp->fseek(fsize, SEEK_SET); #endif u32 padSize = pad_up_size(addr); u32 size = padSize - fsize; info.padSize = info.size = fsize = padSize; int type = searchFileSaveType(fsize); if (type != 0xFF) info.type = (type + 1); #ifndef _DONT_SAVE_BACKUP if (size > 0) { u8 *tmp = new u8[size]; memset(tmp, val, size); fwrite(tmp, 1, size, fp->get_fp()); delete [] tmp; } //this is just for humans to read fp->fprintf(DESMUME_BACKUP_FOOTER_TXT); //and now the actual footer fp->write32le(addr); //the size of data that has actually been written fp->write32le(padSize); //the size we padded it to fp->write32le(info.type); //save memory type fp->write32le(addr_size); fp->write32le(info.size); //save memory size fp->write32le((u32)0); //version number fp->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save fp->fflush(); //this is a HORRIBLE IDEA. //leave the FP positioned to write the final byte //this is a HACK to make the basic read/write byte operation work when it calls ensure(). //IDEALLY, no assumptions about the file pointer can be made. //but someone (actually, not really) so very carefully profiled the save IO code and discovered that not fseeking for every byte read/write was a great optimization. //so, now all this code is depending/assuming on the FP being kept in a precise position, and I dont think its smart to change the main user of this assumption to paper over this bug by making it fseek before read/write, while leaving other unknown assuming clients intact fpMC->fseek(addr-1, SEEK_SET); #endif }
bool BackupDevice::save_no_gba(const char* fname) { FILE* outf = fopen(fname,"wb"); if(!outf) return false; u32 size = data.size(); u32 padSize = pad_up_size(size); if(data.size()>0) fwrite(&data[0],1,size,outf); for(u32 i=size;i<padSize;i++) fputc(0xFF,outf); if (padSize < 512 * 1024) { for(u32 i=padSize; i<512 * 1024; i++) fputc(0xFF,outf); } fclose(outf); return true; }
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()); } }
void BackupDevice::ensure(u32 addr, u8 val, EMUFILE_FILE *fpOut) { if (!fpOut && (addr < fsize)) return; EMUFILE_FILE *fp = fpOut?fpOut:fpMC; #ifndef _DONT_SAVE_BACKUP fp->fseek(fsize, SEEK_SET); #endif u32 padSize = pad_up_size(addr); u32 size = padSize - fsize; info.padSize = info.size = fsize = padSize; int type = searchFileSaveType(fsize); if (type != 0xFF) info.type = (type + 1); #ifndef _DONT_SAVE_BACKUP if (size > 0) { u8 *tmp = new u8[size]; memset(tmp, val, size); fwrite(tmp, 1, size, fp->get_fp()); delete [] tmp; } //this is just for humans to read fp->fprintf(DESMUME_BACKUP_FOOTER_TXT); //and now the actual footer fp->write32le(addr); //the size of data that has actually been written fp->write32le(padSize); //the size we padded it to fp->write32le(info.type); //save memory type fp->write32le(addr_size); fp->write32le(info.size); //save memory size fp->write32le((u32)0); //version number fp->fprintf("%s", kDesmumeSaveCookie); //this is what we'll use to recognize the desmume format save fp->fflush(); fp->fseek(addr, SEEK_SET); #endif }
//======================================================================= end //======================================================================= //======================================================================= no$GBA bool BackupDevice::export_raw(const char* filename) { std::vector<u8> data(fsize); u32 pos = fpMC->ftell(); fpMC->fseek(0, SEEK_SET); fread((char*)&data[0], 1, fsize, fpMC->get_fp()); fpMC->fseek(pos, SEEK_SET); FILE* outf = fopen(filename,"wb"); if(!outf) return false; u32 size = data.size(); u32 padSize = pad_up_size(size); if(data.size()>0) fwrite(&data[0],1,size,outf); for(u32 i=size;i<padSize;i++) fputc(kUninitializedSaveDataValue,outf); fclose(outf); return true; }