From b7daefd0f9545b3d477876edf1d9a64d5203dde4 Mon Sep 17 00:00:00 2001 From: nitsuja Date: Sat, 31 Oct 2009 18:50:55 +0000 Subject: [PATCH] add "finished" movie mode to make TASing less annoying (so you don't have to restart the movie every time you let it reach the last frame). fixed some little bugs like a movie loading crash bug too. --- desmume/src/GPU_osd.cpp | 10 +++--- desmume/src/NDSSystem.cpp | 2 +- desmume/src/lua-engine.cpp | 3 ++ desmume/src/movie.cpp | 57 ++++++++++++++++++++++------------ desmume/src/movie.h | 7 +++-- desmume/src/windows/hotkey.cpp | 20 ++++++++++-- desmume/src/windows/main.cpp | 16 ++++++---- desmume/src/windows/main.h | 2 ++ 8 files changed, 81 insertions(+), 36 deletions(-) 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();