From 40926ab5f7c01599fa63b0ec8449678753b2c1a8 Mon Sep 17 00:00:00 2001 From: adelikat Date: Tue, 23 Dec 2008 22:44:04 +0000 Subject: [PATCH] More undo savestate fixes. Win32 - Undo/Redo savestate menu item added. --- src/drivers/win/state.cpp | 3 ++- src/drivers/win/window.cpp | 43 +++++++++++++++++++++++++++----- src/fceu.cpp | 4 +++ src/state.cpp | 50 ++++++++++++++------------------------ src/state.h | 9 ++++--- 5 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/drivers/win/state.cpp b/src/drivers/win/state.cpp index 07340a1a..de0cfcb2 100644 --- a/src/drivers/win/state.cpp +++ b/src/drivers/win/state.cpp @@ -68,7 +68,8 @@ void FCEUD_LoadStateFrom() bool CheckBackupSaveStateExist() { - //This function simply checks to see if the backup savestate of the appropriate filename exists + //This function simply checks to see if the backup loadstate exists, the backup loadstate is a special savestate + //That is made before loading any state, so that the user never loses his data string filename = GetBackupFileName(); //Get backup savestate filename //Check if this filename exists diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 92bbe836..07998818 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -94,7 +94,10 @@ void ShowNetplayConsole(void); //mbg merge 7/17/06 YECH had to add void MapInput(void); extern BOOL CALLBACK ReplayMetadataDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); //Metadata dialog extern bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists -extern void SwapSaveState(); +//From src/state.cpp +extern bool undoSS; //Decides if undo savestate is eligible +extern bool redoSS; //Decides if it should be called redo instead of undo +extern void SwapSaveState(); //Performs the undo/redo operation //AutoFire----------------------------------------------- void SetAutoFirePattern(int onframes, int offframes); @@ -115,6 +118,10 @@ int MainWindow_wndx, MainWindow_wndy; static uint32 mousex,mousey,mouseb; static int vchanged = 0; +//Function Declarations +void ChangeMenuItemText(int menuitem, string text); //Alters a menu item name +void ChangeContextMenuItemText(int menuitem, string text, HMENU menu); //Alters a context menu item name + //Recent Menu Strings ------------------------------------ char *recent_files[] = { 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 }; const unsigned int MENU_FIRST_RECENT_FILE = 600; @@ -412,7 +419,24 @@ void UpdateCheckedMenuItems() void UpdateContextMenuItems(HMENU context, int whichContext) { bool exist; + string redoSavestate = "Redo savestate"; + string undoSavestate = "Undo savestate"; + //Undo Loadstate + exist = CheckBackupSaveStateExist(); + EnableMenuItem(context,FCEUX_CONTEXT_UNDOLOADSTATE,MF_BYCOMMAND | exist ? MF_ENABLED : MF_GRAYED); + + //Undo Savestate + if (undoSS || redoSS) //If undo or redo, enable Undo savestate, else keep it gray + EnableMenuItem(context,FCEUX_CONTEXT_UNDOSAVESTATE,MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(context,FCEUX_CONTEXT_UNDOSAVESTATE,MF_BYCOMMAND | MF_GRAYED); + if (redoSS) + ChangeContextMenuItemText(FCEUX_CONTEXT_UNDOSAVESTATE, redoSavestate, context); + else + ChangeContextMenuItemText(FCEUX_CONTEXT_UNDOSAVESTATE, undoSavestate, context); + + //Case specific menu item handling switch(whichContext) { //0 = Game + Movie in read only @@ -420,16 +444,12 @@ void UpdateContextMenuItems(HMENU context, int whichContext) break; //1 = Game + No Movie case 1: - exist = CheckBackupSaveStateExist(); - EnableMenuItem(context,FCEUX_CONTEXT_UNDOLOADSTATE,MF_BYCOMMAND | exist ? MF_ENABLED : MF_GRAYED); break; //2 = No Game case 2: break; //3 = Game + Movie in read + write case 3: - exist = CheckBackupSaveStateExist(); - EnableMenuItem(context,FCEUX_CONTEXT_UNDOLOADSTATE,MF_BYCOMMAND | exist ? MF_ENABLED : MF_GRAYED); break; default: break; @@ -790,7 +810,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) hfceuxcontextsub = GetSubMenu(hfceuxcontext,2); whichContext = 2; } -UpdateContextMenuItems(hfceuxcontextsub, whichContext); + UpdateContextMenuItems(hfceuxcontextsub, whichContext); TrackPopupMenu(hfceuxcontextsub,0,(MainWindow_wndx+mousex),(MainWindow_wndy+mousey),TPM_RIGHTBUTTON,hWnd,0); } @@ -1830,6 +1850,17 @@ void FCEUD_LuaRunFrom(void) } } +void ChangeContextMenuItemText(int menuitem, string text, HMENU menu) +{ + MENUITEMINFO moo; + moo.cbSize = sizeof(moo); + moo.fMask = MIIM_TYPE; + moo.cch = NULL; + GetMenuItemInfo(menu, menuitem, FALSE, &moo); + moo.dwTypeData = (LPSTR)text.c_str(); + SetMenuItemInfo(menu, menuitem, FALSE, &moo); +} + void ChangeMenuItemText(int menuitem, string text) { MENUITEMINFO moo; diff --git a/src/fceu.cpp b/src/fceu.cpp index f7f12596..f38597da 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -124,6 +124,10 @@ static void CloseGame(void) delete GameInfo; GameInfo = 0; + + lastSavestateMade[0] = 0; + undoSS = false; + redoSS = false; } } diff --git a/src/state.cpp b/src/state.cpp index 71981e0d..348ee95d 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -60,7 +60,8 @@ static int StateShow; bool FCEU_state_loading_old_format; char lastSavestateMade[2048]; //Stores the last savestate made (needed for UndoSavestate) -bool redoSS = false; //This will be true if UndoSaveState is run, will turn false when a new savestate is made +bool undoSS = false; //This will be true if there is a backup state for lastSavestateMade +bool redoSS = false; //This will be true if UndoSaveState is run, will turn false when a new savestate is made #define SFMDATA_SIZE (64) static SFORMAT SFMDATA[SFMDATA_SIZE]; @@ -435,10 +436,10 @@ void FCEUSS_Save(const char *fname) { CreateBackupSaveState(fname); //Make a backup of previous savestate before overwriting it strcpy(lastSavestateMade,fname); //Remember what the last savestate filename was (for undoing later) - redoSS = true; //Backup was created so redo is possible + undoSS = true; //Backup was created so redo is possible } else - redoSS = false; //No backup was needed, so lastSavestateMade does not contain a file that has a backup + undoSS = false; //so backup made so lastSavestateMade does have a backup file, so no undo st =FCEUD_UTF8_fstream(fname, "wb"); } @@ -452,10 +453,10 @@ void FCEUSS_Save(const char *fname) { CreateBackupSaveState(fn); //Make a backup of previous savestate before overwriting it strcpy(lastSavestateMade,fn); //Remember what the last savestate filename was (for undoing later) - redoSS = true; //Backup was created so redo is possible + undoSS = true; //Backup was created so redo is possible } else - redoSS = false; //No backup was needed, so lastSavestateMade does not contain a file that has a backup + undoSS = false; //so backup made so lastSavestateMade does have a backup file, so no undo st = FCEUD_UTF8_fstream(fn,"wb"); free(fn); @@ -889,33 +890,12 @@ string GenerateBackupSaveStateFn(const char *fname) void CreateBackupSaveState(const char *fname) { - string filename = GenerateBackupSaveStateFn(fname); - std::fstream* st = 0; - st = FCEUD_UTF8_fstream(filename.c_str(),"wb"); - - if(st == NULL) - { - FCEU_DispMessage("State %d save error.",filename.c_str()); - return; - } - - if(FCEUMOV_Mode(MOVIEMODE_INACTIVE)) - FCEUSS_SaveMS(st,-1); - else - FCEUSS_SaveMS(st,0); - - delete st; + string newFilename = GenerateBackupSaveStateFn(fname); //Get backup savestate filename + if (CheckFileExists(newFilename.c_str())) //See if backup already exists + remove(newFilename.c_str()) ; //If so, delete it + rename(fname,newFilename.c_str()); //Rename savestate to backup filename + undoSS = true; //There is a backup savestate file to mast last loaded, so undo is possible } -//--------------------------------------------------------------------------------------------------------------------------------------------------- -//Logic - undo available until a new savestate is made,game is closed, or fcuex is closed - -//What we need is a concept of if you are undoing or redoing as well -//Undo should know there is a bak file before making a decision. the main platform code should know this before calling it. -//Once it is undone, it should know this and call it a redo if called again on the same file. It should remember as long as it knows about undo. -//The undo redo is meaningless information for this function as it simply swaps. -//perhaps a combo of flag(s) and a function to handle flag situations is called for? -//This function would then simply swap the files, which means it is both undo and redo - //And extra function needs to be in charge of flags to keep up with which one is being done, but that is purely cosmetic void SwapSaveState() { @@ -946,7 +926,13 @@ void SwapSaveState() rename(backup.c_str(),temp.c_str()); //rename backup file to temp file rename(lastSavestateMade,backup.c_str()); //rename current as backup rename(temp.c_str(),lastSavestateMade); //rename backup as current - + + undoSS = true; //Just in case, if this was run, then there is definately a last savestate and backup + if (redoSS) //This was a redo function, so if run again it will be an undo again + redoSS = false; + else //This was an undo function so next will be redo, so flag it + redoSS = true; + FCEUI_DispMessage("%s restored",backup.c_str()); FCEUI_printf("%s restored\n",backup.c_str()); } diff --git a/src/state.h b/src/state.h index 734c2743..c0c25320 100644 --- a/src/state.h +++ b/src/state.h @@ -62,6 +62,9 @@ void AddExState(void *v, uint32 s, int type, char *desc); void FCEU_DrawSaveStates(uint8 *XBuf); void CreateBackupSaveState(const char *fname); //backsup a savestate before overwriting it with a new one -void BackupLoadState(); //Makes a backup savestate before any loadstate -void LoadBackup(); //Loads the backupsavestate -void SwapSaveState(); //Swaps a savestate with its backup state \ No newline at end of file +void BackupLoadState(); //Makes a backup savestate before any loadstate +void LoadBackup(); //Loads the backupsavestate +void SwapSaveState(); //Swaps a savestate with its backup state +extern bool undoSS; //undo savestate flag +extern bool redoSS; //redo savestate flag +extern char lastSavestateMade[2048]; //Filename of last savestate used \ No newline at end of file