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
This commit is contained in:
parent
473b954991
commit
7c06c4d2ab
|
@ -1084,7 +1084,7 @@ void FCEUMOV_AddInputState()
|
||||||
else if(movieMode == MOVIEMODE_PLAY)
|
else if(movieMode == MOVIEMODE_PLAY)
|
||||||
{
|
{
|
||||||
//stop when we run out of frames
|
//stop when we run out of frames
|
||||||
if(currFrameCounter == (int)currMovieData.records.size())
|
if(currFrameCounter >= (int)currMovieData.records.size())
|
||||||
{
|
{
|
||||||
FinishPlayback();
|
FinishPlayback();
|
||||||
}
|
}
|
||||||
|
@ -1307,11 +1307,13 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size)
|
||||||
|
|
||||||
if (sameTimeline)
|
if (sameTimeline)
|
||||||
{
|
{
|
||||||
//if the frame counter is longer than our current movie, then error
|
//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
|
||||||
if(currFrameCounter > (int)currMovieData.records.size()) //adelikat: TODO: finished mode needs something different here
|
//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
|
//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;
|
return false;
|
||||||
}
|
}
|
||||||
movieMode = MOVIEMODE_PLAY;
|
movieMode = MOVIEMODE_PLAY;
|
||||||
|
@ -1323,7 +1325,7 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else //Read + write
|
||||||
{
|
{
|
||||||
//truncate before we copy, just to save some time
|
//truncate before we copy, just to save some time
|
||||||
tempMovieData.truncateAt(currFrameCounter);
|
tempMovieData.truncateAt(currFrameCounter);
|
||||||
|
|
|
@ -776,10 +776,8 @@ bool FCEUSS_Load(const char *fname)
|
||||||
//Update input display if movie is loaded
|
//Update input display if movie is loaded
|
||||||
extern uint32 cur_input_display;
|
extern uint32 cur_input_display;
|
||||||
extern uint8 FCEU_GetJoyJoy(void);
|
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);
|
cur_input_display = FCEU_GetJoyJoy(); //Input display should show the last buttons pressed (stored in the savestate)
|
||||||
else
|
|
||||||
cur_input_display = FCEU_GetJoyJoy();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue