Skip to content

Commit 3e9398f

Browse files
committed
Added a timed pause state for use by the state history loader. When the user backs up to a previous state, give the option of temporarily pausing to give the user time to visually process the state before resuming game play. When in this state, an unpause count down can also be optionally shown on the upper left of the video display. Also, setting pause during this state down will cancel the count down and put the emulation into full pause. TODO add GUI config hooks to control video overlay and duration config options.
1 parent b6a8b46 commit 3e9398f

File tree

7 files changed

+96
-4
lines changed

7 files changed

+96
-4
lines changed

src/drawing.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ void FCEU_DrawRecordingStatus(uint8* XBuf)
346346
hasPlayRecIcon = true;
347347
}
348348

349-
if(FCEUI_EmulationPaused())
349+
if( EmulationPaused & (EMULATIONPAUSED_PAUSED | EMULATIONPAUSED_TIMER) )
350350
drawstatus(XBuf-ClipSidesOffset,3,28,hasPlayRecIcon?-16:0);
351351
}
352352
}

src/driver.h

+2
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ void FCEUI_ClearEmulationFrameStepped();
273273
void FCEUI_SetEmulationPaused(int val);
274274
///toggles the paused bit (bit0) for EmulationPaused. caused FCEUD_DebugUpdate() to fire if the emulation pauses
275275
void FCEUI_ToggleEmulationPause();
276+
void FCEUI_PauseForDuration(int secs);
277+
int FCEUI_PauseFramesRemaining();
276278

277279
//indicates whether input aids should be drawn (such as crosshairs, etc; usually in fullscreen mode)
278280
bool FCEUD_ShouldDrawInputAids();

src/fceu.cpp

+45-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ bool movieSubtitles = true; //Toggle for displaying movie subtitles
116116
bool DebuggerWasUpdated = false; //To prevent the debugger from updating things without being updated.
117117
bool AutoResumePlay = false;
118118
char romNameWhenClosingEmulator[2048] = {0};
119+
static unsigned int pauseTimer = 0;
119120

120121

121122
FCEUGI::FCEUGI()
@@ -764,6 +765,22 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
764765
#endif
765766
}
766767

768+
if (EmulationPaused & EMULATIONPAUSED_TIMER)
769+
{
770+
if (pauseTimer > 0)
771+
{
772+
pauseTimer--;
773+
}
774+
else
775+
{
776+
EmulationPaused &= ~EMULATIONPAUSED_TIMER;
777+
}
778+
if (EmulationPaused & EMULATIONPAUSED_PAUSED)
779+
{
780+
EmulationPaused &= ~EMULATIONPAUSED_TIMER;
781+
}
782+
}
783+
767784
if (EmulationPaused & EMULATIONPAUSED_FA)
768785
{
769786
// the user is holding Frame Advance key
@@ -787,7 +804,7 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
787804
RefreshThrottleFPS();
788805
}
789806
#endif
790-
if (EmulationPaused & EMULATIONPAUSED_PAUSED)
807+
if (EmulationPaused & (EMULATIONPAUSED_PAUSED | EMULATIONPAUSED_TIMER) )
791808
{
792809
// emulator is paused
793810
memcpy(XBuf, XBackBuf, 256*256);
@@ -1263,6 +1280,33 @@ void FCEUI_FrameAdvance(void) {
12631280
frameAdvanceRequested = true;
12641281
}
12651282

1283+
void FCEUI_PauseForDuration(int secs)
1284+
{
1285+
int framesPerSec;
1286+
1287+
// If already paused, do nothing
1288+
if (EmulationPaused & EMULATIONPAUSED_PAUSED)
1289+
{
1290+
return;
1291+
}
1292+
1293+
if (PAL || dendy)
1294+
{
1295+
framesPerSec = 50;
1296+
}
1297+
else
1298+
{
1299+
framesPerSec = 60;
1300+
}
1301+
pauseTimer = framesPerSec * secs;
1302+
EmulationPaused |= EMULATIONPAUSED_TIMER;
1303+
}
1304+
1305+
int FCEUI_PauseFramesRemaining(void)
1306+
{
1307+
return (EmulationPaused & EMULATIONPAUSED_TIMER) ? pauseTimer : 0;
1308+
}
1309+
12661310
static int AutosaveCounter = 0;
12671311

12681312
void UpdateAutosave(void) {

src/fceu.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,9 @@ extern uint8 vsdip;
181181

182182
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
183183

184-
#define EMULATIONPAUSED_PAUSED 1
185-
#define EMULATIONPAUSED_FA 2
184+
#define EMULATIONPAUSED_PAUSED 0x01
185+
#define EMULATIONPAUSED_TIMER 0x02
186+
#define EMULATIONPAUSED_FA 0x04
186187

187188
#define FRAMEADVANCE_DELAY_DEFAULT 10
188189
#define NES_HEADER_SIZE 16

src/state.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,7 @@ class StateRecorder
12051205
lastState = ringHead;
12061206
loadIndexReset = false;
12071207
lastLoadFrame = 0;
1208+
loadPauseTime = 3;
12081209
}
12091210

12101211
~StateRecorder(void)
@@ -1243,6 +1244,7 @@ class StateRecorder
12431244
printf("ringBufSize:%i framesPerSnap:%i\n", ringBufSize, framesPerSnap );
12441245

12451246
compressionLevel = stateRecorderConfig.compressionLevel;
1247+
loadPauseTime = stateRecorderConfig.loadPauseTimeSeconds;
12461248
}
12471249

12481250
void update(void)
@@ -1318,6 +1320,11 @@ class StateRecorder
13181320
lastState = snapIdx;
13191321
loadIndexReset = true;
13201322

1323+
if (loadPauseTime > 0)
1324+
{ // Temporary pause after loading new state for user to have time to process
1325+
FCEUI_PauseForDuration(loadPauseTime);
1326+
}
1327+
13211328
return 0;
13221329
}
13231330

@@ -1362,6 +1369,7 @@ class StateRecorder
13621369
int ringStart;
13631370
int ringBufSize;
13641371
int compressionLevel;
1372+
int loadPauseTime;
13651373
unsigned int frameCounter;
13661374
unsigned int framesPerSnap;
13671375
unsigned int lastLoadFrame;

src/state.h

+2
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,14 @@ struct StateRecorderConfigData
8484
float historyDurationMinutes;
8585
float timeBetweenSnapsMinutes;
8686
int compressionLevel;
87+
int loadPauseTimeSeconds;
8788

8889
StateRecorderConfigData(void)
8990
{
9091
historyDurationMinutes = 15.0f;
9192
timeBetweenSnapsMinutes = 3.0f / 60.0f;
9293
compressionLevel = 0;
94+
loadPauseTimeSeconds = 3;
9395
}
9496
};
9597

src/video.cpp

+35
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ std::string AsSnapshotName =""; //adelikat:this will set the snapshot name whe
8787
void FCEUI_SetSnapshotAsName(std::string name) { AsSnapshotName = name; }
8888
std::string FCEUI_GetSnapshotAsName() { return AsSnapshotName; }
8989

90+
static void FCEU_DrawPauseCountDown(uint8 *XBuf);
91+
9092
void FCEU_KillVirtualVideo(void)
9193
{
9294
if ( XBuf )
@@ -254,6 +256,7 @@ void FCEU_PutImage(void)
254256
FCEU_DrawLagCounter(XBuf);
255257
FCEU_DrawNTSCControlBars(XBuf);
256258
FCEU_DrawRecordingStatus(XBuf);
259+
FCEU_DrawPauseCountDown(XBuf);
257260
ShowFPS();
258261
}
259262

@@ -771,3 +774,35 @@ void ShowFPS(void)
771774

772775
DrawTextTrans(XBuf + ((256 - ClipSidesOffset) - 40) + (FSettings.FirstSLine + 4) * 256, 256, (uint8*)fpsmsg, 0xA0);
773776
}
777+
778+
bool showPauseCountDown = true;
779+
780+
static void FCEU_DrawPauseCountDown(uint8 *XBuf)
781+
{
782+
if (EmulationPaused & EMULATIONPAUSED_TIMER)
783+
{
784+
int pauseFramesLeft = FCEUI_PauseFramesRemaining();
785+
786+
if (showPauseCountDown && (pauseFramesLeft > 0) )
787+
{
788+
char text[32];
789+
int framesPerSec;
790+
791+
if (PAL || dendy)
792+
{
793+
framesPerSec = 50;
794+
}
795+
else
796+
{
797+
framesPerSec = 60;
798+
}
799+
800+
sprintf(text, "Unpausing in %d...", (pauseFramesLeft / framesPerSec) + 1);
801+
802+
if (text[0])
803+
{
804+
DrawTextTrans(XBuf + ClipSidesOffset + (FSettings.FirstSLine) * 256, 256, (uint8*)text, 0xA0);
805+
}
806+
}
807+
}
808+
}

0 commit comments

Comments
 (0)