From 23c7ce73426128749df604246691a9f0845e6171 Mon Sep 17 00:00:00 2001 From: aquanull Date: Wed, 4 Apr 2018 21:13:42 +0800 Subject: [PATCH] Adds new command to toggle movie Recording/Playing directly. Adds new command to truncate movie in Read+Write mode. Adds new command to insert/delete 1 frame in Read+Write mode. --- src/driver.h | 3 +- src/drivers/win/res.rc | 111 ++++++++++++++++++++---- src/drivers/win/resource.h | 8 ++ src/drivers/win/window.cpp | 83 +++++++++++++++--- src/fceu.cpp | 4 + src/input.cpp | 4 + src/input.h | 5 ++ src/movie.cpp | 172 +++++++++++++++++++++++++++++++++++-- src/movie.h | 4 + 9 files changed, 359 insertions(+), 35 deletions(-) diff --git a/src/driver.h b/src/driver.h index 7d228e0b..f221b9bb 100644 --- a/src/driver.h +++ b/src/driver.h @@ -337,7 +337,8 @@ enum EFCEUI FCEUI_STOPMOVIE, FCEUI_RECORDMOVIE, FCEUI_PLAYMOVIE, FCEUI_OPENGAME, FCEUI_CLOSEGAME, FCEUI_TASEDITOR, - FCEUI_RESET, FCEUI_POWER, FCEUI_PLAYFROMBEGINNING, FCEUI_EJECT_DISK, FCEUI_SWITCH_DISK, FCEUI_INSERT_COIN + FCEUI_RESET, FCEUI_POWER, FCEUI_PLAYFROMBEGINNING, FCEUI_EJECT_DISK, FCEUI_SWITCH_DISK, FCEUI_INSERT_COIN, + FCEUI_TOGGLERECORDINGMOVIE, FCEUI_TRUNCATEMOVIE, FCEUI_INSERT1FRAME, FCEUI_DELETE1FRAME }; //checks whether an EFCEUI is valid right now diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index b536c7cf..95b39718 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -7,7 +7,8 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxres.h" +#include "afxres.h" + ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -1854,6 +1855,14 @@ BEGIN MENUITEM "&Play Movie...", MENU_REPLAY_MOVIE MENUITEM "&Stop Movie", MENU_STOP_MOVIE MENUITEM "Play from &Beginning", ID_FILE_PLAYMOVIEFROMBEGINNING + MENUITEM "&Toggle Recording/Playing", ID_FILE_TOGGLE_RECORDING_MOVIE + POPUP "&Modify" + BEGIN + MENUITEM "&Insert 1 Frame", ID_FILE_INSERT_1_FRAME + MENUITEM "&Delete 1 Frame", ID_FILE_DELETE_1_FRAME + MENUITEM SEPARATOR + MENUITEM "&Truncate at Current Frame", ID_FILE_TRUNCATE_MOVIE + END MENUITEM SEPARATOR MENUITEM "&Read-only", ID_FILE_MOVIE_TOGGLEREAD END @@ -2225,17 +2234,12 @@ END FCEUCONTEXTMENUS MENU BEGIN - POPUP "Game+Movie+readonly" + POPUP "NoGame" BEGIN - MENUITEM "Toggle to read+write", FCEUX_CONTEXT_READONLYTOGGLE - MENUITEM "Play Movie from Beginning", FCEU_CONTEXT_PLAYMOVIEFROMBEGINNING - MENUITEM "Stop Movie Replay", FCEU_CONTEXT_STOPMOVIE - MENUITEM "View comments and subtitles", FCEUX_CONTEXT_VIEWCOMMENTSSUBTITLES + MENUITEM "Open ROM", FCEU_CONTEXT_OPENROM + MENUITEM "Last ROM used", FCEUX_CONTEXT_RECENTROM1 MENUITEM SEPARATOR - MENUITEM "Undo savestate", FCEUX_CONTEXT_UNDOSAVESTATE - MENUITEM "Rewind to last auto-save", FCEUX_CONTEXT_REWINDTOLASTAUTO - MENUITEM SEPARATOR - MENUITEM "Help....", FCEU_CONTEXT_MOVIEHELP + MENUITEM "Help...", FCEU_CONTEXT_FCEUHELP MENUITEM SEPARATOR MENUITEM "Use Config > Gui to get zapper right click", FCEUX_CONTEXT_GUICONFIG END @@ -2254,16 +2258,81 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Use Config > Gui to get zapper right click", FCEUX_CONTEXT_GUICONFIG END - POPUP "NoGame" + POPUP "Game+Movie+Playing+readonly" BEGIN - MENUITEM "Open ROM", FCEU_CONTEXT_OPENROM - MENUITEM "Last ROM used", FCEUX_CONTEXT_RECENTROM1 + MENUITEM "Toggle to read+write", FCEUX_CONTEXT_READONLYTOGGLE + MENUITEM "Play Movie from Beginning", FCEU_CONTEXT_PLAYMOVIEFROMBEGINNING + MENUITEM "Stop Movie Replay", FCEU_CONTEXT_STOPMOVIE + MENUITEM "View comments and subtitles", FCEUX_CONTEXT_VIEWCOMMENTSSUBTITLES MENUITEM SEPARATOR - MENUITEM "Help...", FCEU_CONTEXT_FCEUHELP + MENUITEM "Toggle to Recording", FCEUX_CONTEXT_TOGGLE_RECORDING + POPUP "Modify Movie" + BEGIN + MENUITEM "Insert 1 Frame", FCEUX_CONTEXT_INSERT_1_FRAME + MENUITEM "Delete 1 Frame", FCEUX_CONTEXT_DELETE_1_FRAME + MENUITEM SEPARATOR + MENUITEM "Truncate at Current Frame", FCEUX_CONTEXT_TRUNCATE_MOVIE + END + MENUITEM SEPARATOR + MENUITEM "Undo savestate", FCEUX_CONTEXT_UNDOSAVESTATE + MENUITEM "Rewind to last auto-save", FCEUX_CONTEXT_REWINDTOLASTAUTO + MENUITEM SEPARATOR + MENUITEM "Help....", FCEU_CONTEXT_MOVIEHELP MENUITEM SEPARATOR MENUITEM "Use Config > Gui to get zapper right click", FCEUX_CONTEXT_GUICONFIG END - POPUP "Game+Movie+readwrite" + POPUP "Game+Movie+Playing+readwrite" + BEGIN + MENUITEM "Toggle to Read-only", FCEUX_CONTEXT_READONLYTOGGLE + MENUITEM "Play Movie From Beginning", FCEU_CONTEXT_PLAYMOVIEFROMBEGINNING + MENUITEM "Stop Movie Replay", FCEU_CONTEXT_STOPMOVIE + MENUITEM "View comments and subtitles", FCEUX_CONTEXT_VIEWCOMMENTSSUBTITLES + MENUITEM "Make backup", FCEUX_CONTEXT_MAKEBACKUP + MENUITEM "Save Movie As...", FCEUX_CONTEXT_SAVEMOVIEAS + MENUITEM SEPARATOR + MENUITEM "Toggle to Recording", FCEUX_CONTEXT_TOGGLE_RECORDING + POPUP "Modify Movie" + BEGIN + MENUITEM "Insert 1 Frame", FCEUX_CONTEXT_INSERT_1_FRAME + MENUITEM "Delete 1 Frame", FCEUX_CONTEXT_DELETE_1_FRAME + MENUITEM SEPARATOR + MENUITEM "Truncate at Current Frame", FCEUX_CONTEXT_TRUNCATE_MOVIE + END + MENUITEM SEPARATOR + MENUITEM "Undo savestate", FCEUX_CONTEXT_UNDOSAVESTATE + MENUITEM "Undo loadstate", FCEUX_CONTEXT_UNDOLOADSTATE + MENUITEM "Rewind to last auto-save", FCEUX_CONTEXT_REWINDTOLASTAUTO + MENUITEM SEPARATOR + MENUITEM "&Mode: Full state-movie loads", ID_CONTEXT_FULLSAVESTATES + MENUITEM SEPARATOR + MENUITEM "Help...", FCEU_CONTEXT_MOVIEHELP + MENUITEM SEPARATOR + MENUITEM "Use Config > Gui to get zapper right click", FCEUX_CONTEXT_GUICONFIG + END + POPUP "Game+Movie+Recording+readonly" + BEGIN + MENUITEM "Toggle to read+write", FCEUX_CONTEXT_READONLYTOGGLE + MENUITEM "Play Movie from Beginning", FCEU_CONTEXT_PLAYMOVIEFROMBEGINNING + MENUITEM "Stop Movie Recording", FCEU_CONTEXT_STOPMOVIE + MENUITEM "View comments and subtitles", FCEUX_CONTEXT_VIEWCOMMENTSSUBTITLES + MENUITEM SEPARATOR + MENUITEM "Toggle to Playing", FCEUX_CONTEXT_TOGGLE_RECORDING + POPUP "Modify Movie" + BEGIN + MENUITEM "Insert 1 Frame", FCEUX_CONTEXT_INSERT_1_FRAME + MENUITEM "Delete 1 Frame", FCEUX_CONTEXT_DELETE_1_FRAME + MENUITEM SEPARATOR + MENUITEM "Truncate at Current Frame", FCEUX_CONTEXT_TRUNCATE_MOVIE + END + MENUITEM SEPARATOR + MENUITEM "Undo savestate", FCEUX_CONTEXT_UNDOSAVESTATE + MENUITEM "Rewind to last auto-save", FCEUX_CONTEXT_REWINDTOLASTAUTO + MENUITEM SEPARATOR + MENUITEM "Help....", FCEU_CONTEXT_MOVIEHELP + MENUITEM SEPARATOR + MENUITEM "Use Config > Gui to get zapper right click", FCEUX_CONTEXT_GUICONFIG + END + POPUP "Game+Movie+Recording+readwrite" BEGIN MENUITEM "Toggle to Read-only", FCEUX_CONTEXT_READONLYTOGGLE MENUITEM "Play Movie From Beginning", FCEU_CONTEXT_PLAYMOVIEFROMBEGINNING @@ -2272,6 +2341,15 @@ BEGIN MENUITEM "Make backup", FCEUX_CONTEXT_MAKEBACKUP MENUITEM "Save Movie As...", FCEUX_CONTEXT_SAVEMOVIEAS MENUITEM SEPARATOR + MENUITEM "Toggle to Playing", FCEUX_CONTEXT_TOGGLE_RECORDING + POPUP "Modify Movie" + BEGIN + MENUITEM "Insert 1 Frame", FCEUX_CONTEXT_INSERT_1_FRAME + MENUITEM "Delete 1 Frame", FCEUX_CONTEXT_DELETE_1_FRAME + MENUITEM SEPARATOR + MENUITEM "Truncate at Current Frame", FCEUX_CONTEXT_TRUNCATE_MOVIE + END + MENUITEM SEPARATOR MENUITEM "Undo savestate", FCEUX_CONTEXT_UNDOSAVESTATE MENUITEM "Undo loadstate", FCEUX_CONTEXT_UNDOLOADSTATE MENUITEM "Rewind to last auto-save", FCEUX_CONTEXT_REWINDTOLASTAUTO @@ -2599,7 +2677,8 @@ IDB_BRANCH_SPRITESHEET BITMAP "res\\branch_spritesheet.bmp" // // Generated from the TEXTINCLUDE 3 resource. // - + + ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED diff --git a/src/drivers/win/resource.h b/src/drivers/win/resource.h index 0ad99e52..9a3f71ef 100644 --- a/src/drivers/win/resource.h +++ b/src/drivers/win/resource.h @@ -923,6 +923,12 @@ #define ID_FILE_CLOSE40218 40218 #define MENU_MV_FILE_GOTO_ADDRESS 40219 #define MENU_BASIC_BOT2 40220 +#define ID_FILE_TRUNCATE_MOVIE 40221 +#define FCEUX_CONTEXT_TRUNCATE_MOVIE 40222 +#define ID_FILE_INSERT_1_FRAME 40223 +#define FCEUX_CONTEXT_INSERT_1_FRAME 40224 +#define ID_FILE_DELETE_1_FRAME 40225 +#define FCEUX_CONTEXT_DELETE_1_FRAME 40226 #define ID_FILE_OPENLUAWINDOW 40229 #define ID_FILE_CLOSELUAWINDOWS 40230 #define ID_CONFIG_DISPLAY 40231 @@ -1053,6 +1059,8 @@ #define FCEUX_CONTEXT_LOADLASTMOVIE 40356 #define ID_GAME_SAVEMOVIEAS 40357 #define FCEUX_CONTEXT_SAVEMOVIEAS 40358 +#define ID_FILE_TOGGLE_RECORDING_MOVIE 40359 +#define FCEUX_CONTEXT_TOGGLE_RECORDING 40360 #define ID_OPTIONS_BINDTOMAINWINDOW 40361 #define ID_CONFIG_PPU 40362 #define ID_PPU_NEWPPU 40363 diff --git a/src/drivers/win/window.cpp b/src/drivers/win/window.cpp index 266487de..df1adc80 100644 --- a/src/drivers/win/window.cpp +++ b/src/drivers/win/window.cpp @@ -494,6 +494,23 @@ void UpdateContextMenuItems(HMENU context, int whichContext) CheckMenuItem(context,ID_CONTEXT_FULLSAVESTATES,MF_BYCOMMAND | (fullSaveStateLoads ? MF_CHECKED : MF_UNCHECKED)); + if (FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_RECORD)) + EnableMenuItem(context, FCEUX_CONTEXT_TOGGLE_RECORDING, MF_BYCOMMAND | MF_ENABLED); + else + EnableMenuItem(context, FCEUX_CONTEXT_TOGGLE_RECORDING, MF_BYCOMMAND | MF_GRAYED); + + if (FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_RECORD)) + { + EnableMenuItem(context, FCEUX_CONTEXT_INSERT_1_FRAME, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(context, FCEUX_CONTEXT_DELETE_1_FRAME, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(context, FCEUX_CONTEXT_TRUNCATE_MOVIE, MF_BYCOMMAND | MF_ENABLED); + } else + { + EnableMenuItem(context, FCEUX_CONTEXT_INSERT_1_FRAME, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(context, FCEUX_CONTEXT_DELETE_1_FRAME, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(context, FCEUX_CONTEXT_TRUNCATE_MOVIE, MF_BYCOMMAND | MF_GRAYED); + } + //Undo Loadstate if (CheckBackupSaveStateExist() && (undoLS || redoLS)) EnableMenuItem(context,FCEUX_CONTEXT_UNDOLOADSTATE,MF_BYCOMMAND | MF_ENABLED); @@ -547,9 +564,8 @@ void UpdateContextMenuItems(HMENU context, int whichContext) InsertMenu(context,0xFFFF, MF_BYCOMMAND, FCEUX_CONTEXT_UNHIDEMENU, "Unhide Menu"); } - if ( ( (whichContext == 0) || (whichContext == 3) ) && (currMovieData.subtitles.size()) ){ + if (whichContext > 1 && currMovieData.subtitles.size() != 0){ // At position 3 is "View comments and subtitles". Insert this there: - InsertMenu(context,0x3, MF_BYPOSITION, FCEUX_CONTEXT_TOGGLESUBTITLES, movieSubtitles ? "Subtitle Display: On" : "Subtitle Display: Off"); // At position 4(+1) is after View comments and subtitles. Insert this there: InsertMenu(context,0x5, MF_BYPOSITION, FCEUX_CONTEXT_DUMPSUBTITLES, "Dump Subtitles to SRT file"); @@ -1374,18 +1390,25 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { if (rightClickEnabled) { - //If There is a movie loaded in read only - if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED) && movie_readonly) - whichContext = 0; // Game+Movie+readonly - //If there is a movie loaded in read+write - else if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED) && !movie_readonly) - whichContext = 3; // Game+Movie+readwrite + //If There is a movie loaded + if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_RECORD | MOVIEMODE_FINISHED)) + { + if (FCEUMOV_Mode(MOVIEMODE_RECORD)) + if (movie_readonly) + whichContext = 4; // Game+Movie+Recording+readonly + else + whichContext = 5; // Game+Movie+Recording+readwrite + else //if (FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_FINISHED)) + if (movie_readonly) + whichContext = 2; // Game+Movie+Playing+readonly + else + whichContext = 3; // Game+Movie+Playing+readwrite //If there is a ROM loaded but no movie - else if (GameInfo) + } else if (GameInfo) whichContext = 1; // Game+NoMovie //Else no ROM else - whichContext = 2; // NoGame + whichContext = 0; // NoGame hfceuxcontext = LoadMenu(fceu_hInstance,"FCEUCONTEXTMENUS"); hfceuxcontextsub = GetSubMenu(hfceuxcontext, whichContext); @@ -1765,6 +1788,22 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) case ID_FILE_MOVIE_TOGGLEREAD: FCEUI_MovieToggleReadOnly(); break; + case FCEUX_CONTEXT_TOGGLE_RECORDING: + case ID_FILE_TOGGLE_RECORDING_MOVIE: + FCEUI_MovieToggleRecording(); + break; + case FCEUX_CONTEXT_INSERT_1_FRAME: + case ID_FILE_INSERT_1_FRAME: + FCEUI_MovieInsertFrame(); + break; + case FCEUX_CONTEXT_DELETE_1_FRAME: + case ID_FILE_DELETE_1_FRAME: + FCEUI_MovieDeleteFrame(); + break; + case FCEUX_CONTEXT_TRUNCATE_MOVIE: + case ID_FILE_TRUNCATE_MOVIE: + FCEUI_MovieTruncate(); + break; //Record Avi/Wav submenu case MENU_RECORD_AVI: @@ -2455,6 +2494,10 @@ adelikat: Outsourced this to a remappable hotkey EnableMenuItem(fceumenu,MENU_MOVIE_RECENT,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_PLAYMOVIE)?MF_ENABLED:MF_GRAYED)); EnableMenuItem(fceumenu,MENU_STOP_MOVIE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_STOPMOVIE)?MF_ENABLED:MF_GRAYED)); EnableMenuItem(fceumenu,ID_FILE_PLAYMOVIEFROMBEGINNING,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_PLAYFROMBEGINNING)?MF_ENABLED:MF_GRAYED)); + EnableMenuItem(fceumenu, ID_FILE_TOGGLE_RECORDING_MOVIE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_TOGGLERECORDINGMOVIE)?MF_ENABLED:MF_GRAYED)); + EnableMenuItem(fceumenu, ID_FILE_INSERT_1_FRAME, MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_INSERT1FRAME) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(fceumenu, ID_FILE_DELETE_1_FRAME, MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_DELETE1FRAME) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(fceumenu, ID_FILE_TRUNCATE_MOVIE, MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_TRUNCATEMOVIE) ? MF_ENABLED : MF_GRAYED)); EnableMenuItem(fceumenu,MENU_SAVESTATE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_QUICKSAVE)?MF_ENABLED:MF_GRAYED)); EnableMenuItem(fceumenu,MENU_LOADSTATE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_QUICKLOAD)?MF_ENABLED:MF_GRAYED)); EnableMenuItem(fceumenu,MENU_SAVE_STATE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_SAVESTATE)?MF_ENABLED:MF_GRAYED)); @@ -2876,6 +2919,26 @@ void UpdateMenuHotkeys() combined = "Play from &Beginning\t" + combo; ChangeMenuItemText(ID_FILE_PLAYMOVIEFROMBEGINNING, combined); + //Toggle Movie Recording/Playing + combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_TOGGLE_RECORDING]); + combined = "&Toggle Recording/Playing\t" + combo; + ChangeMenuItemText(ID_FILE_TOGGLE_RECORDING_MOVIE, combined); + + //Insert 1 Frame + combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_INSERT_1_FRAME]); + combined = "&Insert 1 Frame\t" + combo; + ChangeMenuItemText(ID_FILE_INSERT_1_FRAME, combined); + + //Delete 1 Frame + combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_DELETE_1_FRAME]); + combined = "&Delete 1 Frame\t" + combo; + ChangeMenuItemText(ID_FILE_DELETE_1_FRAME, combined); + + //Truncate Movie at Current Frame + combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_TRUNCATE]); + combined = "&Truncate at &Current Frame\t" + combo; + ChangeMenuItemText(ID_FILE_TRUNCATE_MOVIE, combined); + //Read only combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_READONLY_TOGGLE]); combined = "&Read only\t" + combo; diff --git a/src/fceu.cpp b/src/fceu.cpp index 2ba2a748..062286a5 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -1199,11 +1199,15 @@ bool FCEU_IsValidUI(EFCEUI ui) { break; case FCEUI_STOPMOVIE: + case FCEUI_TOGGLERECORDINGMOVIE: return(FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_RECORD | MOVIEMODE_FINISHED)); case FCEUI_PLAYFROMBEGINNING: return(FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_RECORD | MOVIEMODE_TASEDITOR | MOVIEMODE_FINISHED)); + case FCEUI_TRUNCATEMOVIE: + return(FCEUMOV_Mode(MOVIEMODE_PLAY | MOVIEMODE_RECORD)); + case FCEUI_STOPAVI: return FCEUI_AviIsRecording(); diff --git a/src/input.cpp b/src/input.cpp index adb5b624..21e3e4b6 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -813,6 +813,10 @@ struct EMUCMDTABLE FCEUI_CommandTable[]= { EMUCMD_MOVIE_RECORD_TO, EMUCMDTYPE_MOVIE, FCEUD_MovieRecordTo, 0, 0, "Record Movie To...", 0 }, { EMUCMD_MOVIE_REPLAY_FROM, EMUCMDTYPE_MOVIE, FCEUD_MovieReplayFrom, 0, 0, "Play Movie From...", 0 }, { EMUCMD_MOVIE_PLAY_FROM_BEGINNING, EMUCMDTYPE_MOVIE, FCEUI_MoviePlayFromBeginning, 0, 0, "Play Movie From Beginning", EMUCMDFLAG_TASEDITOR }, + { EMUCMD_MOVIE_TOGGLE_RECORDING, EMUCMDTYPE_MOVIE, FCEUI_MovieToggleRecording, 0, 0, "Toggle Movie Recording/Playing", 0 }, + { EMUCMD_MOVIE_INSERT_1_FRAME, EMUCMDTYPE_MOVIE, FCEUI_MovieInsertFrame, 0, 0, "Insert 1 Frame To Movie", 0 }, + { EMUCMD_MOVIE_DELETE_1_FRAME, EMUCMDTYPE_MOVIE, FCEUI_MovieDeleteFrame, 0, 0, "Delete 1 Frame From Movie", 0 }, + { EMUCMD_MOVIE_TRUNCATE, EMUCMDTYPE_MOVIE, FCEUI_MovieTruncate, 0, 0, "Truncate Movie At Current Frame", 0 }, { EMUCMD_MOVIE_STOP, EMUCMDTYPE_MOVIE, FCEUI_StopMovie, 0, 0, "Stop Movie", 0 }, { EMUCMD_MOVIE_READONLY_TOGGLE, EMUCMDTYPE_MOVIE, FCEUI_MovieToggleReadOnly, 0, 0, "Toggle Read-Only", EMUCMDFLAG_TASEDITOR }, { EMUCMD_MOVIE_FRAME_DISPLAY_TOGGLE, EMUCMDTYPE_MOVIE, FCEUI_MovieToggleFrameDisplay, 0, 0, "Toggle Frame Display", EMUCMDFLAG_TASEDITOR }, diff --git a/src/input.h b/src/input.h index a4ba1624..f4e20674 100644 --- a/src/input.h +++ b/src/input.h @@ -248,6 +248,11 @@ enum EMUCMD EMUCMD_FPS_DISPLAY_TOGGLE, EMUCMD_TOOL_DEBUGSTEPINTO, + EMUCMD_MOVIE_TOGGLE_RECORDING, + EMUCMD_MOVIE_TRUNCATE, + EMUCMD_MOVIE_INSERT_1_FRAME, + EMUCMD_MOVIE_DELETE_1_FRAME, + EMUCMD_MAX }; diff --git a/src/movie.cpp b/src/movie.cpp index c14158fb..e06fcf9f 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -746,6 +746,22 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader) return true; } +static const char *GetMovieModeStr() +{ + if (movieMode == MOVIEMODE_INACTIVE) + return " (no movie)"; + else if (movieMode == MOVIEMODE_PLAY) + return " (playing)"; + else if (movieMode == MOVIEMODE_RECORD) + return " (recording)"; + else if (movieMode == MOVIEMODE_FINISHED) + return " (finished)"; + else if (movieMode == MOVIEMODE_TASEDITOR) + return " (taseditor)"; + else + return "."; +} + static EMUFILE *openRecordingMovie(const char* fname) { if (osRecordingMovie) @@ -1641,22 +1657,162 @@ void FCEUI_SetMovieToggleReadOnly(bool which) FCEU_DispMessage("Movie is Read+Write.",0); } } + +//auqnull: What's the point to toggle Read-Only without a movie loaded? void FCEUI_MovieToggleReadOnly() { char message[260]; - if(movie_readonly) - strcpy(message, "Movie is now Read+Write"); - else + movie_readonly = !movie_readonly; + if (movie_readonly) strcpy(message, "Movie is now Read-Only"); + else + strcpy(message, "Movie is now Read+Write"); + + strcat(message, GetMovieModeStr()); + FCEU_DispMessage(message, 0); +} + +void FCEUI_MovieToggleRecording() +{ + char message[260] = ""; if (movieMode == MOVIEMODE_INACTIVE) - strcat(message, " (no movie)"); - else if (movieMode == MOVIEMODE_FINISHED) - strcat(message, " (finished)"); + strcpy(message, "Cannot toggle Recording"); + else if (currFrameCounter > (int)currMovieData.records.size()) + strcpy(message, "Cannot toggle Recording in a future state"); + else if (movieMode == MOVIEMODE_PLAY || (movieMode == MOVIEMODE_FINISHED && currFrameCounter == (int)currMovieData.records.size())) + { + strcpy(message, "Movie is now Read+Write"); + movie_readonly = false; + FCEUMOV_IncrementRerecordCount(); + movieMode = MOVIEMODE_RECORD; + RedumpWholeMovieFile(true); + } else if (movieMode == MOVIEMODE_RECORD) + { + strcpy(message, "Movie is now Read-Only"); + movie_readonly = true; + movieMode = MOVIEMODE_PLAY; + RedumpWholeMovieFile(true); + if (currFrameCounter >= (int)currMovieData.records.size()) + { + extern int closeFinishedMovie; + if (closeFinishedMovie) + { + movieMode = MOVIEMODE_INACTIVE; + OnMovieClosed(); + } else + movieMode = MOVIEMODE_FINISHED; + } + } else + strcpy(message, "Nothing to do in this mode"); - FCEU_DispMessage(message,0); - movie_readonly = !movie_readonly; + strcat(message, GetMovieModeStr()); + + FCEU_DispMessage(message, 0); +} + +void FCEUI_MovieInsertFrame() +{ + char message[260] = ""; + + if (movieMode == MOVIEMODE_INACTIVE) + strcpy(message, "No movie to insert a frame."); + else if (movie_readonly) + strcpy(message, "Cannot modify movie in Read-Only mode."); + else if (currFrameCounter > (int)currMovieData.records.size()) + strcpy(message, "Cannot insert a frame here."); + else if (movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED) + { + strcpy(message, "1 frame inserted"); + strcat(message, GetMovieModeStr()); + std::vector::iterator iter = currMovieData.records.begin(); + currMovieData.records.insert(iter + currFrameCounter, MovieRecord()); + FCEUMOV_IncrementRerecordCount(); + RedumpWholeMovieFile(); + } else + { + strcpy(message, "Nothing to do in this mode"); + strcat(message, GetMovieModeStr()); + } + + FCEU_DispMessage(message, 0); +} + +void FCEUI_MovieDeleteFrame() +{ + char message[260] = ""; + + if (movieMode == MOVIEMODE_INACTIVE) + strcpy(message, "No movie to delete a frame."); + else if (movie_readonly) + strcpy(message, "Cannot modify movie in Read-Only mode."); + else if (currFrameCounter >= (int)currMovieData.records.size()) + strcpy(message, "Nothing to delete past movie end."); + else if (movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY) + { + strcpy(message, "1 frame deleted"); + std::vector::iterator iter = currMovieData.records.begin(); + currMovieData.records.erase(iter + currFrameCounter); + FCEUMOV_IncrementRerecordCount(); + RedumpWholeMovieFile(); + + if (movieMode != MOVIEMODE_RECORD && currFrameCounter >= (int)currMovieData.records.size()) + { + extern int closeFinishedMovie; + if (closeFinishedMovie) + { + movieMode = MOVIEMODE_INACTIVE; + OnMovieClosed(); + } else + movieMode = MOVIEMODE_FINISHED; + } + strcat(message, GetMovieModeStr()); + } else + { + strcpy(message, "Nothing to do in this mode"); + strcat(message, GetMovieModeStr()); + } + + FCEU_DispMessage(message, 0); +} + +void FCEUI_MovieTruncate() +{ + char message[260] = ""; + + if (movieMode == MOVIEMODE_INACTIVE) + strcpy(message, "No movie to truncate."); + else if (movie_readonly) + strcpy(message, "Cannot modify movie in Read-Only mode."); + else if (currFrameCounter >= (int)currMovieData.records.size()) + strcpy(message, "Nothing to truncate past movie end."); + else if (movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY) + { + strcpy(message, "Movie truncated"); + currMovieData.truncateAt(currFrameCounter); + FCEUMOV_IncrementRerecordCount(); + RedumpWholeMovieFile(); + + if (movieMode != MOVIEMODE_RECORD) + { + extern int closeFinishedMovie; + if (closeFinishedMovie) + { + movieMode = MOVIEMODE_INACTIVE; + OnMovieClosed(); + } + else + movieMode = MOVIEMODE_FINISHED; + } + strcat(message, GetMovieModeStr()); + } else + { + strcpy(message, "Nothing to do in this mode"); + strcat(message, GetMovieModeStr()); + } + + FCEU_DispMessage(message, 0); } void FCEUI_MoviePlayFromBeginning(void) diff --git a/src/movie.h b/src/movie.h index c1c41a17..f6229f6b 100644 --- a/src/movie.h +++ b/src/movie.h @@ -277,6 +277,10 @@ void FCEUI_StopMovie(void); bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount = false); //char* FCEUI_MovieGetCurrentName(int addSlotNumber); void FCEUI_MovieToggleReadOnly(void); +void FCEUI_MovieToggleRecording(); +void FCEUI_MovieInsertFrame(); +void FCEUI_MovieDeleteFrame(); +void FCEUI_MovieTruncate(); bool FCEUI_GetMovieToggleReadOnly(); void FCEUI_SetMovieToggleReadOnly(bool which); int FCEUI_GetMovieLength();