Movies now have a "finished" option. If a playback stops the movie isn't cleared from memory, and can be replayed or a state loaded. Similar functionality as DeSmuME and GENS rerecording.
This commit is contained in:
parent
4456368632
commit
9006fd7a73
|
@ -1,4 +1,5 @@
|
|||
11-may-2010 - 10-may-2010 - adelikat - Loadstate updates input display
|
||||
12-may-2010 - adelikat - Movies now have a "finished" option. If a playback stops the movie isn't cleared from memory, and can be replayed or a state loaded. Similar functionality as DeSmuME and GENS rerecording
|
||||
11-may-2010 - adelikat - Loadstate updates input display
|
||||
11-may-2010 - ugetab - Win32 - Added Ram Search hotkeys for the first 6 search types in the list.
|
||||
10-may-2010 - ugetab - Added gui.getpixel() which gets any gui.pixel() set pixel colors, and possibly other functions. Added emu.getscreenpixel() which gets the RGB and Palette of any pixel on the screen.
|
||||
08-may-2010 - ugetab - Added savestate.object() which is savestate.create() with intuitive numbering under windows
|
||||
|
|
|
@ -336,7 +336,7 @@ void FCEU_DrawRecordingStatus(uint8* XBuf)
|
|||
drawstatus(XBuf-ClipSidesOffset,2,28,0);
|
||||
hasPlayRecIcon = true;
|
||||
}
|
||||
else if(FCEUMOV_Mode(MOVIEMODE_PLAY))
|
||||
else if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_FINISHED))
|
||||
{
|
||||
drawstatus(XBuf-ClipSidesOffset,1,28,0);
|
||||
hasPlayRecIcon = true;
|
||||
|
|
|
@ -1237,14 +1237,14 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|||
hfceuxcontext = LoadMenu(fceu_hInstance,"FCEUCONTEXTMENUS");
|
||||
|
||||
//If There is a movie loaded in read only
|
||||
if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD) && movie_readonly)
|
||||
if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED) && movie_readonly)
|
||||
{
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext,0);
|
||||
whichContext = 0; // Game+Movie+readonly
|
||||
}
|
||||
|
||||
//If there is a movie loaded in read+write
|
||||
else if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD) && !movie_readonly)
|
||||
else if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED) && !movie_readonly)
|
||||
{
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext,3);
|
||||
whichContext = 3; // Game+Movie+readwrite
|
||||
|
@ -2484,7 +2484,7 @@ void FCEUD_AviRecordTo(void)
|
|||
aviDirectory.append("\\"); //if directory override has no \ then add one
|
||||
|
||||
//if we are playing a movie, construct the filename from the current movie.
|
||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD)) //adelikat: TOOD: Think about this. I think MOVIEMODE_FINISHED shouldn't not be included here. Am I wrong?
|
||||
{
|
||||
tempFilename = GetMfn(); //get movie filename
|
||||
tempFilename.erase(0,1); //remove dot
|
||||
|
|
|
@ -611,7 +611,7 @@ void AutoFire(void)
|
|||
//doesn't get screwed up when loading.
|
||||
if(FCEUMOV_Mode(MOVIEMODE_RECORD | MOVIEMODE_PLAY))
|
||||
{
|
||||
rapidAlternator= AutoFirePattern[(AutoFireOffset + FCEUMOV_GetFrame())%AutoFirePatternLength];
|
||||
rapidAlternator= AutoFirePattern[(AutoFireOffset + FCEUMOV_GetFrame())%AutoFirePatternLength]; //adelikat: TODO: Think through this, MOVIEMODE_FINISHED should not use movie data for auto-fire?
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1032,7 +1032,7 @@ bool FCEU_IsValidUI(EFCEUI ui)
|
|||
|
||||
case FCEUI_STOPMOVIE:
|
||||
case FCEUI_PLAYFROMBEGINNING:
|
||||
return FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD);
|
||||
return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED));
|
||||
|
||||
case FCEUI_STOPAVI:
|
||||
return FCEUI_AviIsRecording();
|
||||
|
@ -1043,7 +1043,7 @@ bool FCEU_IsValidUI(EFCEUI ui)
|
|||
|
||||
case FCEUI_RESET:
|
||||
if(!GameInfo) return false;
|
||||
if(FCEUMOV_Mode(MOVIEMODE_TASEDIT|MOVIEMODE_PLAY)) return false;
|
||||
if(FCEUMOV_Mode(MOVIEMODE_FINISHED|MOVIEMODE_TASEDIT|MOVIEMODE_PLAY)) return false;
|
||||
break;
|
||||
|
||||
case FCEUI_POWER:
|
||||
|
|
|
@ -2161,7 +2161,7 @@ static int zapper_read(lua_State *L){
|
|||
int z = 0;
|
||||
extern void GetMouseData(uint32 (&md)[3]); //adelikat: shouldn't this be ifdef'ed for Win32?
|
||||
int x,y,click;
|
||||
if (/*FCEUMOV_IsPlaying()*/ FCEUMOV_Mode(MOVIEMODE_PLAY))
|
||||
if (FCEUMOV_Mode(MOVIEMODE_PLAY))
|
||||
{
|
||||
if (!currFrameCounter)
|
||||
z = 0;
|
||||
|
@ -2580,10 +2580,12 @@ int emu_emulating(lua_State *L) {
|
|||
|
||||
// string movie.mode()
|
||||
//
|
||||
// "record", "playback" or nil
|
||||
// "record", "playback", "finished", or nil
|
||||
int movie_mode(lua_State *L) {
|
||||
if (FCEUMOV_IsRecording())
|
||||
lua_pushstring(L, "record");
|
||||
else if (FCEUMOV_IsFinished())
|
||||
lua_pushstring(L, "finished"); //Note: this comes before plaback since playback checks for finished as well
|
||||
else if (FCEUMOV_IsPlaying())
|
||||
lua_pushstring(L, "playback");
|
||||
else
|
||||
|
|
|
@ -721,7 +721,7 @@ void FCEUI_StopMovie()
|
|||
if(suppressMovieStop)
|
||||
return;
|
||||
|
||||
if(movieMode == MOVIEMODE_PLAY)
|
||||
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED)
|
||||
StopPlayback();
|
||||
else if(movieMode == MOVIEMODE_RECORD)
|
||||
StopRecording();
|
||||
|
@ -834,7 +834,7 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus
|
|||
assert(fname);
|
||||
|
||||
//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();
|
||||
|
@ -978,6 +978,14 @@ void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author)
|
|||
|
||||
static int _currCommand = 0;
|
||||
|
||||
|
||||
// Stop movie playback without closing the movie.
|
||||
static void FinishPlayback()
|
||||
{
|
||||
FCEU_DispMessage("Movie finished playing.");
|
||||
movieMode = MOVIEMODE_FINISHED;
|
||||
}
|
||||
|
||||
//the main interaction point between the emulator and the movie system.
|
||||
//either dumps the current joystick state or loads one state from the movie
|
||||
void FCEUMOV_AddInputState()
|
||||
|
@ -1009,9 +1017,9 @@ void FCEUMOV_AddInputState()
|
|||
else if(movieMode == MOVIEMODE_PLAY)
|
||||
{
|
||||
//stop when we run out of frames
|
||||
if(currFrameCounter == currMovieData.records.size())
|
||||
if(currFrameCounter == (int)currMovieData.records.size())
|
||||
{
|
||||
StopPlayback();
|
||||
FinishPlayback();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1099,6 +1107,8 @@ void FCEU_DrawMovies(uint8 *XBuf)
|
|||
sprintf(counterbuf,"%d/%d",currFrameCounter,currMovieData.records.size());
|
||||
else if(movieMode == MOVIEMODE_RECORD)
|
||||
sprintf(counterbuf,"%d",currMovieData.records.size());
|
||||
else if (movieMode == MOVIEMODE_FINISHED)
|
||||
sprintf(counterbuf,"%d/%d (finished)",currFrameCounter,currMovieData.records.size());
|
||||
else
|
||||
sprintf(counterbuf,"%d (no movie)",currFrameCounter);
|
||||
|
||||
|
@ -1127,7 +1137,7 @@ void FCEU_DrawLagCounter(uint8 *XBuf)
|
|||
int FCEUMOV_WriteState(std::ostream* os)
|
||||
{
|
||||
//we are supposed to dump the movie data into the savestate
|
||||
if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY)
|
||||
if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED)
|
||||
return currMovieData.dump(os, true);
|
||||
else return 0;
|
||||
}
|
||||
|
@ -1151,7 +1161,7 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size)
|
|||
is->seekg((uint32)curr+size);
|
||||
extern bool FCEU_state_loading_old_format;
|
||||
if(FCEU_state_loading_old_format) {
|
||||
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_RECORD) {
|
||||
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_FINISHED) {
|
||||
FCEUI_StopMovie();
|
||||
FCEU_PrintError("You have tried to use an old savestate while playing a movie. This is unsupported (since the old savestate has old-format movie data in it which can't be converted on the fly)");
|
||||
}
|
||||
|
@ -1178,7 +1188,7 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size)
|
|||
// then, we must discard this movie and just load the savestate
|
||||
|
||||
|
||||
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_RECORD)
|
||||
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_FINISHED)
|
||||
{
|
||||
//handle moviefile mismatch
|
||||
if(tempMovieData.guid != currMovieData.guid)
|
||||
|
@ -1203,8 +1213,10 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 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;
|
||||
FinishPlayback();
|
||||
//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);
|
||||
//return false;
|
||||
}
|
||||
movieMode = MOVIEMODE_PLAY;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ enum EMOVIEMODE
|
|||
MOVIEMODE_INACTIVE = 1,
|
||||
MOVIEMODE_RECORD = 2,
|
||||
MOVIEMODE_PLAY = 4,
|
||||
MOVIEMODE_TASEDIT = 8
|
||||
MOVIEMODE_TASEDIT = 8,
|
||||
MOVIEMODE_FINISHED = 16
|
||||
};
|
||||
|
||||
enum EMOVIECMD
|
||||
|
@ -72,8 +73,9 @@ enum EMOVIECMD
|
|||
EMOVIEMODE FCEUMOV_Mode();
|
||||
bool FCEUMOV_Mode(EMOVIEMODE modemask);
|
||||
bool FCEUMOV_Mode(int modemask);
|
||||
inline bool FCEUMOV_IsPlaying() { return FCEUMOV_Mode(MOVIEMODE_PLAY); }
|
||||
inline bool FCEUMOV_IsPlaying() { return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_FINISHED)); }
|
||||
inline bool FCEUMOV_IsRecording() { return FCEUMOV_Mode(MOVIEMODE_RECORD); }
|
||||
inline bool FCEUMOV_IsFinished() { return FCEUMOV_Mode(MOVIEMODE_FINISHED);}
|
||||
|
||||
bool FCEUMOV_ShouldPause(void);
|
||||
int FCEUMOV_GetFrame(void);
|
||||
|
|
|
@ -284,7 +284,7 @@ static bool ReadStateChunks(std::istream* is, int32 totalsize)
|
|||
read_snd=1;
|
||||
break;
|
||||
case 6:
|
||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED))
|
||||
{
|
||||
if(!ReadStateChunk(is,FCEUMOV_STATEINFO,size)) ret=false;
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel)
|
|||
totalsize+=WriteStateChunk(os,31,FCEU_NEWPPU_STATEINFO);
|
||||
totalsize+=WriteStateChunk(os,4,FCEUCTRL_STATEINFO);
|
||||
totalsize+=WriteStateChunk(os,5,FCEUSND_STATEINFO);
|
||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD))
|
||||
if(FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED))
|
||||
{
|
||||
totalsize+=WriteStateChunk(os,6,FCEUMOV_STATEINFO);
|
||||
|
||||
|
@ -776,7 +776,7 @@ 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) || FCEUMOV_Mode(MOVIEMODE_PLAY)) //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.
|
||||
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();
|
||||
|
|
Loading…
Reference in New Issue