State recorder in work.

This commit is contained in:
harry 2023-03-11 07:47:58 -05:00
parent 326d09d546
commit bc6164260d
6 changed files with 95 additions and 3 deletions

View File

@ -53,6 +53,7 @@
#include "../../input.h" #include "../../input.h"
#include "../../movie.h" #include "../../movie.h"
#include "../../wave.h" #include "../../wave.h"
#include "../../state.h"
#include "../../version.h" #include "../../version.h"
#include "common/os_utils.h" #include "common/os_utils.h"
@ -920,6 +921,9 @@ void consoleWin_t::initHotKeys(void)
connect( Hotkeys[ HK_LOAD_STATE_7 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState7(void)) ); connect( Hotkeys[ HK_LOAD_STATE_7 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState7(void)) );
connect( Hotkeys[ HK_LOAD_STATE_8 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState8(void)) ); connect( Hotkeys[ HK_LOAD_STATE_8 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState8(void)) );
connect( Hotkeys[ HK_LOAD_STATE_9 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState9(void)) ); connect( Hotkeys[ HK_LOAD_STATE_9 ].getShortcut(), SIGNAL(activated()), this, SLOT(loadState9(void)) );
connect( Hotkeys[ HK_LOAD_PREV_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(loadPrevState(void)) );
connect( Hotkeys[ HK_LOAD_NEXT_STATE ].getShortcut(), SIGNAL(activated()), this, SLOT(loadNextState(void)) );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void consoleWin_t::createMainMenu(void) void consoleWin_t::createMainMenu(void)
@ -2729,6 +2733,20 @@ void consoleWin_t::loadState7(void){ loadState(7); }
void consoleWin_t::loadState8(void){ loadState(8); } void consoleWin_t::loadState8(void){ loadState(8); }
void consoleWin_t::loadState9(void){ loadState(9); } void consoleWin_t::loadState9(void){ loadState(9); }
void consoleWin_t::loadPrevState(void)
{
FCEU_WRAPPER_LOCK();
FCEU_StateRecorderLoadState( FCEU_StateRecorderGetStateIndex()-1 );
FCEU_WRAPPER_UNLOCK();
}
void consoleWin_t::loadNextState(void)
{
FCEU_WRAPPER_LOCK();
FCEU_StateRecorderLoadState( FCEU_StateRecorderGetStateIndex()-1 );
FCEU_WRAPPER_UNLOCK();
}
void consoleWin_t::quickSave(void) void consoleWin_t::quickSave(void)
{ {
FCEU_WRAPPER_LOCK(); FCEU_WRAPPER_LOCK();

View File

@ -439,6 +439,8 @@ class consoleWin_t : public QMainWindow
void loadState7(void); void loadState7(void);
void loadState8(void); void loadState8(void);
void loadState9(void); void loadState9(void);
void loadPrevState(void);
void loadNextState(void);
void mainMenuOpen(void); void mainMenuOpen(void);
void mainMenuClose(void); void mainMenuClose(void);
void warnAmbiguousShortcut( QShortcut*); void warnAmbiguousShortcut( QShortcut*);

View File

@ -295,6 +295,12 @@ int getHotKeyConfig( int i, const char **nameOut, const char **keySeqOut, const
case HK_SELECT_STATE_PREV: case HK_SELECT_STATE_PREV:
name = "SelectStatePrev"; keySeq = ""; title = "Select Previous State Slot"; group = "State"; name = "SelectStatePrev"; keySeq = ""; title = "Select Previous State Slot"; group = "State";
break; break;
case HK_LOAD_PREV_STATE:
name = "LoadPrevState"; keySeq = ""; title = "Load Previous Recorded State"; group = "State";
break;
case HK_LOAD_NEXT_STATE:
name = "LoadNextState"; keySeq = ""; title = "Load Next Recorded State"; group = "State";
break;
case HK_VOLUME_MUTE: case HK_VOLUME_MUTE:
name = "VolumeMute"; keySeq = ""; title = "Sound Volume Mute"; group = "Sound"; name = "VolumeMute"; keySeq = ""; title = "Sound Volume Mute"; group = "Sound";
break; break;

View File

@ -34,6 +34,9 @@ enum HOTKEY {
HK_SELECT_STATE_5, HK_SELECT_STATE_6, HK_SELECT_STATE_7, HK_SELECT_STATE_8, HK_SELECT_STATE_9, HK_SELECT_STATE_5, HK_SELECT_STATE_6, HK_SELECT_STATE_7, HK_SELECT_STATE_8, HK_SELECT_STATE_9,
HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV, HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV,
// State Recorder
HK_LOAD_PREV_STATE, HK_LOAD_NEXT_STATE,
// GUI // GUI
HK_FULLSCREEN, HK_MAIN_MENU_HIDE, HK_FULLSCREEN, HK_MAIN_MENU_HIDE,

View File

@ -1202,6 +1202,9 @@ class StateRecorder
frameCounter = 0; frameCounter = 0;
framesPerSnap = 3 * 60; framesPerSnap = 3 * 60;
compressionLevel = Z_NO_COMPRESSION; compressionLevel = Z_NO_COMPRESSION;
lastState = ringHead;
loadIndexReset = false;
lastLoadFrame = 0;
} }
~StateRecorder(void) ~StateRecorder(void)
@ -1215,9 +1218,22 @@ class StateRecorder
void update(void) void update(void)
{ {
bool isPaused = FCEUI_EmulationPaused() ? true : false;
unsigned int curFrame = static_cast<unsigned int>(currFrameCounter); unsigned int curFrame = static_cast<unsigned int>(currFrameCounter);
if (curFrame != frameCounter) if (!isPaused && loadIndexReset)
{
int ringBufSize = static_cast<int>( ringBuf.size() );
ringHead = (lastState + 1) % ringBufSize;
frameCounter = curFrame;
loadIndexReset = false;
}
if (!isPaused && (curFrame > frameCounter) )
{ {
frameCounter = curFrame; frameCounter = curFrame;
@ -1233,17 +1249,19 @@ class StateRecorder
//printf("Frame:%u Save:%i Size:%zu Total:%zukB \n", frameCounter, ringHead, em->size(), dataSize() / 1024 ); //printf("Frame:%u Save:%i Size:%zu Total:%zukB \n", frameCounter, ringHead, em->size(), dataSize() / 1024 );
lastState = ringHead;
ringHead = (ringHead + 1) % ringBufSize; ringHead = (ringHead + 1) % ringBufSize;
if (ringStart == ringHead) if (ringStart == ringHead)
{ // Buffer Overrun {
ringStart = (ringHead + 1) % ringBufSize; ringStart = (ringHead + 1) % ringBufSize;
} }
} }
} }
} }
int loadState( int numSnapsFromLatest ) int loadStateRelativeToEnd( int numSnapsFromLatest )
{ {
int ringBufSize = static_cast<int>( ringBuf.size() ); int ringBufSize = static_cast<int>( ringBuf.size() );
@ -1255,18 +1273,43 @@ class StateRecorder
int snapIdx = ringHead - numSnapsFromLatest - 1; int snapIdx = ringHead - numSnapsFromLatest - 1;
loadStateByIndex(snapIdx);
return 0;
}
int loadStateByIndex( int snapIdx )
{
int ringBufSize = static_cast<int>( ringBuf.size() );
if (snapIdx < 0) if (snapIdx < 0)
{ {
snapIdx = snapIdx + ringBufSize; snapIdx = snapIdx + ringBufSize;
} }
snapIdx = snapIdx % ringBufSize;
EMUFILE_MEMORY *em = ringBuf[ snapIdx ]; EMUFILE_MEMORY *em = ringBuf[ snapIdx ];
FCEUSS_LoadFP( em, SSLOADPARAM_NOBACKUP ); FCEUSS_LoadFP( em, SSLOADPARAM_NOBACKUP );
frameCounter = lastLoadFrame = static_cast<unsigned int>(currFrameCounter);
lastState = snapIdx;
loadIndexReset = true;
return 0; return 0;
} }
int getHeadIndex(void)
{
return ringHead;
}
int getStartIndex(void)
{
return ringStart;
}
int numSnapsSaved(void) int numSnapsSaved(void)
{ {
int numSnaps = ringHead - ringStart; int numSnaps = ringHead - ringStart;
@ -1284,6 +1327,7 @@ class StateRecorder
} }
static bool enabled; static bool enabled;
static int lastState;
private: private:
void doSnap(void) void doSnap(void)
@ -1298,11 +1342,14 @@ class StateRecorder
int compressionLevel; int compressionLevel;
unsigned int frameCounter; unsigned int frameCounter;
unsigned int framesPerSnap; unsigned int framesPerSnap;
unsigned int lastLoadFrame;
bool loadIndexReset;
}; };
static StateRecorder *stateRecorder = nullptr; static StateRecorder *stateRecorder = nullptr;
bool StateRecorder::enabled = false; bool StateRecorder::enabled = false;
int StateRecorder::lastState = 0;
int FCEU_StateRecorderStart(void) int FCEU_StateRecorderStart(void)
{ {
@ -1340,3 +1387,17 @@ bool FCEU_StateRecorderRunning(void)
{ {
return stateRecorder != nullptr; return stateRecorder != nullptr;
} }
int FCEU_StateRecorderLoadState(int snapIndex)
{
if (stateRecorder != nullptr)
{
stateRecorder->loadStateByIndex(snapIndex);
}
return 0;
}
int FCEU_StateRecorderGetStateIndex(void)
{
return StateRecorder::lastState;
}

View File

@ -84,3 +84,5 @@ int FCEU_StateRecorderStop(void);
int FCEU_StateRecorderUpdate(void); int FCEU_StateRecorderUpdate(void);
bool FCEU_StateRecorderRunning(void); bool FCEU_StateRecorderRunning(void);
bool FCEU_StateRecorderIsEnabled(void); bool FCEU_StateRecorderIsEnabled(void);
int FCEU_StateRecorderGetStateIndex(void);
int FCEU_StateRecorderLoadState(int snapIndex);