Added logic to protect against TAS seek overruns in Qt/SDL emulation thread.

This commit is contained in:
mjbudd77 2022-01-10 07:16:52 -05:00
parent d380fc7f50
commit a673ee4a26
2 changed files with 24 additions and 0 deletions

View File

@ -158,6 +158,11 @@ void PLAYBACK::update()
// pause when seeking hits pause_frame // pause when seeking hits pause_frame
if (pauseFrame && currFrameCounter + 1 >= pauseFrame) if (pauseFrame && currFrameCounter + 1 >= pauseFrame)
{ {
// force frame counter back to target pause frame,
// since Qt/SDL port is multithreaded, emulation thread sometimes overshoots target
// before GUI thread can shutoff seek.
//currFrameCounter = pauseFrame - 1;
stopSeeking(); stopSeeking();
} }
else if (currFrameCounter >= getLastPosition() && currFrameCounter >= currMovieData.getNumRecords() - 1 && mustAutopauseAtTheEnd && taseditorConfig->autopauseAtTheEndOfMovie && !isTaseditorRecording()) else if (currFrameCounter >= getLastPosition() && currFrameCounter >= currMovieData.getNumRecords() - 1 && mustAutopauseAtTheEnd && taseditorConfig->autopauseAtTheEndOfMovie && !isTaseditorRecording())
@ -363,6 +368,7 @@ void PLAYBACK::startSeekingToFrame(int frame)
void PLAYBACK::stopSeeking() void PLAYBACK::stopSeeking()
{ {
pauseFrame = 0; pauseFrame = 0;
//printf("Seek Finished\n");
//if ( turbo ) //if ( turbo )
//{ //{
// printf("Turbo seek off\n"); // printf("Turbo seek off\n");
@ -567,6 +573,7 @@ int PLAYBACK::getLastPosition()
return lastPositionFrame - 1; return lastPositionFrame - 1;
} }
// getPauseFrame must be thread safe, it is called from both GUI and emulation threads.
int PLAYBACK::getPauseFrame() int PLAYBACK::getPauseFrame()
{ {
return pauseFrame - 1; return pauseFrame - 1;

View File

@ -1194,6 +1194,23 @@ static void DoFun(int frameskip, int periodic_saves)
static int fskipc = 0; static int fskipc = 0;
//static int opause = 0; //static int opause = 0;
// If TAS editor is engaged, check whether a seek frame is set.
// If a seek is in progress, don't emulate past target frame.
if ( tasWindowIsOpen() )
{
int runToFrameTarget;
runToFrameTarget = tasWin->playback.getPauseFrame();
if ( runToFrameTarget >= 0)
{
if ( currFrameCounter >= runToFrameTarget )
{
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED);
return;
}
}
}
//TODO peroidic saves, working on it right now //TODO peroidic saves, working on it right now
if (periodic_saves && FCEUD_GetTime() % PERIODIC_SAVE_INTERVAL < 30){ if (periodic_saves && FCEUD_GetTime() % PERIODIC_SAVE_INTERVAL < 30){
FCEUI_SaveState(NULL, false); FCEUI_SaveState(NULL, false);