From 7c06c4d2abfa30edd93ca01256f02ffed13405e1 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sat, 15 May 2010 21:22:16 +0000 Subject: [PATCH] Fixed up more loadstate logic. We had a slight logic error this whole time that wasn't a problem until now. Checking to see if a state is a future event, we assumed frame counter of the state matched the length of the movie. Now that movie finished is a mode, that is no longer true. Fixed that, and fixed the input display updating at the end of a load state to always look at the state input rather than the statemovie last record. This fixes proper behavior of saving and loading states during movie finished mode as per the "Laws of TAS": http://tasvideos.org/Adelikat/LawsOfTAS.html --- src/movie.cpp | 12 +++++++----- src/state.cpp | 8 +++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/movie.cpp b/src/movie.cpp index fed4c429..96cba795 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -1084,7 +1084,7 @@ void FCEUMOV_AddInputState() else if(movieMode == MOVIEMODE_PLAY) { //stop when we run out of frames - if(currFrameCounter == (int)currMovieData.records.size()) + if(currFrameCounter >= (int)currMovieData.records.size()) { FinishPlayback(); } @@ -1307,11 +1307,13 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size) if (sameTimeline) { - //if the frame counter is longer than our current movie, then error - if(currFrameCounter > (int)currMovieData.records.size()) //adelikat: TODO: finished mode needs something different here + //if we made it this far, then the savestate has identical movie data but we want to know now if the stateMOVIE size is greater than current movie size and make this error + //then we want to know if currFramecoutner > currmoviedata.records.size so we can know it is time for movie finished handling + //currFrameCounter is currently savestate frame counter (not savestate movie size + if(tempMovieData.records.size() > currMovieData.records.size()) { //TODO: turn frame counter to red to get attention - 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); + FCEU_PrintError("Savestate is from a frame (%d) after the final frame in the movie (%d). This is not permitted.", tempMovieData.records.size(), currMovieData.records.size()-1); return false; } movieMode = MOVIEMODE_PLAY; @@ -1323,7 +1325,7 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size) return false; } } - else + else //Read + write { //truncate before we copy, just to save some time tempMovieData.truncateAt(currFrameCounter); diff --git a/src/state.cpp b/src/state.cpp index cd9a14c7..1acf3236 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -776,11 +776,9 @@ bool FCEUSS_Load(const char *fname) //Update input display if movie is loaded extern uint32 cur_input_display; extern uint8 FCEU_GetJoyJoy(void); - if (FCEUMOV_Mode(MOVIEMODE_RECORD|MOVIEMODE_PLAY|MOVIEMODE_FINISHED)) //adelikat: just doing GetJoyJoy regardless should work, but I just felt conceptually movies should be relying on movie data. There might be some fringe cases where this is necessary. - memcpy(&cur_input_display,currMovieData.records[currFrameCounter-1].joysticks.data,4); - else - cur_input_display = FCEU_GetJoyJoy(); - + + cur_input_display = FCEU_GetJoyJoy(); //Input display should show the last buttons pressed (stored in the savestate) + return true; } else