FCEU state recorder in work.

This commit is contained in:
harry 2023-03-04 16:34:21 -05:00
parent c0eee08ce5
commit d7c23fa92e
4 changed files with 178 additions and 2 deletions

View File

@ -179,10 +179,10 @@ public:
va_start(argptr, format);
vsprintf(tempbuf,format,argptr);
fwrite(tempbuf,amt);
fwrite(tempbuf,amt);
delete[] tempbuf;
va_end(argptr);
va_end(argptr);
return amt;
};

View File

@ -208,6 +208,8 @@ static void FCEU_CloseGame(void)
GameInterface(GI_CLOSE);
FCEU_StateRecorderStop();
FCEUI_StopMovie();
ResetExState(0, 0);
@ -592,6 +594,12 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
}
FCEU_fclose(fp);
if ( FCEU_StateRecorderIsEnabled() )
{
FCEU_StateRecorderStart();
}
return GameInfo;
}
@ -793,6 +801,7 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
AutoFire();
UpdateAutosave();
FCEU_StateRecorderUpdate();
#ifdef _S9XLUA_H
FCEU_LuaFrameBoundary();

View File

@ -1179,3 +1179,164 @@ void RedoLoadState()
redoLS = false; //Flag that RedoLoadState can not be run again
undoLS = true; //Flag that LoadBackup can be run again
}
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//----------- Save State History ----------------
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
class StateRecorder
{
public:
StateRecorder(void)
{
size_t ringBufSize = 60;
for (size_t i=0; i<ringBufSize; i++)
{
EMUFILE_MEMORY *em = new EMUFILE_MEMORY( 0x10000 );
ringBuf.push_back(em);
}
ringStart = ringHead = ringTail = 0;
frameCounter = 0;
framesPerSnap = 3 * 60;
compressionLevel = Z_NO_COMPRESSION;
}
~StateRecorder(void)
{
for (size_t i=0; i<ringBuf.size(); i++)
{
delete ringBuf[i];
}
ringBuf.clear();
}
void update(void)
{
unsigned int curFrame = static_cast<unsigned int>(currFrameCounter);
if (curFrame != frameCounter)
{
frameCounter = curFrame;
if ( (frameCounter % framesPerSnap) == 0 )
{
int ringBufSize = static_cast<int>( ringBuf.size() );
EMUFILE_MEMORY *em = ringBuf[ ringHead ];
em->set_len(0);
FCEUSS_SaveMS( em, compressionLevel );
//printf("Frame:%u Save:%i Size:%zu Total:%zukB \n", frameCounter, ringHead, em->size(), dataSize() / 1024 );
ringHead = (ringHead + 1) % ringBufSize;
if (ringStart == ringHead)
{ // Buffer Overrun
ringStart = (ringHead + 1) % ringBufSize;
}
}
}
}
int loadState( int numSnapsFromLatest )
{
int ringBufSize = static_cast<int>( ringBuf.size() );
if (numSnapsFromLatest < 0)
{
numSnapsFromLatest = 0;
}
numSnapsFromLatest = numSnapsFromLatest % ringBufSize;
int snapIdx = ringHead - numSnapsFromLatest - 1;
if (snapIdx < 0)
{
snapIdx = snapIdx + ringBufSize;
}
EMUFILE_MEMORY *em = ringBuf[ snapIdx ];
FCEUSS_LoadFP( em, SSLOADPARAM_NOBACKUP );
return 0;
}
int numSnapsSaved(void)
{
int numSnaps = ringHead - ringStart;
if (numSnaps < 0)
{
numSnaps = numSnaps + static_cast<int>( ringBuf.size() );
}
return numSnaps;
}
size_t dataSize(void)
{
return ringBuf.size() * ringBuf[0]->size();
}
static bool enabled;
private:
void doSnap(void)
{
}
std::vector <EMUFILE_MEMORY*> ringBuf;
int ringHead;
int ringTail;
int ringStart;
int compressionLevel;
unsigned int frameCounter;
unsigned int framesPerSnap;
};
static StateRecorder *stateRecorder = nullptr;
bool StateRecorder::enabled = false;
int FCEU_StateRecorderStart(void)
{
if (stateRecorder == nullptr)
{
stateRecorder = new StateRecorder();
}
return stateRecorder == nullptr;
}
int FCEU_StateRecorderStop(void)
{
if (stateRecorder != nullptr)
{
delete stateRecorder; stateRecorder = nullptr;
}
return stateRecorder != nullptr;
}
int FCEU_StateRecorderUpdate(void)
{
if (stateRecorder != nullptr)
{
stateRecorder->update();
}
return 0;
}
bool FCEU_StateRecorderIsEnabled(void)
{
return StateRecorder::enabled;
}
bool FCEU_StateRecorderRunning(void)
{
return stateRecorder != nullptr;
}

View File

@ -78,3 +78,9 @@ extern bool backupSavestates; //Whether or not to make backups, true by defaul
bool CheckBackupSaveStateExist(); //Checks if backupsavestate exists
extern bool compressSavestates; //Whether or not to compress non-movie savestates (by default, yes)
int FCEU_StateRecorderStart(void);
int FCEU_StateRecorderStop(void);
int FCEU_StateRecorderUpdate(void);
bool FCEU_StateRecorderRunning(void);
bool FCEU_StateRecorderIsEnabled(void);