/**************************************************************************** * FCE Ultra 0.98.12 * Nintendo Wii/Gamecube Port * * Tantric 2008-2009 * * fceustate.cpp * * Memory Based Load/Save RAM Manager * * These are the battery-backed RAM (save data) routines, brought together * as GCxxxxx * The original file I/O is replaced with Memory Read/Writes to the * savebuffer below ****************************************************************************/ #include #include #include #include #include #include "fceugx.h" #include "menu.h" #include "filebrowser.h" #include "memcardop.h" #include "fileop.h" extern "C" { #include "types.h" #include "fceu.h" #include "ppu.h" #include "cart.h" #include "x6502.h" #include "general.h" extern u32 iNESGameCRC32; extern CartInfo iNESCart; extern CartInfo UNIFCart; } static u32 NGCFCEU_GameSave(CartInfo *LocalHWInfo, int operation, int method) { u32 offset = 0; if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0]) { int x; for(x=0;x<4;x++) { if(LocalHWInfo->SaveGame[x]) { if(operation == 0) // save to file memcpy(savebuffer+offset, LocalHWInfo->SaveGame[x], LocalHWInfo->SaveGameLen[x]); else // load from file memcpy(LocalHWInfo->SaveGame[x], savebuffer+offset, LocalHWInfo->SaveGameLen[x]); offset += LocalHWInfo->SaveGameLen[x]; } } } return offset; } bool SaveRAM (char * filepath, int method, bool silent) { bool retval = false; int datasize = 0; int offset = 0; if(nesGameType == 4) { if(!silent) InfoPrompt("RAM saving is not available for FDS games!"); return false; } if(method == METHOD_AUTO) method = autoSaveMethod(silent); if(method == METHOD_AUTO) return false; AllocSaveBuffer (); // save game save to savebuffer if(nesGameType == 1) datasize = NGCFCEU_GameSave(&iNESCart, 0, method); else if(nesGameType == 2) datasize = NGCFCEU_GameSave(&UNIFCart, 0, method); if (datasize) { if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) { // Set the comments char comments[2][32]; memset(comments, 0, 64); sprintf (comments[0], "%s RAM", APPNAME); snprintf (comments[1], 32, romFilename); SetMCSaveComments(comments); } offset = SaveFile(filepath, datasize, method, silent); if (offset > 0) { if (!silent) InfoPrompt("Save successful"); retval = true; } } else { if (!silent) InfoPrompt("No data to save!"); } FreeSaveBuffer (); return retval; } bool SaveRAMAuto (int method, bool silent) { if(method == METHOD_AUTO) method = autoSaveMethod(silent); if(method == METHOD_AUTO) return false; char filepath[1024]; if(!MakeFilePath(filepath, FILE_RAM, method, romFilename, 0)) return false; return SaveRAM(filepath, method, silent); } bool LoadRAM (char * filepath, int method, bool silent) { int offset = 0; bool retval = false; if(nesGameType == 4) // RAM saves don't exist for FDS games return false; if(method == METHOD_AUTO) method = autoSaveMethod(silent); // we use 'Save' because we need R/W if(method == METHOD_AUTO) return false; AllocSaveBuffer (); offset = LoadFile(filepath, method, silent); if (offset > 0) { if(nesGameType == 1) NGCFCEU_GameSave(&iNESCart, 1, method); else if(nesGameType == 2) NGCFCEU_GameSave(&UNIFCart, 1, method); ResetNES(); retval = true; } else { // if we reached here, nothing was done! if(!silent) InfoPrompt ("Save file not found"); } FreeSaveBuffer (); return retval; } bool LoadRAMAuto (int method, bool silent) { if(method == METHOD_AUTO) method = autoSaveMethod(silent); if(method == METHOD_AUTO) return false; char filepath[MAXPATHLEN]; char fullpath[MAXPATHLEN]; char filepath2[MAXPATHLEN]; char fullpath2[MAXPATHLEN]; // look for Auto save file if(!MakeFilePath(filepath, FILE_RAM, method, romFilename, 0)) return false; if (LoadRAM(filepath, method, silent)) return true; // look for file with no number or Auto appended if(!MakeFilePath(filepath2, FILE_RAM, method, romFilename, -1)) return false; if(LoadRAM(filepath2, method, silent)) { // rename this file - append Auto sprintf(fullpath, "%s%s", rootdir, filepath); // add device to path sprintf(fullpath2, "%s%s", rootdir, filepath2); // add device to path rename(fullpath2, fullpath); // rename file (to avoid duplicates) return true; } return false; }