bool SavePalettes(bool silent) { char filepath[1024]; int datasize; int offset = 0; if(prefpath[0] == 0) return false; sprintf(filepath, "%s/%s", prefpath, PAL_FILE_NAME); // Now create the XML palette file if (!silent) ShowAction("Saving palette..."); AllocSaveBuffer(); datasize = preparePalData(palettes, loadedPalettes); offset = SaveFile(filepath, datasize, silent); FreeSaveBuffer(); CancelAction(); if (offset > 0) { if (!silent) InfoPrompt("Palette saved"); return true; } return false; }
bool LoadState (char * filepath, bool silent) { int offset = 0; bool retval = false; int device; if(!FindDevice(filepath, &device)) return 0; AllocSaveBuffer (); offset = LoadFile(filepath, silent); if (offset > 0) { EMUFILE_MEMFILE save(savebuffer, offset); FCEUSS_LoadFP(&save, SSLOADPARAM_NOBACKUP); retval = true; } else { // if we reached here, nothing was done! if(!silent) ErrorPrompt ("State file not found"); } FreeSaveBuffer (); return retval; }
/**************************************************************************** * Load Palettes ***************************************************************************/ bool LoadPalettes() { bool retval = false; int offset = 0; char filepath[MAXPATHLEN]; AllocSaveBuffer (); sprintf(filepath, "%s/%s", prefpath, PAL_FILE_NAME); offset = LoadFile(filepath, SILENT); if (offset > 0) retval = decodePalsData (); FreeSaveBuffer (); // add hard-coded palettes for (int i=0; i<gamePalettesCount; i++) AddPalette(gamePalettes[i], gamePalettes[i].gameName, false); if (!retval) retval = SavePalettes(SILENT); return retval; }
/**************************************************************************** * SetupCheats * * Erases any prexisting cheats, loads cheats from a cheat file * Called when a ROM is first loaded ***************************************************************************/ void SetupCheats() { char filepath[1024]; int offset = 0; S9xInitCheatData (); S9xDeleteCheats (); int method = GCSettings.SaveMethod; if(method == METHOD_AUTO) method = autoSaveMethod(SILENT); if(!MakeFilePath(filepath, FILE_CHEAT, method)) return; AllocSaveBuffer(); offset = LoadFile(filepath, method, SILENT); // load cheat file if present if(offset > 0) { if(NGCLoadCheatFile (offset)) { // disable all cheats loaded from the file for (uint16 i = 0; i < Cheat.num_cheats; i++) S9xDisableCheat(i); } } FreeSaveBuffer (); }
/**************************************************************************** * Load Preferences from specified filepath ***************************************************************************/ bool LoadPrefsFromMethod (char * path) { bool retval = false; int offset = 0; char filepath[MAXPATHLEN]; sprintf(filepath, "%s/%s", path, PREF_FILE_NAME); AllocSaveBuffer (); offset = LoadFile(filepath, SILENT); if (offset > 0) retval = decodePrefsData (); FreeSaveBuffer (); if(retval) { strcpy(prefpath, path); if(appPath[0] == 0) strcpy(appPath, prefpath); } return retval; }
/**************************************************************************** * SetupCheats * * Erases any prexisting cheats, loads cheats from a cheat file * Called when a ROM is first loaded ***************************************************************************/ void WiiSetupCheats() { memset(Cheat.c, 0, sizeof(Cheat.c)); Cheat.num_cheats = 0; char filepath[1024]; int offset = 0; if(!MakeFilePath(filepath, FILE_CHEAT)) return; AllocSaveBuffer(); offset = LoadFile(filepath, SILENT); // load cheat file if present if(offset > 0) LoadCheatFile (offset); FreeSaveBuffer (); }
bool SavePrefs (bool silent) { char filepath[MAXPATHLEN]; int datasize; int offset = 0; int device = 0; if(prefpath[0] != 0) { sprintf(filepath, "%s/%s", prefpath, PREF_FILE_NAME); FindDevice(filepath, &device); } else if(appPath[0] != 0) { sprintf(filepath, "%s/%s", appPath, PREF_FILE_NAME); strcpy(prefpath, appPath); FindDevice(filepath, &device); } else { device = autoSaveMethod(silent); if(device == 0) return false; sprintf(filepath, "%s%s", pathPrefix[device], APPFOLDER); DIR *dir = opendir(filepath); if (!dir) { if(mkdir(filepath, 0777) != 0) return false; sprintf(filepath, "%s%s/roms", pathPrefix[device], APPFOLDER); if(mkdir(filepath, 0777) != 0) return false; sprintf(filepath, "%s%s/saves", pathPrefix[device], APPFOLDER); if(mkdir(filepath, 0777) != 0) return false; } else { closedir(dir); } sprintf(filepath, "%s%s/%s", pathPrefix[device], APPFOLDER, PREF_FILE_NAME); sprintf(prefpath, "%s%s", pathPrefix[device], APPFOLDER); } if(device == 0) return false; if (!silent) ShowAction ("Saving preferences..."); FixInvalidSettings(); AllocSaveBuffer (); datasize = preparePrefsData (); offset = SaveFile(filepath, datasize, silent); FreeSaveBuffer (); CancelAction(); if (offset > 0) { if (!silent) InfoPrompt("Preferences saved"); return true; } return false; }
bool SaveBatteryOrState(char * filepath, int action, bool silent) { bool result = false; int offset = 0; int datasize = 0; // we need the actual size of the data written int device; if(!FindDevice(filepath, &device)) return 0; if(action == FILE_SNAPSHOT && gameScreenPngSize > 0) { char screenpath[1024]; strncpy(screenpath, filepath, 1024); screenpath[strlen(screenpath)-4] = 0; sprintf(screenpath, "%s.png", screenpath); SaveFile((char *)gameScreenPng, screenpath, gameScreenPngSize, silent); } AllocSaveBuffer(); // put VBA memory into savebuffer, sets datasize to size of memory written if(action == FILE_SRAM) { if(cartridgeType == 1) datasize = MemgbWriteBatteryFile((char *)savebuffer); else datasize = MemCPUWriteBatteryFile((char *)savebuffer); if (cartridgeType == 1) { const char* generic_goomba_error = "Cannot save SRAM in Goomba format (did not load correctly.)"; // check for goomba sram format char* old_sram = (char*)malloc(GOOMBA_COLOR_SRAM_SIZE); size_t br = LoadFile(old_sram, filepath, GOOMBA_COLOR_SRAM_SIZE, true); if (br >= GOOMBA_COLOR_SRAM_SIZE && goomba_is_sram(old_sram)) { void* cleaned = goomba_cleanup(old_sram); if (cleaned == NULL) { ErrorPrompt(generic_goomba_error); datasize = 0; } else { if (cleaned != old_sram) { free(old_sram); old_sram = (char*)cleaned; } stateheader* sh = stateheader_for(old_sram, RomTitle); if (sh == NULL) { // Game probably doesn't use SRAM datasize = 0; } else { void* new_sram = goomba_new_sav(old_sram, sh, savebuffer, datasize); if (new_sram == NULL) { ErrorPrompt(goomba_last_error()); datasize = 0; } else { memcpy(savebuffer, new_sram, GOOMBA_COLOR_SRAM_SIZE); datasize = GOOMBA_COLOR_SRAM_SIZE; free(new_sram); } } } } free(old_sram); } } else { if(emulator.emuWriteMemState((char *)savebuffer, SAVEBUFFERSIZE)) datasize = *((int *)(savebuffer+4)) + 8; } // write savebuffer into file if(datasize > 0) { offset = SaveFile(filepath, datasize, silent); if(offset > 0) { if(!silent) InfoPrompt ("Save successful"); result = true; } } else { if(!silent) InfoPrompt("No data to save!"); } FreeSaveBuffer(); return result; }
bool LoadBatteryOrState(char * filepath, int action, bool silent) { bool result = false; int offset = 0; int device; if(!FindDevice(filepath, &device)) return 0; AllocSaveBuffer(); // load the file into savebuffer offset = LoadFile(filepath, silent); if (cartridgeType == 1 && goomba_is_sram(savebuffer)) { void* cleaned = goomba_cleanup(savebuffer); if (savebuffer == NULL) { ErrorPrompt(goomba_last_error()); offset = 0; } else { if (cleaned != savebuffer) { memcpy(savebuffer, cleaned, GOOMBA_COLOR_SRAM_SIZE); free(cleaned); } stateheader* sh = stateheader_for(savebuffer, RomTitle); if (sh == NULL) { ErrorPrompt(goomba_last_error()); offset = 0; } else { goomba_size_t outsize; void* gbc_sram = goomba_extract(savebuffer, sh, &outsize); if (gbc_sram == NULL) { ErrorPrompt(goomba_last_error()); offset = 0; } else { memcpy(savebuffer, gbc_sram, outsize); offset = outsize; free(gbc_sram); } } } } // load savebuffer into VBA memory if (offset > 0) { if(action == FILE_SRAM) { if(cartridgeType == 1) result = MemgbReadBatteryFile((char *)savebuffer, offset); else result = MemCPUReadBatteryFile((char *)savebuffer, offset); } else { result = emulator.emuReadMemState((char *)savebuffer, offset); } } FreeSaveBuffer(); if(!silent && !result) { if(offset == 0) { if(action == FILE_SRAM) ErrorPrompt ("Save file not found"); else ErrorPrompt ("State file not found"); } else { if(action == FILE_SRAM) ErrorPrompt ("Invalid save file"); else ErrorPrompt ("Invalid state file"); } } return result; }
/**************************************************************************** * NGCUnfreezeGame ***************************************************************************/ int NGCUnfreezeGame (int method, bool8 silent) { char filepath[1024]; int offset = 0; int result = 0; char msg[80]; bufoffset = 0; ShowAction ((char*) "Loading..."); if(method == METHOD_AUTO) method = autoSaveMethod(); // we use 'Save' because snapshot needs R/W if(!MakeFilePath(filepath, FILE_SNAPSHOT, method)) return 0; AllocSaveBuffer (); offset = LoadFile(filepath, method, silent); if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) // MC in slot A or slot B { if (offset) { char * zipbuffer = (char *)malloc(SAVEBUFFERSIZE); memset (zipbuffer, 0, SAVEBUFFERSIZE); // skip the saveicon and comment offset = (sizeof(saveicon) + 64); uLongf zipsize = 0; uLongf decompressedsize = 0; memcpy (&zipsize, savebuffer+offset, 4); offset += 4; memcpy (&decompressedsize, savebuffer+offset, 4); offset += 4; uLongf DestBuffSize = SAVEBUFFERSIZE; int err= uncompress((Bytef*)zipbuffer, (uLongf*)&DestBuffSize, (const Bytef*)(savebuffer + offset), zipsize); if ( err!=Z_OK ) { sprintf (msg, "Unzip error %s ",zError(err)); WaitPrompt (msg); } else if ( DestBuffSize != decompressedsize ) { WaitPrompt((char*) "Unzipped size doesn't match expected size!"); } else { offset = SAVEBUFFERSIZE; memcpy (savebuffer, zipbuffer, SAVEBUFFERSIZE); } free(zipbuffer); } } if(offset > 0) { if (S9xUnfreezeGame ("AGAME") == SUCCESS) result = 1; else WaitPrompt((char*) "Error thawing"); } else { if(!silent) WaitPrompt((char*) "Freeze file not found"); } FreeSaveBuffer (); return result; }
/**************************************************************************** * NGCFreezeGame * * Do freeze game for Nintendo Gamecube ***************************************************************************/ int NGCFreezeGame (int method, bool8 silent) { char filepath[1024]; int offset = 0; // bytes written (actual) int woffset = 0; // bytes written (expected) char msg[100]; ShowAction ((char*) "Saving..."); if(method == METHOD_AUTO) method = autoSaveMethod(); if(!MakeFilePath(filepath, FILE_SNAPSHOT, method)) return 0; S9xSetSoundMute (TRUE); S9xPrepareSoundForSnapshotSave (FALSE); AllocSaveBuffer (); NGCFreezeMemBuffer (); // copy freeze mem into savebuffer woffset = bufoffset; S9xPrepareSoundForSnapshotSave (TRUE); S9xSetSoundMute (FALSE); if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) // MC Slot A or B { // Copy in save icon woffset = sizeof (saveicon); memcpy (savebuffer, saveicon, woffset); // And the freezecomment sprintf (freezecomment[0], "%s Freeze", VERSIONSTR); sprintf (freezecomment[1], Memory.ROMName); memcpy (savebuffer + woffset, freezecomment, 64); woffset += 64; // Zip and copy in the freeze uLongf DestBuffSize = (uLongf) SAVEBUFFERSIZE; int err= compress2((Bytef*)(savebuffer+woffset+8), (uLongf*)&DestBuffSize, (const Bytef*)savebuffer, (uLongf)bufoffset, Z_BEST_COMPRESSION); if(err!=Z_OK) { sprintf (msg, "zip error %s ",zError(err)); WaitPrompt (msg); return 0; } int zippedsize = (int)DestBuffSize; memcpy (savebuffer + woffset, &zippedsize, 4); woffset += 4; int decompressedsize = (int)bufoffset; memcpy (savebuffer + woffset, &decompressedsize, 4); woffset += 4; woffset += zippedsize; } offset = SaveFile(filepath, woffset, method, silent); FreeSaveBuffer (); if(offset > 0) // save successful! { if(!silent) WaitPrompt((char*) "Save successful"); return 1; } return 0; }
bool SaveRAM (char * filepath, bool silent) { bool retval = false; int datasize = 0; int offset = 0; int device; if(!FindDevice(filepath, &device)) return 0; if(GameInfo->type == GIT_FDS) { if(!silent) InfoPrompt("RAM saving is not available for FDS games!"); return false; } AllocSaveBuffer (); // save game save to savebuffer if(GameInfo->type == GIT_CART) datasize = WiiFCEU_GameSave(&iNESCart, 0); else if(GameInfo->type == GIT_VSUNI) datasize = WiiFCEU_GameSave(&UNIFCart, 0); if (datasize) { // Check to see if this is a PocketNES save file FILE* file = fopen(filepath, "rb"); if (file) { uint32 tag; fread(&tag, sizeof(uint32), 1, file); fclose(file); if (goomba_is_sram(&tag)) { void* gba_data = malloc(GOOMBA_COLOR_SRAM_SIZE); file = fopen(filepath, "rb"); fread(gba_data, 1, GOOMBA_COLOR_SRAM_SIZE, file); fclose(file); void* cleaned = goomba_cleanup(gba_data); if (!cleaned) { ErrorPrompt(goomba_last_error()); } else if (cleaned != gba_data) { memcpy(gba_data, cleaned, GOOMBA_COLOR_SRAM_SIZE); free(cleaned); } // Look for just one save file. If there aren't any, or there is more than one, don't read any data. const stateheader* sh1 = NULL; const stateheader* sh2 = NULL; const stateheader* sh = stateheader_first(gba_data); while (sh && stateheader_plausible(sh)) { if (little_endian_conv_16(sh->type) != GOOMBA_SRAMSAVE) {} else if (sh1 == NULL) { sh1 = sh; } else { sh2 = sh; break; } sh = stateheader_advance(sh); } if (sh1 == NULL) { ErrorPrompt("PocketNES save file has no SRAM."); datasize = 0; } else if (sh2 != NULL) { ErrorPrompt("PocketNES save file has more than one SRAM."); datasize = 0; } else { char* newdata = goomba_new_sav(gba_data, sh1, savebuffer, datasize); if (!newdata) { ErrorPrompt(goomba_last_error()); datasize = 0; } else { memcpy(savebuffer, newdata, GOOMBA_COLOR_SRAM_SIZE); datasize = GOOMBA_COLOR_SRAM_SIZE; free(newdata); } } } } } if (datasize) { offset = SaveFile(filepath, datasize, silent); if (offset > 0) { if (!silent) InfoPrompt("Save successful"); retval = true; } } else { if (!silent) InfoPrompt("No data to save!"); } FreeSaveBuffer (); return retval; }
bool LoadRAM (char * filepath, bool silent) { int offset = 0; bool retval = false; int device; if(!FindDevice(filepath, &device)) return 0; if(GameInfo->type == GIT_FDS) // RAM saves don't exist for FDS games return false; AllocSaveBuffer (); offset = LoadFile(filepath, silent); // Check to see if this is a PocketNES save file if (goomba_is_sram(savebuffer)) { void* cleaned = goomba_cleanup(savebuffer); if (!cleaned) { ErrorPrompt(goomba_last_error()); } else if (cleaned != savebuffer) { memcpy(savebuffer, cleaned, GOOMBA_COLOR_SRAM_SIZE); free(cleaned); } // Look for just one save file. If there aren't any, or there is more than one, don't read any data. const stateheader* sh1 = NULL; const stateheader* sh2 = NULL; const stateheader* sh = stateheader_first(savebuffer); while (sh && stateheader_plausible(sh)) { if (little_endian_conv_16(sh->type) != GOOMBA_SRAMSAVE) { } else if (sh1 == NULL) { sh1 = sh; } else { sh2 = sh; break; } sh = stateheader_advance(sh); } if (sh1 == NULL) { ErrorPrompt("PocketNES save file has no SRAM."); offset = 0; } else if (sh2 != NULL) { ErrorPrompt("PocketNES save file has more than one SRAM."); offset = 0; } else { goomba_size_t len; void* extracted = goomba_extract(savebuffer, sh1, &len); if (!extracted) ErrorPrompt(goomba_last_error()); else { memcpy(savebuffer, extracted, len); offset = len; free(extracted); } } } if (offset > 0) { if(GameInfo->type == GIT_CART) WiiFCEU_GameSave(&iNESCart, 1); else if(GameInfo->type == GIT_VSUNI) WiiFCEU_GameSave(&UNIFCart, 1); ResetNES(); retval = true; } else { // if we reached here, nothing was done! if(!silent) InfoPrompt ("Save file not found"); } FreeSaveBuffer (); return retval; }