Merge pull request #23 from aquanull/master

A batch of various bugfixes and several feature enhancements mixed in.
This commit is contained in:
zeromus 2018-12-24 15:39:36 -05:00 committed by GitHub
commit a6219f5006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 870 additions and 320 deletions

View File

@ -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

View File

@ -61,6 +61,7 @@ extern bool disableMovieMessages;
extern bool replaceP2StartWithMicrophone;
extern bool SingleInstanceOnly;
extern bool Show_FPS;
extern int movieRecordMode;
extern bool oldInputDisplay;
extern bool fullSaveStateLoads;
extern int frameSkipAmt;
@ -470,6 +471,7 @@ static CFGSTRUCT fceuconfig[] =
AC(replaceP2StartWithMicrophone),
AC(SingleInstanceOnly),
AC(Show_FPS),
AC(movieRecordMode),
ENDCFGSTRUCT
};

View File

@ -1770,9 +1770,9 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
{
CheckDlgButton(hwndDlg, IDC_DEBUGGER_BREAK_ON_CYCLES, break_on_cycles ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_DEBUGGER_BREAK_ON_INSTRUCTIONS, break_on_instructions ? BST_CHECKED : BST_UNCHECKED);
sprintf(str, "%d", break_cycles_limit);
sprintf(str, "%u", (unsigned)break_cycles_limit);
SetDlgItemText(hwndDlg, IDC_DEBUGGER_CYCLES_EXCEED, str);
sprintf(str, "%d", break_instructions_limit);
sprintf(str, "%u", (unsigned)break_instructions_limit);
SetDlgItemText(hwndDlg, IDC_DEBUGGER_INSTRUCTIONS_EXCEED, str);
CheckDlgButton(hwndDlg, IDC_DEBUGGER_BREAK_ON_BAD_OP, FCEUI_Debugger().badopbreak ? BST_CHECKED : BST_UNCHECKED);
@ -2200,7 +2200,7 @@ BOOL CALLBACK DebuggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
//mbg merge 7/18/06 changed pausing check and set
if (FCEUI_EmulationPaused()) {
UpdateRegs(hwndDlg);
FCEUI_ToggleEmulationPause();
FCEUI_SetEmulationPaused(0);
//DebuggerWasUpdated = false done in above function;
}
break;

View File

@ -429,7 +429,9 @@ Name* parse(char* lines, const char* filename)
}
} else
{
sscanf(cur->offset, "%*[$]%4X", &(cur->offsetNumeric));
unsigned int tempOffset;
sscanf(cur->offset, "%*[$]%4X", &(tempOffset));
cur->offsetNumeric = (uint16)tempOffset;
// Add the node to the list of address nodes
if (prev)
{

View File

@ -245,9 +245,6 @@ int DTestButton(ButtConfig *bc)
void UpdateGamepad(bool snes)
{
if(FCEUMOV_Mode(MOVIEMODE_PLAY))
return;
int JS=0;
if(FCEUMOV_Mode(MOVIEMODE_RECORD))
AutoFire();
@ -422,10 +419,13 @@ void FCEUD_UpdateInput()
bool joy=false;
bool mouse=false;
bool mouse_relative=false;
EMOVIEMODE FCEUMOVState = FCEUMOV_Mode();
UpdateRawInputAndHotkeys();
//aquanull: if we are ok with getting real input even when emulation is paused, why should we bother skipping it when playing a movie?
bool skipRealInput = (FCEUMOV_Mode() == MOVIEMODE_PLAY && currFrameCounter < (int)currMovieData.records.size());
UpdateRawInputAndHotkeys();
if (!skipRealInput) //FatRatKnight: Moved this if out of the function, a more concise fix may be desired.
{
for(int x=0;x<2;x++)
switch(InputType[x])
@ -469,11 +469,8 @@ void FCEUD_UpdateInput()
if(joy)
UpdateGamepad(false);
if (FCEUMOVState != MOVIEMODE_PLAY) //FatRatKnight: Moved this if out of the function, a more concise fix may be desired.
{
if (mouse) GetMouseData(MouseData);
if (mouse_relative) GetMouseRelative(MouseRelative);
}
if (mouse) GetMouseData(MouseData);
if (mouse_relative) GetMouseRelative(MouseRelative);
}
}

View File

@ -2242,7 +2242,7 @@ BOOL CALLBACK MemFindCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
break;
case WM_CLOSE:
case WM_QUIT:
GetDlgItemText(hwndDlg,IDC_MEMVIEWFIND_WHAT,FindTextBox,59);
GetDlgItemText(hwndDlg,IDC_MEMVIEWFIND_WHAT,FindTextBox,60);
DestroyWindow(hwndDlg);
hMemFind = 0;
hwndDlg = 0;
@ -2302,7 +2302,7 @@ void FindNext(){
unsigned char data[60];
int datasize = 0, i, j, inputc = -1, found;
if(hMemFind) GetDlgItemText(hMemFind,IDC_MEMVIEWFIND_WHAT,str,59);
if(hMemFind) GetDlgItemText(hMemFind,IDC_MEMVIEWFIND_WHAT,str,60);
else strcpy(str,FindTextBox);
for(i = 0;str[i] != 0;i++){

View File

@ -72,12 +72,12 @@ extern void RemoveRecentItem(unsigned int which, char**bufferArray, const unsign
//Ram change monitor globals-----------------------------------
bool RamChangeInitialize = false; //Set true during memw WM_INIT
const int MAX_RAMMONITOR = 4; //Maximum number of Ram values that can be monitored
char editboxnow[MAX_RAMMONITOR][5]; //current address put into editbox 00
char editboxlast[MAX_RAMMONITOR][5]; //last address put into editbox (1 frame ago)
char editboxnow[MAX_RAMMONITOR][8]; //current address put into editbox 00
char editboxlast[MAX_RAMMONITOR][8]; //last address put into editbox (1 frame ago)
int editlast[MAX_RAMMONITOR]; //last address value (1 frame ago)
int editnow[MAX_RAMMONITOR]; //current address value
unsigned int editcount[MAX_RAMMONITOR]; //Current counter value
char editchangem[MAX_RAMMONITOR][5]; //counter converted to string
char editchangem[MAX_RAMMONITOR][12]; //counter converted to string
//-------------------------------------------------
@ -286,15 +286,15 @@ void UpdateMemWatch()
//Display blue if address is frozen
if (FrozenAddressCount && FrozenAddresses.size())
{
for (unsigned int x = 0; x < FrozenAddressCount; x++)
{
if (mwrec.addr == FrozenAddresses[x])
for (unsigned int x = 0; x < FrozenAddressCount; x++)
{
//SetTextColor(hdc,RGB(0,0,255));
SetTextColor(hdc,GetSysColor(COLOR_HIGHLIGHT));
if (mwrec.addr == FrozenAddresses[x])
{
//SetTextColor(hdc,RGB(0,0,255));
SetTextColor(hdc,GetSysColor(COLOR_HIGHLIGHT));
}
}
}
}
char* text;
if(mwrec.valid && GameInfo)
@ -336,7 +336,6 @@ void UpdateMemWatch()
TextOut(hdc,0,0,text,strlen(text));
SetTextColor(hdc,RGB(0,0,0));
}
}
}
@ -388,14 +387,14 @@ bool iftextchanged()
int i,j;
for(i=0;i<NUMWATCHES;i++)
{
for(j=0;j<LABELLENGTH;j++)
for(j=0;j<ADDRESSLENGTH;j++)
{
if(addresses[i][j] != NULL || labels [i][j] != NULL)
if(addresses[i][j] != '\0' || labels [i][j] != '\0')
return true;
}
for(;j<LABELLENGTH;j++)
{
if(labels[i][j] != NULL)
if(labels[i][j] != '\0')
return true;
}
}
@ -445,16 +444,16 @@ static void SaveMemWatch()
for(i=0;i<NUMWATCHES;i++)
{
//Use dummy strings to fill empty slots
if(labels[i][0] == 0)
{
labels[i][0] = '|';
labels[i][1] = 0;
}
if(addresses[i][0] == 0)
{
addresses[i][0] = '|';
addresses[i][1] = 0;
}
if(labels[i][0] == 0)
{
labels[i][0] = '|';
labels[i][1] = 0;
}
//spaces can be a problem for scanf so get rid of them
TakeOutSpaces(i);
fprintf(fp, "%s %s\n", addresses[i], labels[i]);
@ -476,16 +475,16 @@ static void QuickSaveMemWatch() //Save rather than Save as
for(int i=0;i<NUMWATCHES;i++)
{
//Use dummy strings to fill empty slots
if(labels[i][0] == 0)
{
labels[i][0] = '|';
labels[i][1] = 0;
}
if(addresses[i][0] == 0)
{
addresses[i][0] = '|';
addresses[i][1] = 0;
}
if(labels[i][0] == 0)
{
labels[i][0] = '|';
labels[i][1] = 0;
}
//spaces can be a problem for scanf so get rid of them
TakeOutSpaces(i);
fprintf(fp, "%s %s\n", addresses[i], labels[i]);
@ -572,7 +571,7 @@ static void LoadMemWatch()
}
fclose(fp);
}
fileChanged = false;
fileChanged = false;
}
//Loads a recent file given the recent files array number(0-4)
@ -592,33 +591,33 @@ void OpenMemwatchRecentFile(int memwRFileNumber)
MemwAddRecentFile(x);
int i,j;
for(i=0;i<NUMWATCHES;i++)
{
fscanf(fp, "%s ", watchfcontents); //Reads contents of newly opened file
for(j = 0; j < ADDRESSLENGTH; j++)
addresses[i][j] = watchfcontents[j];
fscanf(fp, "%s\n", watchfcontents);
for(j = 0; j < LABELLENGTH; j++)
labels[i][j] = watchfcontents[j];
//Replace dummy strings with empty strings
if(addresses[i][0] == '|')
{
fscanf(fp, "%s ", watchfcontents); //Reads contents of newly opened file
for(j = 0; j < ADDRESSLENGTH; j++)
addresses[i][j] = watchfcontents[j];
fscanf(fp, "%s\n", watchfcontents);
for(j = 0; j < LABELLENGTH; j++)
labels[i][j] = watchfcontents[j];
addresses[i][0] = 0;
}
if(labels[i][0] == '|')
{
labels[i][0] = 0;
}
PutInSpaces(i);
//Replace dummy strings with empty strings
if(addresses[i][0] == '|')
{
addresses[i][0] = 0;
}
if(labels[i][0] == '|')
{
labels[i][0] = 0;
}
PutInSpaces(i);
int templl = LABELLENGTH - 1;
int tempal = ADDRESSLENGTH - 1;
addresses[i][tempal] = 0;
labels[i][templl] = 0; //just in case
int templl = LABELLENGTH - 1;
int tempal = ADDRESSLENGTH - 1;
addresses[i][tempal] = 0;
labels[i][templl] = 0; //just in case
SetDlgItemText(hwndMemWatch,MW_VAL (i),(LPTSTR) "---");
SetDlgItemText(hwndMemWatch,MW_ADDR(i),(LPTSTR) addresses[i]);
SetDlgItemText(hwndMemWatch,MW_NAME(i),(LPTSTR) labels[i]);
SetDlgItemText(hwndMemWatch,MW_VAL (i),(LPTSTR) "---");
SetDlgItemText(hwndMemWatch,MW_ADDR(i),(LPTSTR) addresses[i]);
SetDlgItemText(hwndMemWatch,MW_NAME(i),(LPTSTR) labels[i]);
}
fclose(fp); //Close the file
fileChanged = false; //Flag that the memwatch file has not been changed since last save
@ -958,11 +957,15 @@ void CreateMemWatch()
int i,j;
for(i=0;i<NUMWATCHES;i++)
{
for(j=0;j<LABELLENGTH;j++)
for(j=0;j<ADDRESSLENGTH;j++)
{
addresses[i][j] = 0;
labels[i][j] = 0;
}
for (;j<LABELLENGTH;j++)
{
labels[i][j] = 0;
}
}
}

View File

@ -146,23 +146,23 @@ void ResetMemoryRegions()
{
MemoryRegion& region = *iter;
region.virtualIndex = nextVirtualIndex;
nextVirtualIndex = region.virtualIndex + region.size;
nextVirtualIndex = region.virtualIndex + region.size + 4;
}
//assert(nextVirtualIndex <= MAX_RAM_SIZE);
if(nextVirtualIndex > MAX_RAM_SIZE)
{
s_prevValues = (unsigned char*)realloc(s_prevValues, sizeof(char)*(nextVirtualIndex+4));
memset(s_prevValues, 0, sizeof(char)*(nextVirtualIndex+4));
s_prevValues = (unsigned char*)realloc(s_prevValues, sizeof(unsigned char)*nextVirtualIndex);
memset(s_prevValues, 0, sizeof(unsigned char)*nextVirtualIndex);
s_curValues = (unsigned char*)realloc(s_curValues, sizeof(char)*(nextVirtualIndex+4));
memset(s_curValues, 0, sizeof(char)*(nextVirtualIndex+4));
s_curValues = (unsigned char*)realloc(s_curValues, sizeof(unsigned char)*nextVirtualIndex);
memset(s_curValues, 0, sizeof(unsigned char)*nextVirtualIndex);
s_numChanges = (unsigned short*)realloc(s_numChanges, sizeof(short)*(nextVirtualIndex+4));
memset(s_numChanges, 0, sizeof(short)*(nextVirtualIndex+4));
s_numChanges = (unsigned short*)realloc(s_numChanges, sizeof(unsigned short)*nextVirtualIndex);
memset(s_numChanges, 0, sizeof(unsigned short)*nextVirtualIndex);
s_itemIndexToRegionPointer = (MemoryRegion**)realloc(s_itemIndexToRegionPointer, sizeof(MemoryRegion*)*(nextVirtualIndex+4));
memset(s_itemIndexToRegionPointer, 0, sizeof(MemoryRegion*)*(nextVirtualIndex+4));
s_itemIndexToRegionPointer = (MemoryRegion**)realloc(s_itemIndexToRegionPointer, sizeof(MemoryRegion*)*nextVirtualIndex);
memset(s_itemIndexToRegionPointer, 0, sizeof(MemoryRegion*)*nextVirtualIndex);
MAX_RAM_SIZE = nextVirtualIndex;
}

View File

@ -470,7 +470,7 @@ void OpenRWRecentFile(int memwRFileNumber)
return;
}
int Change_File_L(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, HWND hwnd)
int Change_File_L(char *Dest, const char *Dir, const char *Titre, const char *Filter, const char *Ext, HWND hwnd)
{
OPENFILENAME ofn;
@ -501,7 +501,7 @@ int Change_File_L(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, H
return 0;
}
int Change_File_S(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, HWND hwnd)
int Change_File_S(char *Dest, const char *Dir, const char *Titre, const char *Filter, const char *Ext, HWND hwnd)
{
OPENFILENAME ofn;
@ -536,11 +536,12 @@ int Change_File_S(char *Dest, char *Dir, char *Titre, char *Filter, char *Ext, H
bool Save_Watches()
{
string initdir = FCEU_GetPath(FCEUMKF_MEMW);
const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/')));
strcpy(Str_Tmp,slash ? slash+1 : gamefilename);
char* dot = strrchr(Str_Tmp, '.');
if(dot) *dot = 0;
if(Change_File_S(Str_Tmp, applicationPath, "Save Watches", "Watchlist (*.wch)\0*.wch\0All Files (*.*)\0*.*\0\0", "wch", RamWatchHWnd))
if(Change_File_S(Str_Tmp, initdir.c_str(), "Save Watches", "Watchlist (*.wch)\0*.wch\0All Files (*.*)\0*.*\0\0", "wch", RamWatchHWnd))
{
FILE *WatchFile = fopen(Str_Tmp,"w+b");
fputc('\n',WatchFile);
@ -655,12 +656,13 @@ bool Load_Watches(bool clear, const char* filename)
bool Load_Watches(bool clear)
{
string initdir = FCEU_GetPath(FCEUMKF_MEMW);
const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/')));
strcpy(Str_Tmp,slash ? slash+1 : gamefilename);
char* dot = strrchr(Str_Tmp, '.');
if(dot) *dot = 0;
strcat(Str_Tmp,".wch");
if(Change_File_L(Str_Tmp, applicationPath, "Load Watches", "Watchlist (*.wch)\0*.wch\0All Files (*.*)\0*.*\0\0", "wch", RamWatchHWnd))
if(Change_File_L(Str_Tmp, initdir.c_str(), "Load Watches", "Watchlist (*.wch)\0*.wch\0All Files (*.*)\0*.*\0\0", "wch", RamWatchHWnd))
{
return Load_Watches(clear, Str_Tmp);
}

View File

@ -126,7 +126,10 @@ void UpdateReplayCommentsSubs(const char * fname) {
MOVIE_INFO info;
FCEUFILE *fp = FCEU_fopen(fname,0,"rb",0);
fp->stream = fp->stream->memwrap();
EMUFILE *tmp = fp->stream->memwrap();
if (tmp != fp->stream)
delete fp->stream;
fp->stream = tmp;
bool scanok = FCEUI_MovieGetInfo(fp, info, true);
delete fp;
@ -151,8 +154,11 @@ void UpdateReplayDialog(HWND hwndDlg)
{
MOVIE_INFO info;
FCEUFILE* fp = FCEU_fopen(fn,0,"rb",0);
fp->stream = fp->stream->memwrap();
FCEUFILE *fp = FCEU_fopen(fn,0,"rb",0);
EMUFILE *tmp = fp->stream->memwrap();
if (tmp != fp->stream)
delete fp->stream;
fp->stream = tmp;
bool isarchive = FCEU_isFileInArchive(fn);
bool ismovie = FCEUI_MovieGetInfo(fp, info, false);
delete fp;

View File

@ -7,7 +7,8 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@ -1854,7 +1855,23 @@ 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 "&Quickly 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
POPUP "Record &Mode"
BEGIN
MENUITEM "&Next Record Mode", ID_FILE_NEXTRECORDMODE
MENUITEM SEPARATOR
MENUITEM "&Truncate", ID_FILE_RECORDMODE_TRUNCATE
MENUITEM "&Overwrite[W]", ID_FILE_RECORDMODE_OVERWRITE
MENUITEM "&Insert[I]", ID_FILE_RECORDMODE_INSERT
END
MENUITEM "&Read-only", ID_FILE_MOVIE_TOGGLEREAD
END
POPUP "&AVI/Wav"
@ -2225,17 +2242,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 +2266,99 @@ 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
POPUP "Record Mode"
BEGIN
MENUITEM "&Truncate", FCEUX_CONTEXT_RECORDMODE_TRUNCATE
MENUITEM "&Overwrite[W]", FCEUX_CONTEXT_RECORDMODE_OVERWRITE
MENUITEM "&Insert[I]", FCEUX_CONTEXT_RECORDMODE_INSERT
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
POPUP "Record Mode"
BEGIN
MENUITEM "&Truncate", FCEUX_CONTEXT_RECORDMODE_TRUNCATE
MENUITEM "&Overwrite[W]", FCEUX_CONTEXT_RECORDMODE_OVERWRITE
MENUITEM "&Insert[I]", FCEUX_CONTEXT_RECORDMODE_INSERT
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
POPUP "Record Mode"
BEGIN
MENUITEM "&Truncate", FCEUX_CONTEXT_RECORDMODE_TRUNCATE
MENUITEM "&Overwrite[W]", FCEUX_CONTEXT_RECORDMODE_OVERWRITE
MENUITEM "&Insert[I]", FCEUX_CONTEXT_RECORDMODE_INSERT
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 +2367,21 @@ 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
POPUP "Record Mode"
BEGIN
MENUITEM "&Truncate", FCEUX_CONTEXT_RECORDMODE_TRUNCATE
MENUITEM "&Overwrite[W]", FCEUX_CONTEXT_RECORDMODE_OVERWRITE
MENUITEM "&Insert[I]", FCEUX_CONTEXT_RECORDMODE_INSERT
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 +2709,8 @@ IDB_BRANCH_SPRITESHEET BITMAP "res\\branch_spritesheet.bmp"
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -833,6 +833,9 @@
#define MENU_DEBUGGER 40080
#define MENU_MEMORY_WATCH 40081
#define MENU_RAMFILTER 40082
#define ID_FILE_RECENT 40100
#define MEMW_HELP_WCOMMANDS 40101
#define MEMW_OPTIONS_LOADLASTFILE 40102
#define MEMW_FILE_NEW 40103
#define MEMW_FILE_OPEN 40104
#define MEMW_FILE_SAVE 40105
@ -840,13 +843,20 @@
#define MEMW_FILE_RECENT 40107
#define MEMW_FILE_CLOSE 40108
#define MEMW_OPTIONS_LOADSTART 40109
#define MEMW_HELP_WCOMMANDS 40113
#define MEMW_OPTIONS_LOADLASTFILE 40114
#define ID_FILE_RECENT 40117
#define ID_FILE_RECORDMODE_TRUNCATE 40110
#define ID_FILE_RECORDMODE_OVERWRITE 40111
#define ID_FILE_RECORDMODE_INSERT 40112
#define ID_FILE_RECORDMODE_XOR 40113
#define FCEUX_CONTEXT_RECORDMODE_TRUNCATE 40115
#define FCEUX_CONTEXT_RECORDMODE_OVERWRITE 40116
#define FCEUX_CONTEXT_RECORDMODE_INSERT 40117
#define FCEUX_CONTEXT_RECORDMODE_XOR 40118
#define MENU_RECORD_WAV 40120
#define MENU_STOP_WAV 40121
#define MENU_TASEDIT 40124
#define MENU_PAUSEAFTERPLAYBACK 40126
#define ID_FILE_NEXTRECORDMODE 40127
#define ID_FILE_PREVRECORDMODE 40128
#define ACCEL_CTRL_O 40130
#define ACCEL_CTRL_E 40131
#define ACCEL_CTRL_W 40132
@ -923,6 +933,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 +1069,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

View File

@ -122,6 +122,7 @@ extern BOOL CALLBACK ReplayMetadataDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wP
extern bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists
extern bool oldInputDisplay;
extern int RAMInitOption;
extern int movieRecordMode;
//AutoFire-----------------------------------------------
void ShowNetplayConsole(void); //mbg merge 7/17/06 YECH had to add
@ -417,6 +418,9 @@ void UpdateCheckedMenuItems()
CheckMenuItem(fceumenu, polo2[x], *polo[x] ? MF_CHECKED : MF_UNCHECKED);
}
//File Menu
CheckMenuItem(fceumenu, ID_FILE_RECORDMODE_TRUNCATE, movieRecordMode == MOVIE_RECORD_MODE_TRUNCATE ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(fceumenu, ID_FILE_RECORDMODE_OVERWRITE, movieRecordMode == MOVIE_RECORD_MODE_OVERWRITE ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(fceumenu, ID_FILE_RECORDMODE_INSERT, movieRecordMode == MOVIE_RECORD_MODE_INSERT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(fceumenu, ID_FILE_MOVIE_TOGGLEREAD, movie_readonly ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(fceumenu, ID_FILE_OPENLUAWINDOW, LuaConsoleHWnd ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(fceumenu, ID_AVI_ENABLEHUDRECORDING, FCEUI_AviEnableHUDrecording() ? MF_CHECKED : MF_UNCHECKED);
@ -494,6 +498,26 @@ 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);
}
CheckMenuItem(context, FCEUX_CONTEXT_RECORDMODE_TRUNCATE, movieRecordMode == MOVIE_RECORD_MODE_TRUNCATE ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(context, FCEUX_CONTEXT_RECORDMODE_OVERWRITE, movieRecordMode == MOVIE_RECORD_MODE_OVERWRITE ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(context, FCEUX_CONTEXT_RECORDMODE_INSERT, movieRecordMode == MOVIE_RECORD_MODE_INSERT ? MF_CHECKED : MF_UNCHECKED);
//Undo Loadstate
if (CheckBackupSaveStateExist() && (undoLS || redoLS))
EnableMenuItem(context,FCEUX_CONTEXT_UNDOLOADSTATE,MF_BYCOMMAND | MF_ENABLED);
@ -547,9 +571,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 +1397,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);
@ -1443,7 +1473,9 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
goto proco;
case WM_SIZE:
if (!fullscreen && !changerecursive && !windowedfailed)
if (wParam == SIZE_MINIMIZED)
nofocus = 1;
else if (!fullscreen && !changerecursive && !windowedfailed)
{
switch(wParam)
{
@ -1687,9 +1719,12 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
// A menu item for the recent movie files menu was clicked.
if(wParam >= MOVIE_FIRST_RECENT_FILE && wParam < MOVIE_FIRST_RECENT_FILE + MAX_NUMBER_OF_MOVIE_RECENT_FILES)
{
// aquanull: FCEUI_LoadMovie() calls AddRecentMovieFile(), which may change the orders of recent movies.
// For FCEUX_LoadMovieExtras() to receive the correct filename, fname has to be unaffected.
char*& fname = recent_movie[wParam - MOVIE_FIRST_RECENT_FILE];
if(fname)
{
string movie_fname = fname;
if (!FCEUI_LoadMovie(fname, 1, false))
{
int result = MessageBox(hWnd,"Remove from list?", "Could Not Open Recent File", MB_YESNO);
@ -1699,7 +1734,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
UpdateMovieRMenu(recentmoviemenu, recent_movie, MENU_MOVIE_RECENT, MOVIE_FIRST_RECENT_FILE);
}
} else {
FCEUX_LoadMovieExtras(fname);
FCEUX_LoadMovieExtras(movie_fname.c_str());
}
}
}
@ -1760,6 +1795,40 @@ 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;
case ID_FILE_NEXTRECORDMODE:
FCEUI_MovieNextRecordMode();
break;
case ID_FILE_PREVRECORDMODE:
FCEUI_MoviePrevRecordMode();
break;
case FCEUX_CONTEXT_RECORDMODE_TRUNCATE:
case ID_FILE_RECORDMODE_TRUNCATE:
FCEUI_MovieRecordModeTruncate();
break;
case FCEUX_CONTEXT_RECORDMODE_OVERWRITE:
case ID_FILE_RECORDMODE_OVERWRITE:
FCEUI_MovieRecordModeOverwrite();
break;
case FCEUX_CONTEXT_RECORDMODE_INSERT:
case ID_FILE_RECORDMODE_INSERT:
FCEUI_MovieRecordModeInsert();
break;
//Record Avi/Wav submenu
case MENU_RECORD_AVI:
@ -2420,6 +2489,7 @@ adelikat: Outsourced this to a remappable hotkey
DoFCEUExit();
break;
case WM_SETFOCUS:
nofocus = 0;
if (wasPausedByCheats)
{
EmulationPaused = 0;
@ -2449,6 +2519,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));
@ -2870,11 +2944,56 @@ 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;
ChangeMenuItemText(ID_FILE_MOVIE_TOGGLEREAD, combined);
//Next Record Mode
combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_NEXT_RECORD_MODE]);
combined = "&Next Record Mode\t" + combo;
ChangeMenuItemText(ID_FILE_NEXTRECORDMODE, combined);
//Prev Record Mode
combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_PREV_RECORD_MODE]);
combined = "&Prev Record Mode\t" + combo;
ChangeMenuItemText(ID_FILE_PREVRECORDMODE, combined);
//Record Mode Truncate
combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_RECORD_MODE_TRUNCATE]);
combined = "&Truncate\t" + combo;
ChangeMenuItemText(ID_FILE_RECORDMODE_TRUNCATE, combined);
//Record Mode Overwrite
combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_RECORD_MODE_OVERWRITE]);
combined = "&Overwrite[W]\t" + combo;
ChangeMenuItemText(ID_FILE_RECORDMODE_OVERWRITE, combined);
//Record Mode Insert
combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_RECORD_MODE_INSERT]);
combined = "&Insert[I]\t" + combo;
ChangeMenuItemText(ID_FILE_RECORDMODE_INSERT, combined);
//Screenshot
combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SCREENSHOT]);
combined = "&Screenshot\t" + combo;

View File

@ -86,6 +86,7 @@ void EMUFILE_FILE::truncate(s32 length)
#else
ftruncate(fileno(fp),length);
#endif
// this is probably wrong if mode is "wb"
fclose(fp);
fp = NULL;
open(fname.c_str(),mode);

View File

@ -112,6 +112,7 @@ bool movieSubtitles = true; //Toggle for displaying movie subtitles
bool DebuggerWasUpdated = false; //To prevent the debugger from updating things without being updated.
bool AutoResumePlay = false;
char romNameWhenClosingEmulator[2048] = {0};
bool togglePausedRequested = false; //Flaged true to pause at frame boundary
FCEUGI::FCEUGI()
: filename(0),
@ -656,6 +657,14 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
JustFrameAdvanced = false;
//do pausing at frame boundary to avoid inconsistency
if (togglePausedRequested)
{
togglePausedRequested = false;
if (!frameAdvanceRequested)
EmulationPaused ^= EMULATIONPAUSED_PAUSED;
}
if (frameAdvanceRequested)
{
if (frameAdvance_Delay_count == 0 || frameAdvance_Delay_count >= frameAdvance_Delay)
@ -722,6 +731,8 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION);
#endif
FCEU_PutImage();
#ifdef WIN32
//These Windows only dialogs need to be updated only once per frame so they are included here
UpdateCheatList(); // CaH4e3: can't see why, this is only cause problems with selection - adelikat: selection is only a problem when not paused, it shoudl be paused to select, we want to see the values update
@ -1119,7 +1130,7 @@ void FCEUI_SetEmulationPaused(int val) {
void FCEUI_ToggleEmulationPause(void)
{
EmulationPaused = (EmulationPaused & EMULATIONPAUSED_PAUSED) ^ EMULATIONPAUSED_PAUSED;
togglePausedRequested = true;;
DebuggerWasUpdated = false;
}
@ -1199,11 +1210,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();

View File

@ -284,11 +284,16 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
{
//if the archive contained no files, try to open it the old fashioned way
EMUFILE_FILE* fp = FCEUD_UTF8_fstream(fileToOpen,mode);
if(!fp || (fp->get_fp() == NULL))
if(!fp)
return 0;
if (fp->get_fp() == NULL)
{
//fp is new'ed so it has to be deleted
delete fp;
return 0;
}
//try to read a zip file
{
fceufp = TryUnzip(fileToOpen);

View File

@ -813,9 +813,18 @@ 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 },
{ EMUCMD_MOVIE_NEXT_RECORD_MODE, EMUCMDTYPE_MOVIE, FCEUI_MovieNextRecordMode, 0, 0, "Next Record Mode", 0 },
{ EMUCMD_MOVIE_PREV_RECORD_MODE, EMUCMDTYPE_MOVIE, FCEUI_MoviePrevRecordMode, 0, 0, "Prev Record Mode", 0 },
{ EMUCMD_MOVIE_RECORD_MODE_TRUNCATE, EMUCMDTYPE_MOVIE, FCEUI_MovieRecordModeTruncate, 0, 0, "Record Mode Truncate", 0 },
{ EMUCMD_MOVIE_RECORD_MODE_OVERWRITE, EMUCMDTYPE_MOVIE, FCEUI_MovieRecordModeOverwrite, 0, 0, "Record Mode Overwrite", 0 },
{ EMUCMD_MOVIE_RECORD_MODE_INSERT, EMUCMDTYPE_MOVIE, FCEUI_MovieRecordModeInsert, 0, 0, "Record Mode Insert", 0 },
{ EMUCMD_MOVIE_FRAME_DISPLAY_TOGGLE, EMUCMDTYPE_MOVIE, FCEUI_MovieToggleFrameDisplay, 0, 0, "Toggle Frame Display", EMUCMDFLAG_TASEDITOR },
{ EMUCMD_MOVIE_INPUT_DISPLAY_TOGGLE, EMUCMDTYPE_MISC, FCEUI_ToggleInputDisplay, 0, 0, "Toggle Input Display", EMUCMDFLAG_TASEDITOR },
{ EMUCMD_MOVIE_ICON_DISPLAY_TOGGLE, EMUCMDTYPE_MISC, FCEUD_ToggleStatusIcon, 0, 0, "Toggle Status Icon", EMUCMDFLAG_TASEDITOR },

View File

@ -248,6 +248,17 @@ 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_MOVIE_NEXT_RECORD_MODE,
EMUCMD_MOVIE_PREV_RECORD_MODE,
EMUCMD_MOVIE_RECORD_MODE_TRUNCATE,
EMUCMD_MOVIE_RECORD_MODE_OVERWRITE,
EMUCMD_MOVIE_RECORD_MODE_INSERT,
EMUCMD_MAX
};

View File

@ -6178,7 +6178,7 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) {
//if (wasPaused) FCEUI_ToggleEmulationPause();
// And run it right now. :)
//FCEU_LuaFrameBoundary();
FCEU_LuaFrameBoundary();
// Set up our protection hook to be executed once every 10,000 bytecode instructions.
//lua_sethook(thread, FCEU_LuaHookFunction, LUA_MASKCOUNT, 10000);

View File

@ -98,6 +98,7 @@ int input_display = 0;
int frame_display = 0;
int rerecord_display = 0;
bool fullSaveStateLoads = false; //Option for loading a savestates full contents in read+write mode instead of up to the frame count in the savestate (useful as a recovery option)
int movieRecordMode = 0; //Option for various movie recording modes such as TRUNCATE (normal), OVERWRITE etc.
SFORMAT FCEUMOV_STATEINFO[]={
{ &currFrameCounter, 4|FCEUSTATE_RLSB, "FCNT"},
@ -478,7 +479,7 @@ void MovieData::installValue(std::string& key, std::string& val)
}
}
int MovieData::dump(EMUFILE *os, bool binary)
int MovieData::dump(EMUFILE *os, bool binary, bool seekToCurrFramePos)
{
int start = os->ftell();
os->fprintf("version %d\n", version);
@ -516,19 +517,30 @@ int MovieData::dump(EMUFILE *os, bool binary)
if (this->loadFrameCount >= 0)
os->fprintf("length %d\n" , this->loadFrameCount);
int currFramePos = -1;
if(binary)
{
//put one | to start the binary dump
os->fputc('|');
for(int i=0;i<(int)records.size();i++)
for (int i = 0; i < (int)records.size(); i++)
{
if (seekToCurrFramePos && currFrameCounter == i)
currFramePos = os->ftell();
records[i].dumpBinary(this, os, i);
}
} else
{
for(int i=0;i<(int)records.size();i++)
for (int i = 0; i < (int)records.size(); i++)
{
if (seekToCurrFramePos && currFrameCounter == i)
currFramePos = os->ftell();
records[i].dump(this, os, i);
}
}
int end = os->ftell();
if (currFramePos >= 0)
os->fseek(currFramePos, SEEK_SET);
return end-start;
}
@ -735,53 +747,120 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
return true;
}
/// Stop movie playback.
static void StopPlayback()
static const char *GetMovieModeStr()
{
FCEU_DispMessageOnMovie("Movie playback stopped.");
movieMode = MOVIEMODE_INACTIVE;
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 ".";
}
// Stop movie playback without closing the movie.
static void FinishPlayback()
static const char *GetMovieReadOnlyStr()
{
extern int closeFinishedMovie;
if (closeFinishedMovie)
StopPlayback();
if (movieMode == MOVIEMODE_RECORD)
return movie_readonly ? " R-O" : "";
else
return movie_readonly ? "" : " R+W";
}
static const char *GetMovieRecordModeStr()
{
switch (movieRecordMode)
{
FCEU_DispMessage("Movie finished playing.",0);
movieMode = MOVIEMODE_FINISHED;
case MOVIE_RECORD_MODE_OVERWRITE:
return " [W]";
case MOVIE_RECORD_MODE_INSERT:
return " [I]";
default:
return "";
}
}
static EMUFILE *openRecordingMovie(const char* fname)
{
if (osRecordingMovie)
delete osRecordingMovie;
osRecordingMovie = FCEUD_UTF8_fstream(fname, "wb");
if (!osRecordingMovie || osRecordingMovie->fail()) {
FCEU_PrintError("Error opening movie output file: %s", fname);
return NULL;
}
strcpy(curMovieFilename, fname);
return osRecordingMovie;
}
static void closeRecordingMovie()
{
if(osRecordingMovie)
if (osRecordingMovie)
{
delete osRecordingMovie;
osRecordingMovie = 0;
}
}
// Callers shall set the approriate movieMode before calling this
static void RedumpWholeMovieFile(bool justToggledRecording = false)
{
bool recording = (movieMode == MOVIEMODE_RECORD);
assert((NULL != osRecordingMovie) == (recording != justToggledRecording) && "osRecordingMovie should be consistent with movie mode!");
if (NULL == openRecordingMovie(curMovieFilename))
return;
currMovieData.dump(osRecordingMovie, false/*currMovieData.binaryFlag*/, recording);
if (recording)
osRecordingMovie->fflush();
else
closeRecordingMovie();
}
/// Stop movie playback.
static void StopPlayback()
{
assert(movieMode != MOVIEMODE_RECORD && NULL == osRecordingMovie);
movieMode = MOVIEMODE_INACTIVE;
FCEU_DispMessageOnMovie("Movie playback stopped.");
}
// Stop movie playback without closing the movie.
static void FinishPlayback()
{
assert(movieMode != MOVIEMODE_RECORD);
extern int closeFinishedMovie;
if (closeFinishedMovie)
StopPlayback();
else
{
movieMode = MOVIEMODE_FINISHED;
FCEU_DispMessage("Movie finished playing.",0);
}
}
/// Stop movie recording
static void StopRecording()
{
FCEU_DispMessage("Movie recording stopped.",0);
movieMode = MOVIEMODE_INACTIVE;
assert(movieMode == MOVIEMODE_RECORD);
closeRecordingMovie();
movieMode = MOVIEMODE_INACTIVE;
RedumpWholeMovieFile(true);
FCEU_DispMessage("Movie recording stopped.",0);
}
void FCEUI_StopMovie()
static void OnMovieClosed()
{
if(suppressMovieStop)
return;
if(movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED)
StopPlayback();
else if(movieMode == MOVIEMODE_RECORD)
StopRecording();
assert(movieMode == MOVIEMODE_INACTIVE);
curMovieFilename[0] = 0; //No longer a current movie filename
freshMovie = false; //No longer a fresh movie loaded
@ -794,6 +873,19 @@ void FCEUI_StopMovie()
bool bogorf;
void FCEUI_StopMovie()
{
if (suppressMovieStop)
return;
if (movieMode == MOVIEMODE_PLAY || movieMode == MOVIEMODE_FINISHED)
StopPlayback();
else if (movieMode == MOVIEMODE_RECORD)
StopRecording();
OnMovieClosed();
}
void poweron(bool shouldDisableBatteryLoading)
{
//// make a for-movie-recording power-on clear the game's save data, too
@ -961,6 +1053,7 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
freshMovie = true; //Movie has been loaded, so it must be unaltered
if (bindSavestate) AutoSS = false; //If bind savestate to movie is true, then their isn't a valid auto-save to load, so flag it
cur_input_display = 0; //clear previous input display
//fully reload the game to reinitialize everything before playing any movie
poweron(true);
@ -1021,21 +1114,6 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
return true;
}
static void openRecordingMovie(const char* fname)
{
osRecordingMovie = FCEUD_UTF8_fstream(fname, "wb");
if(!osRecordingMovie || osRecordingMovie->fail()) {
FCEU_PrintError("Error opening movie output file: %s",fname);
return;
}
strcpy(curMovieFilename, fname);
#ifdef WIN32
//Add to the recent movie menu
AddRecentMovieFile(fname);
#endif
}
//begin recording a new movie
//TODO - BUG - the record-from-another-savestate doesnt work.
@ -1048,11 +1126,14 @@ void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author)
FCEUI_StopMovie();
openRecordingMovie(fname);
if(!osRecordingMovie || osRecordingMovie->fail())
if (NULL == openRecordingMovie(fname))
return;
#ifdef WIN32
//Add to the recent movie menu
AddRecentMovieFile(fname);
#endif
currFrameCounter = 0;
LagCounterReset();
FCEUMOV_CreateCleanMovie();
@ -1183,14 +1264,29 @@ void FCEUMOV_AddInputState()
mr.commands = _currCommand;
_currCommand = 0;
//Adelikat: in normal mode, this is done at the time of loading a savestate in read+write mode
//aquanull: now it supports other recording modes that don't necessarily truncate further frame data
//If the user chooses it can be delayed to here
if (fullSaveStateLoads && (currFrameCounter < (int)currMovieData.records.size()))
currMovieData.truncateAt(currFrameCounter);
if (currFrameCounter < (int)currMovieData.records.size())
switch (movieRecordMode)
{
case MOVIE_RECORD_MODE_OVERWRITE:
currMovieData.records[currFrameCounter].Clone(mr);
break;
case MOVIE_RECORD_MODE_INSERT:
//FIXME: this could be very insufficient
currMovieData.records.insert(currMovieData.records.begin() + currFrameCounter, mr);
break;
//case MOVIE_RECORD_MODE_TRUNCATE:
default:
//Adelikat: in normal mode, this is done at the time of loading a savestate in read+write mode
currMovieData.truncateAt(currFrameCounter);
currMovieData.records.push_back(mr);
break;
}
else
currMovieData.records.push_back(mr);
mr.dump(&currMovieData, osRecordingMovie,currMovieData.records.size()); // to disk
currMovieData.records.push_back(mr);
mr.dump(&currMovieData, osRecordingMovie, currFrameCounter); // to disk
}
currFrameCounter++;
@ -1224,33 +1320,42 @@ void FCEUMOV_AddCommand(int cmd)
void FCEU_DrawMovies(uint8 *XBuf)
{
if(frame_display)
// not the best place, but just working
assert((NULL != osRecordingMovie) == (movieMode == MOVIEMODE_RECORD));
if (frame_display)
{
char counterbuf[32] = {0};
int color = 0x20;
if(movieMode == MOVIEMODE_PLAY)
sprintf(counterbuf,"%d/%d",currFrameCounter,(int)currMovieData.records.size());
else if(movieMode == MOVIEMODE_RECORD)
sprintf(counterbuf,"%d",currFrameCounter);
else if (movieMode == MOVIEMODE_FINISHED)
if (movieMode == MOVIEMODE_PLAY)
{
sprintf(counterbuf,"%d/%d (finished)",currFrameCounter,(int)currMovieData.records.size());
sprintf(counterbuf, "%d/%d%s%s", currFrameCounter, (int)currMovieData.records.size(), GetMovieRecordModeStr(), GetMovieReadOnlyStr());
} else if (movieMode == MOVIEMODE_RECORD)
{
if (movieRecordMode == MOVIE_RECORD_MODE_TRUNCATE)
sprintf(counterbuf, "%d%s%s (record)", currFrameCounter, GetMovieRecordModeStr(), GetMovieReadOnlyStr()); // nearly classic
else
sprintf(counterbuf, "%d/%d%s%s (record)", currFrameCounter, (int)currMovieData.records.size(), GetMovieRecordModeStr(), GetMovieReadOnlyStr());
} else if (movieMode == MOVIEMODE_FINISHED)
{
sprintf(counterbuf,"%d/%d%s%s (finished)",currFrameCounter,(int)currMovieData.records.size(), GetMovieRecordModeStr(), GetMovieReadOnlyStr());
color = 0x17; //Show red to get attention
} else if(movieMode == MOVIEMODE_TASEDITOR)
} else if (movieMode == MOVIEMODE_TASEDITOR)
{
sprintf(counterbuf,"%d",currFrameCounter);
} else
sprintf(counterbuf,"%d (no movie)",currFrameCounter);
if(counterbuf[0])
if (counterbuf[0])
DrawTextTrans(ClipSidesOffset+XBuf+FCEU_TextScanlineOffsetFromBottom(30)+1, 256, (uint8*)counterbuf, color+0x80);
}
if(rerecord_display && movieMode != MOVIEMODE_INACTIVE)
if (rerecord_display && movieMode != MOVIEMODE_INACTIVE)
{
char counterbuf[32] = {0};
sprintf(counterbuf,"%d",currMovieData.rerecordCount);
sprintf(counterbuf, "%d", currMovieData.rerecordCount);
if(counterbuf[0])
if (counterbuf[0])
DrawTextTrans(ClipSidesOffset+XBuf+FCEU_TextScanlineOffsetFromBottom(50)+1, 256, (uint8*)counterbuf, 0x28+0x80);
}
}
@ -1420,10 +1525,15 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size)
#endif
}
closeRecordingMovie();
if (movie_readonly)
{
if (movieMode == MOVIEMODE_RECORD)
{
movieMode = MOVIEMODE_PLAY;
RedumpWholeMovieFile(true);
closeRecordingMovie();
}
// currFrameCounter at this point represents the savestate framecount
int frame_of_mismatch = CheckTimelines(tempMovieData, currMovieData);
if (frame_of_mismatch >= 0)
@ -1436,50 +1546,42 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size)
} else
FCEU_PrintError("Error: Savestate not in the same timeline as movie!\nFrame %d branches from current timeline", frame_of_mismatch);
return false;
} else if (movieMode == MOVIEMODE_FINISHED
&& currFrameCounter > (int)currMovieData.records.size()
&& currMovieData.records.size() == tempMovieData.records.size())
} else if ((int)tempMovieData.records.size() < currFrameCounter)
{
// special case (in MOVIEMODE_FINISHED mode)
// allow loading post-movie savestates that were made after finishing current movie
} else if (currFrameCounter > (int)currMovieData.records.size())
{
// this is future event state, don't allow it
//TODO: turn frame counter to red to get attention
if (!backupSavestates) //If backups are disabled we can just resume normally since we can't restore so stop movie and inform user
// this is post-movie savestate and must be checked further
if (tempMovieData.records.size() < currMovieData.records.size())
{
FCEU_PrintError("Error: Savestate is from a frame (%d) after the final frame in the movie (%d). This is not permitted.\nUnable to restore backup, movie playback stopped.", currFrameCounter, currMovieData.records.size()-1);
FCEUI_StopMovie();
} else
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 (currFrameCounter > (int)tempMovieData.records.size())
{
// this is post-movie savestate, don't allow it
//TODO: turn frame counter to red to get attention
if (!backupSavestates) //If backups are disabled we can just resume normally since we can't restore so stop movie and inform user
{
FCEU_PrintError("Error: Savestate is from a frame (%d) after the final frame in the savestated movie (%d). This is not permitted.\nUnable to restore backup, movie playback stopped.", currFrameCounter, tempMovieData.records.size()-1);
FCEUI_StopMovie();
} else
FCEU_PrintError("Savestate is from a frame (%d) after the final frame in the savestated movie (%d). This is not permitted.", currFrameCounter, tempMovieData.records.size()-1);
return false;
} else
{
// Finally, this is a savestate file for this movie
movieMode = MOVIEMODE_PLAY;
// this savestate doesn't contain enough input to be checked
//TODO: turn frame counter to red to get attention
if (!backupSavestates) //If backups are disabled we can just resume normally since we can't restore so stop movie and inform user
{
FCEU_PrintError("Error: Savestate taken from a frame (%d) after the final frame in the savestated movie (%d) cannot be verified against current movie (%d). This is not permitted.\nUnable to restore backup, movie playback stopped.", currFrameCounter, tempMovieData.records.size() - 1, currMovieData.records.size() - 1);
FCEUI_StopMovie();
} else
FCEU_PrintError("Savestate taken from a frame (%d) after the final frame in the savestated movie (%d) cannot be verified against current movie (%d). This is not permitted.", currFrameCounter, tempMovieData.records.size() - 1, currMovieData.records.size() - 1);
return false;
}
}
// Finally, this is a savestate file for this movie
// We'll allow loading post-movie savestates that were made after finishing current movie
if (currFrameCounter < (int)currMovieData.records.size())
movieMode = MOVIEMODE_PLAY;
else
FinishPlayback();
} else
{
//Read+Write mode
closeRecordingMovie();
if (currFrameCounter > (int)tempMovieData.records.size())
{
//This is a post movie savestate, handle it differently
//Replace movie contents but then switch to movie finished mode
currMovieData = tempMovieData;
openRecordingMovie(curMovieFilename);
currMovieData.dump(osRecordingMovie, false/*currMovieData.binaryFlag*/);
movieMode = MOVIEMODE_PLAY;
FCEUMOV_IncrementRerecordCount();
RedumpWholeMovieFile();
FinishPlayback();
} else
{
@ -1489,11 +1591,9 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size)
tempMovieData.truncateAt(currFrameCounter);
currMovieData = tempMovieData;
FCEUMOV_IncrementRerecordCount();
openRecordingMovie(curMovieFilename);
currMovieData.dump(osRecordingMovie, false/*currMovieData.binaryFlag*/);
movieMode = MOVIEMODE_RECORD;
FCEUMOV_IncrementRerecordCount();
RedumpWholeMovieFile(true);
}
}
}
@ -1601,22 +1701,192 @@ 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())
{
movie_readonly = !movie_readonly;
if (movie_readonly)
strcpy(message, "Movie is now Read-Only (finished)");
else
strcpy(message, "Movie is now Read+Write (finished)");
} 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<MovieRecord>::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<MovieRecord>::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_MovieNextRecordMode()
{
movieRecordMode = (movieRecordMode + 1) % MOVIE_RECORD_MODE_MAX;
}
void FCEUI_MoviePrevRecordMode()
{
movieRecordMode = (movieRecordMode + MOVIE_RECORD_MODE_MAX - 1) % MOVIE_RECORD_MODE_MAX;
}
void FCEUI_MovieRecordModeTruncate()
{
movieRecordMode = MOVIE_RECORD_MODE_TRUNCATE;
}
void FCEUI_MovieRecordModeOverwrite()
{
movieRecordMode = MOVIE_RECORD_MODE_OVERWRITE;
}
void FCEUI_MovieRecordModeInsert()
{
movieRecordMode = MOVIE_RECORD_MODE_INSERT;
}
void FCEUI_MoviePlayFromBeginning(void)
@ -1628,10 +1898,16 @@ void FCEUI_MoviePlayFromBeginning(void)
#endif
} else if (movieMode != MOVIEMODE_INACTIVE)
{
if (movieMode == MOVIEMODE_RECORD)
{
movieMode = MOVIEMODE_PLAY;
RedumpWholeMovieFile(true);
}
if (currMovieData.savestate.empty())
{
movie_readonly = true;
movieMode = MOVIEMODE_PLAY;
cur_input_display = 0; //clear previous input display
poweron(true);
currFrameCounter = 0;
FCEU_DispMessage("Movie is now Read-Only. Playing from beginning.",0);

View File

@ -65,6 +65,16 @@ enum EMOVIEMODE
MOVIEMODE_FINISHED = 16
};
enum EMOVIERECORDMODE
{
MOVIE_RECORD_MODE_TRUNCATE = 0,
MOVIE_RECORD_MODE_OVERWRITE = 1,
MOVIE_RECORD_MODE_INSERT = 2,
//MOVIE_RECORD_MODE_XOR = 3,
MOVIE_RECORD_MODE_MAX
};
enum EMOVIECMD
{
MOVIECMD_RESET = 1,
@ -234,7 +244,7 @@ public:
void truncateAt(int frame);
void installValue(std::string& key, std::string& val);
int dump(EMUFILE* os, bool binary);
int dump(EMUFILE* os, bool binary, bool seekToCurrFramePos = false);
void clearRecordRange(int start, int len);
void eraseRecords(int at, int frames = 1);
@ -267,6 +277,8 @@ extern bool freshMovie;
extern bool movie_readonly;
extern bool autoMovieBackup;
extern bool fullSaveStateLoads;
extern int movieRecordMode;
//--------------------------------------------------
void FCEUI_MakeBackupMovie(bool dispMessage);
void FCEUI_CreateMovieFile(std::string fn);
@ -277,6 +289,15 @@ 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();
void FCEUI_MovieNextRecordMode();
void FCEUI_MoviePrevRecordMode();
void FCEUI_MovieRecordModeTruncate();
void FCEUI_MovieRecordModeOverwrite();
void FCEUI_MovieRecordModeInsert();
bool FCEUI_GetMovieToggleReadOnly();
void FCEUI_SetMovieToggleReadOnly(bool which);
int FCEUI_GetMovieLength();

View File

@ -1862,7 +1862,6 @@ int FCEUPPU_Loop(int skip) {
} else
#endif
{
FCEU_PutImage();
return(1);
}
}
@ -2429,7 +2428,5 @@ int FCEUX_PPU_Loop(int skip) {
}
finish:
FCEU_PutImage();
return 0;
}

View File

@ -178,6 +178,31 @@ static void ReallySnap(void)
FCEU_DispMessage("Screen snapshot %d saved.",0,x-1);
}
static uint32 GetButtonColor(uint32 held, uint32 c, uint32 ci, int bit)
{
uint32 on = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0x90 : 0xA7; //Standard, or Gray depending on movie mode
uint32 oni = 0xA0; //Color for immediate keyboard buttons
uint32 blend = 0xB6; //Blend of immiate and last held buttons
uint32 ahold = 0x87; //Auto hold
uint32 off = 0xCF;
uint32 color;
uint8 mask = 1u << bit;
if (held & mask) { //If auto-hold
if (!(ci & mask))
color = ahold;
else
color = (c & mask) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c & mask)
color = (ci & mask) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else
color = (ci & mask) ? oni : off;
}
return color;
}
void FCEU_PutImage(void)
{
if(dosnapsave==2) //Save screenshot as, currently only flagged & run by the Win32 build. //TODO SDL: implement this?
@ -247,19 +272,10 @@ void FCEU_PutImage(void)
if(input_display)
{
extern uint32 JSAutoHeld;
uint32 held;
int controller, c, ci, color;
int i, j;
uint32 on = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0x90:0xA7; //Standard, or Gray depending on movie mode
uint32 oni = 0xA0; //Color for immediate keyboard buttons
uint32 blend = 0xB6; //Blend of immiate and last held buttons
uint32 ahold = 0x87; //Auto hold
uint32 off = 0xCF;
uint8 *t = XBuf+(FSettings.LastSLine-9)*256 + 20; //mbg merge 7/17/06 changed t to uint8*
if(input_display > 4) input_display = 4;
for(controller = 0; controller < input_display; controller++, t += 56)
for(int controller = 0; controller < input_display; controller++, t += 56)
{
for(i = 0; i < 34;i++)
for(j = 0; j <9 ; j++)
@ -267,33 +283,27 @@ void FCEU_PutImage(void)
for(i = 3; i < 6; i++)
for(j = 3; j< 6; j++)
t[i+j*256] = 0xCF;
c = cur_input_display >> (controller * 8);
uint32 held = 0;
uint32 c = cur_input_display >> (controller * 8);
uint32 ci = 0;
uint32 color;
#ifdef WIN32
// This doesn't work in anything except windows for now.
// It doesn't get set anywhere in other ports.
#ifdef WIN32
if (!oldInputDisplay) ci = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0:GetGamepadPressedImmediate() >> (controller * 8);
else ci = 0;
if (!oldInputDisplay)
ci = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0 : GetGamepadPressedImmediate() >> (controller * 8);
if (!oldInputDisplay && !FCEUMOV_Mode(MOVIEMODE_PLAY)) held = (JSAutoHeld >> (controller * 8));
else held = 0;
if (!oldInputDisplay && !FCEUMOV_Mode(MOVIEMODE_PLAY))
held = (JSAutoHeld >> (controller * 8));
#else
// Put other port info here
ci = 0;
held = 0;
#endif
//adelikat: I apologize to anyone who ever sifts through this color assignment
//A
if (held&1) { //If auto-hold
if (!(ci&1) ) color = ahold;
else
color = (c&1) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&1) color = (ci&1) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&1) ? oni : off;
}
color = GetButtonColor(held, c, ci, 0);
for(i=0; i < 4; i++)
{
for(j = 0; j < 4; j++)
@ -304,15 +314,7 @@ void FCEU_PutImage(void)
}
}
//B
if (held&2) { //If auto-hold
if (!(ci&2) ) color = ahold;
else
color = (c&2) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&2) color = (ci&2) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&2) ? oni : off;
}
color = GetButtonColor(held, c, ci, 1);
for(i=0; i < 4; i++)
{
for(j = 0; j < 4; j++)
@ -323,45 +325,21 @@ void FCEU_PutImage(void)
}
}
//Select
if (held&4) { //If auto-hold
if (!(ci&4) ) color = ahold;
else
color = (c&4) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&4) color = (ci&4) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&4) ? oni : off;
}
color = GetButtonColor(held, c, ci, 2);
for(i = 0; i < 4; i++)
{
t[11+5*256+i] = color;
t[11+6*256+i] = color;
}
//Start
if (held&8) { //If auto-hold
if (!(ci&8) ) color = ahold;
else
color = (c&8) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&8) color = (ci&8) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&8) ? oni : off;
}
color = GetButtonColor(held, c, ci, 3);
for(i = 0; i < 4; i++)
{
t[17+5*256+i] = color;
t[17+6*256+i] = color;
}
//Up
if (held&16) { //If auto-hold
if (!(ci&16) ) color = ahold;
else
color = (c&16) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&16) color = (ci&16) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&16) ? oni : off;
}
color = GetButtonColor(held, c, ci, 4);
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
@ -370,15 +348,7 @@ void FCEU_PutImage(void)
}
}
//Down
if (held&32) { //If auto-hold
if (!(ci&32) ) color = ahold;
else
color = (c&32) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&32) color = (ci&32) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&32) ? oni : off;
}
color = GetButtonColor(held, c, ci, 5);
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
@ -387,15 +357,7 @@ void FCEU_PutImage(void)
}
}
//Left
if (held&64) { //If auto-hold
if (!(ci&64) ) color = ahold;
else
color = (c&64) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&64) color = (ci&64) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&64) ? oni : off;
}
color = GetButtonColor(held, c, ci, 6);
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
@ -404,15 +366,7 @@ void FCEU_PutImage(void)
}
}
//Right
if (held&128) { //If auto-hold
if (!(ci&128) ) color = ahold;
else
color = (c&128) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed!
}
else {
if (c&128) color = (ci&128) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors
else color = (ci&128) ? oni : off;
}
color = GetButtonColor(held, c, ci, 7);
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)