diff --git a/desmume/src/GPU_osd.cpp b/desmume/src/GPU_osd.cpp index 6ca742656..79698ab83 100644 --- a/desmume/src/GPU_osd.cpp +++ b/desmume/src/GPU_osd.cpp @@ -509,10 +509,12 @@ void DrawHUD() if (CommonSettings.hud.FrameCounterDisplay) { - if (movieMode == MOVIEMODE_PLAY) - osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d/%d",currFrameCounter,currMovieData.records.size()); - else if(movieMode == MOVIEMODE_RECORD) + if(movieMode == MOVIEMODE_RECORD) osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d",currFrameCounter); + else if (movieMode == MOVIEMODE_PLAY) + osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d/%d",currFrameCounter,currMovieData.records.size()); + else if (movieMode == MOVIEMODE_FINISHED) + osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d/%d (finished)",currFrameCounter,currMovieData.records.size()); else osd->addFixed(Hud.FrameCounter.x, Hud.FrameCounter.y, "%d (no movie)",currFrameCounter); } @@ -658,7 +660,7 @@ void OSDCLASS::setListCoord(u16 x, u16 y) lineText_y = y; } -void OSDCLASS::setLineColor(u8 r=255, u8 b=255, u8 g=255) +void OSDCLASS::setLineColor(u8 r=255, u8 g=255, u8 b=255) { lineText_color = AggColor(r,g,b); } diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 3478d1758..7d804a575 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -2802,7 +2802,7 @@ void NDS_setTouchPos(u16 x, u16 y) rawUserInput.touch.touchY = NDS_getADCTouchPosY(y); rawUserInput.touch.isTouch = true; - if(movieMode != MOVIEMODE_INACTIVE) + if(movieMode != MOVIEMODE_INACTIVE && movieMode != MOVIEMODE_FINISHED) { // just in case, since the movie only stores 8 bits per touch coord rawUserInput.touch.touchX &= 0x0FF0; diff --git a/desmume/src/lua-engine.cpp b/desmume/src/lua-engine.cpp index 4ea68ebc7..2db6c6a7b 100644 --- a/desmume/src/lua-engine.cpp +++ b/desmume/src/lua-engine.cpp @@ -3421,6 +3421,9 @@ DEFINE_LUA_FUNCTION(movie_getmode, "") case MOVIEMODE_INACTIVE: lua_pushstring(L, "inactive"); break; + case MOVIEMODE_FINISHED: + lua_pushstring(L, "finished"); + break; default: lua_pushnil(L); break; diff --git a/desmume/src/movie.cpp b/desmume/src/movie.cpp index 6aeb43042..0a7a67794 100644 --- a/desmume/src/movie.cpp +++ b/desmume/src/movie.cpp @@ -176,7 +176,8 @@ MovieData::MovieData() void MovieData::truncateAt(int frame) { - records.resize(frame); + if(records.size() < frame) + records.resize(frame); } @@ -384,6 +385,13 @@ static void StopPlayback() movieMode = MOVIEMODE_INACTIVE; } +/// Stop movie playback without closing the movie. +static void FinishPlayback() +{ + driver->USR_InfoMessage("Movie finished playing."); + movieMode = MOVIEMODE_FINISHED; +} + /// Stop movie recording static void StopRecording() @@ -398,7 +406,7 @@ static void StopRecording() void FCEUI_StopMovie() { - if(movieMode == MOVIEMODE_PLAY) + if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED) StopPlayback(); else if(movieMode == MOVIEMODE_RECORD) StopRecording(); @@ -421,7 +429,7 @@ const char* _CDECL_ FCEUI_LoadMovie(const char *fname, bool _read_only, bool tas return "LoadMovie doesn't support browsing yet"; //mbg 6/10/08 - we used to call StopMovie here, but that cleared curMovieFilename and gave us crashes... - if(movieMode == MOVIEMODE_PLAY) + if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED) StopPlayback(); else if(movieMode == MOVIEMODE_RECORD) StopRecording(); @@ -626,7 +634,7 @@ void _CDECL_ FCEUI_SaveMovie(const char *fname, std::wstring author, int flag, s //stop when we run out of frames if(currFrameCounter == (int)currMovieData.records.size()) { - StopPlayback(); + FinishPlayback(); } else { @@ -758,7 +766,7 @@ void mov_savestate(EMUFILE* fp) //if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY) // return currMovieData.dump(os, true); //else return 0; - if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY) + if(movieMode != MOVIEMODE_INACTIVE) { write32le(kMOVI,fp); currMovieData.dump(fp, true); @@ -834,7 +842,7 @@ bool mov_loadstate(EMUFILE* fp, int size) // then, we must discard this movie and just load the savestate - if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_RECORD) + if(movieMode != MOVIEMODE_INACTIVE) { //handle moviefile mismatch if(tempMovieData.guid != currMovieData.guid) @@ -854,7 +862,30 @@ bool mov_loadstate(EMUFILE* fp, int size) closeRecordingMovie(); - if(movie_readonly) + if(!movie_readonly) + { + ////truncate before we copy, just to save some time + //tempMovieData.truncateAt(currFrameCounter); // disabled because this can really screw things up and shouldn't usually be faster + + currMovieData = tempMovieData; + currMovieData.rerecordCount = currRerecordCount; + } + + if(currFrameCounter > currMovieData.records.size()) + { + // if the frame counter is longer than our current movie, + // switch to "finished" mode. + // this is a mode that behaves like "inactive" + // except it permits switching to play/record by loading an earlier savestate. + // (and we continue to store the finished movie in savestates made while finished) + osd->setLineColor(255,0,0); // let's make the text red too to hopefully catch the user's attention a bit. + FinishPlayback(); + osd->setLineColor(255,255,255); + + //FCEU_PrintError("Savestate is from a frame (%d) after the final frame in the movie (%d). This is not permitted.", currFrameCounter, currMovieData.records.size()-1); + //return false; + } + else if(movie_readonly) { //------------------------------------------------------------- //this code would reload the movie from disk. allegedly it is helpful to hexers, but @@ -872,21 +903,10 @@ bool mov_loadstate(EMUFILE* fp, int size) //} //------------------------------------------------------------- - //if the frame counter is longer than our current movie, then error - if(currFrameCounter > (int)currMovieData.records.size()) - { - FCEU_PrintError("Savestate is from a frame (%d) after the final frame in the movie (%d). This is not permitted.", currFrameCounter, currMovieData.records.size()-1); - return false; - } - movieMode = MOVIEMODE_PLAY; } else { - //truncate before we copy, just to save some time - tempMovieData.truncateAt(currFrameCounter); - currMovieData = tempMovieData; - // #ifdef _S9XLUA_H // if(!FCEU_LuaRerecordCountSkip()) currRerecordCount++; @@ -1014,7 +1034,6 @@ static bool CheckFileExists(const char* filename) if (!fp) { - fclose(fp); return false; } else diff --git a/desmume/src/movie.h b/desmume/src/movie.h index 6b1be485f..1183f3537 100644 --- a/desmume/src/movie.h +++ b/desmume/src/movie.h @@ -26,9 +26,10 @@ typedef struct enum EMOVIEMODE { - MOVIEMODE_INACTIVE = 1, - MOVIEMODE_RECORD = 2, - MOVIEMODE_PLAY = 4, + MOVIEMODE_INACTIVE = 0, + MOVIEMODE_RECORD = 1, + MOVIEMODE_PLAY = 2, + MOVIEMODE_FINISHED = 3, }; enum EMOVIECMD diff --git a/desmume/src/windows/hotkey.cpp b/desmume/src/windows/hotkey.cpp index 97d5ea847..823b65b1e 100644 --- a/desmume/src/windows/hotkey.cpp +++ b/desmume/src/windows/hotkey.cpp @@ -223,10 +223,24 @@ void HK_ResetLagCounter(int, bool justPressed) { } void HK_ToggleReadOnly(int, bool justPressed) { movie_readonly ^= true; + + char msg [64]; + char* pMsg = msg; if(movie_readonly) - osd->addLine("Read Only"); + pMsg += sprintf(pMsg, "Read-Only"); else - osd->addLine("Read+Write"); + pMsg += sprintf(pMsg, "Read+Write"); + if(movieMode == MOVIEMODE_INACTIVE) + pMsg += sprintf(pMsg, " (no movie)"); + if(movieMode == MOVIEMODE_FINISHED) + pMsg += sprintf(pMsg, " (finished)"); + if(movieMode == MOVIEMODE_INACTIVE) + osd->setLineColor(255,0,0); + else if(movieMode == MOVIEMODE_FINISHED) + osd->setLineColor(255,255,0); + else + osd->setLineColor(255,255,255); + osd->addLine(msg); } void HK_PlayMovie(int, bool justPressed) @@ -325,7 +339,7 @@ void HK_PreviousSaveSlot(int, bool justPressed) { osd->addLine("State %i selected", lastSaveState); } -void HK_Pause(int, bool justPressed) { Pause(); } +void HK_Pause(int, bool justPressed) { TogglePause(); } void HK_FastForwardToggle(int, bool justPressed) { FastForward ^=1; } void HK_FastForwardKeyDown(int, bool justPressed) { FastForward = 1; } void HK_FastForwardKeyUp(int) { FastForward = 0; } diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 56fcc7fc1..3d5c5bfd0 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -1738,13 +1738,9 @@ class WinDriver : public BaseDriver virtual void EMU_PauseEmulation(bool pause) { if(pause) - { - void Pause(); Pause(); - } + Pause(); else - { - void Unpause(); Unpause(); - } + Unpause(); } virtual bool EMU_IsEmulationPaused() @@ -2873,6 +2869,13 @@ void Unpause() } void Pause() +{ + lastPauseFromLostFocus = FALSE; + if (!emu_paused) NDS_Pause(); + emu_paused = 1; +} + +void TogglePause() { lastPauseFromLostFocus = FALSE; if (emu_paused) NDS_UnPause(); @@ -2880,6 +2883,7 @@ void Pause() emu_paused ^= 1; } + bool first; void FrameAdvance(bool state) diff --git a/desmume/src/windows/main.h b/desmume/src/windows/main.h index 19d1bd65c..9bf04986e 100644 --- a/desmume/src/windows/main.h +++ b/desmume/src/windows/main.h @@ -10,6 +10,8 @@ void NDS_UnPause(bool showMsg = true); void LoadSaveStateInfo(); void Display(); void Pause(); +void Unpause(); +void TogglePause(); void FrameAdvance(bool state); void ResetGame(); //Resets game (for the menu item & hotkey void AviRecordTo();