Cheat console:

1. Added a global switch for all cheats, it is checked by default. Check or uncheck it can quickly tweak all cheats enabled or disabled. It's not game specific and effective to all games.
2. Added a checkmark to check behaviour of automatically load cheats.
3. Fixed a wierd bug in loading names of cheats from file.
iNES Header Editor:
4. Disable iNES header editor menu when currently loaded game is not in iNES format.
Others:
5. Some of the checkbox passed parameter MF_CHECKED, the right one is BST_CHECKED, though they have the same value.
6. Code/Data Logger is created by CreateDialog(), but destroyed by EndDialog()? A non-modal window should be destroy by DestroyWindow(), EndDialog() is for DialogBox(). It seems nobody noticed this bug for years.

Currently there are some opposite tweaks in the config file for the new feature in cheat console, for example the unchcecked state is 1 in config file, that's for backward compatibility.
The iNES header editor might not quite stable as newly baked from the oven, there might be some improvements to its code.
This commit is contained in:
owomomo 2019-06-12 22:16:01 +08:00
parent 5ef8394745
commit fb1d489cfa
21 changed files with 294 additions and 190 deletions

View File

@ -62,6 +62,8 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
CHEATF_SUBFAST SubCheats[256] = { 0 };
uint32 numsubcheats = 0;
int globalCheatDisabled = 0;
int disableAutoLSCheats = 0;
struct CHEATF *cheats = 0, *cheatsl = 0;
@ -104,11 +106,10 @@ void RebuildSubCheats(void)
SetReadHandler(SubCheats[x].addr, SubCheats[x].addr, SubCheats[x].PrevRead);
numsubcheats = 0;
while(c)
{
if(c->type == 1 && c->status)
if (!globalCheatDisabled)
while(c)
{
if(GetReadHandler(c->addr) != SubCheatsRead)
if(c->type == 1 && c->status && GetReadHandler(c->addr) != SubCheatsRead)
{
SubCheats[numsubcheats].PrevRead = GetReadHandler(c->addr);
SubCheats[numsubcheats].addr = c->addr;
@ -117,9 +118,9 @@ void RebuildSubCheats(void)
SetReadHandler(c->addr, c->addr, SubCheatsRead);
numsubcheats++;
}
c = c->next;
}
c = c->next;
}
FrozenAddressCount = numsubcheats; //Update the frozen address list
UpdateFrozenList();
@ -243,7 +244,6 @@ void FCEU_LoadGameCheats(FILE *override, int override_existing)
char *neo = &tbuf[4+2+2+1+1+1];
if(sscanf(tbuf, "%04x%*[:]%02x%*[:]%02x", &addr, &val, &compare) != 3)
continue;
char namebuf[128];
strcpy(namebuf, neo);
}
else
@ -277,6 +277,31 @@ void FCEU_LoadGameCheats(FILE *override, int override_existing)
fclose(fp);
}
void FCEU_SaveGameCheats(FILE* fp, int release)
{
struct CHEATF *next = cheats;
while (next)
{
if (next->type)
fputc('S', fp);
if (next->compare >= 0)
fputc('C', fp);
if (!next->status)
fputc(':', fp);
if (next->compare >= 0)
fprintf(fp, "%04x:%02x:%02x:%s\n", next->addr, next->val, next->compare, next->name);
else
fprintf(fp, "%04x:%02x:%s\n", next->addr, next->val, next->name);
if (release) free(next->name);
struct CHEATF *t = next;
next = next->next;
if (release) free(t);
}
}
void FCEU_FlushGameCheats(FILE *override, int nosave)
{
if(CheatComp)
@ -309,7 +334,6 @@ void FCEU_FlushGameCheats(FILE *override, int nosave)
if(cheats)
{
struct CHEATF *next=cheats;
FILE *fp;
if(override)
@ -319,28 +343,7 @@ void FCEU_FlushGameCheats(FILE *override, int nosave)
if(fp)
{
for(;;)
{
struct CHEATF *t;
if(next->type)
fputc('S',fp);
if(next->compare>=0)
fputc('C',fp);
if(!next->status)
fputc(':',fp);
if(next->compare>=0)
fprintf(fp,"%04x:%02x:%02x:%s\n",next->addr,next->val,next->compare,next->name);
else
fprintf(fp,"%04x:%02x:%s\n",next->addr,next->val,next->name);
free(next->name);
t=next;
next=next->next;
free(t);
if(!next) break;
}
FCEU_SaveGameCheats(fp, 1);
if(!override)
fclose(fp);
}
@ -642,6 +645,14 @@ int FCEUI_ToggleCheat(uint32 which)
return(-1);
}
int FCEUI_GlobalToggleCheat(int global_enabled)
{
int _numsubcheats = numsubcheats;
globalCheatDisabled = !global_enabled;
RebuildSubCheats();
return _numsubcheats != numsubcheats;
}
static int InitCheatComp(void)
{
uint32 x;

View File

@ -3,6 +3,8 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p);
void FCEU_LoadGameCheats(FILE *override, int override_existing = 1);
void FCEU_FlushGameCheats(FILE *override, int nosave);
void FCEU_SaveGameCheats(FILE *fp, int release = 0);
int FCEUI_GlobalToggleCheat(int global_enabled);
void FCEU_ApplyPeriodicCheats(void);
void FCEU_PowerCheats(void);
int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size);
@ -12,6 +14,8 @@ int FCEU_CheatGetByte(uint32 A);
void FCEU_CheatSetByte(uint32 A, uint8 V);
extern int savecheats;
extern int globalCheatDisabled;
extern int disableAutoLSCheats;
int FCEU_DisableAllCheats();

View File

@ -191,6 +191,8 @@ int FCEUI_DecodeGG(const char *str, int *a, int *v, int *c);
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type);
int FCEUI_DelCheat(uint32 which);
int FCEUI_ToggleCheat(uint32 which);
int FCEUI_GlobalToggleCheat(int global_enable);
void FCEU_SaveGameCheats(FILE *fp, int release = 0);
int32 FCEUI_CheatSearchGetCount(void);
void FCEUI_CheatSearchGetRange(uint32 first, uint32 last, int (*callb)(uint32 a, uint8 last, uint8 current));

View File

@ -135,7 +135,7 @@ BOOL CALLBACK CDLoggerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
FreeCDLog();
RenameCDLog("");
hCDLogger = 0;
EndDialog(hwndDlg, 0);
DestroyWindow(hwndDlg);
}
break;
case WM_COMMAND:

View File

@ -34,6 +34,8 @@ HWND hCheat = 0; //mbg merge 7/19/06 had to add
HMENU hCheatcontext = 0; //Handle to cheat context menu
bool pauseWhileActive = false; //For checkbox "Pause while active"
extern int globalCheatDisabled;
extern int disableAutoLSCheats;
extern bool wasPausedByCheats;
int CheatWindow;
@ -296,7 +298,9 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
if (ChtPosY == -32000) ChtPosY = 0;
SetWindowPos(hwndDlg, 0, ChtPosX, ChtPosY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
CheckDlgButton(hwndDlg, IDC_CHEAT_PAUSEWHENACTIVE, pauseWhileActive ? MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHEAT_PAUSEWHENACTIVE, pauseWhileActive ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_CHEAT_GLOBAL_SWITCH, globalCheatDisabled ? BST_UNCHECKED : BST_CHECKED);
CheckDlgButton(hwndDlg, IDC_CHEAT_AUTOLOADSAVE, disableAutoLSCheats == 2 ? BST_UNCHECKED : disableAutoLSCheats == 1 ? BST_INDETERMINATE : BST_CHECKED);
//setup font
hFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
@ -633,37 +637,10 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
}
case IDC_BTN_CHEAT_ADDFROMFILE:
{
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwndDlg;
ofn.hInstance = fceu_hInstance;
ofn.lpstrTitle = "Open cheats file";
const char filter[] = "Cheat files (*.cht)\0*.cht\0All Files (*.*)\0*.*\0\0";
ofn.lpstrFilter = filter;
char nameo[2048] = { 0 };
/*
I gave up setting the default filename for import cheat dialog, since the filename display contains a bug.
if (GameInfo)
char filename[2048];
if (ShowCheatFileBox(hwndDlg, filename, false))
{
char* filename;
if ((filename = strrchr(GameInfo->filename, '\\')) || (filename = strrchr(GameInfo->filename, '/')))
strcpy(nameo, filename + 1);
else
strcpy(nameo, GameInfo->filename);
strcpy(strrchr(nameo, '.'), ".cht");
}
*/
ofn.lpstrFile = nameo;
ofn.nMaxFile = 2048;
ofn.lpstrDefExt = "cht";
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST;
ofn.lpstrInitialDir = FCEU_GetPath(FCEUMKF_CHEAT).c_str();
if (GetOpenFileName(&ofn))
{
FILE* file = FCEUD_UTF8fopen(nameo, "rb");
FILE* file = FCEUD_UTF8fopen(filename, "rb");
if (file)
{
FCEU_LoadGameCheats(file, 0);
@ -675,42 +652,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
}
break;
case IDC_BTN_CHEAT_EXPORTTOFILE:
{
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance = fceu_hInstance;
ofn.lpstrTitle = "Save cheats file";
const char filter[] = "Cheat files (*.cht)\0*.cht\0All Files (*.*)\0*.*\0\0";
ofn.lpstrFilter = filter;
char nameo[2048] = { 0 };
if (GameInfo)
{
char* filename;
if ((filename = strrchr(GameInfo->filename, '\\')) || (filename = strrchr(GameInfo->filename, '/')))
strcpy(nameo, filename + 1);
else
strcpy(nameo, GameInfo->filename);
strcpy(strrchr(nameo, '.'), ".cht");
}
ofn.lpstrFile = nameo;
ofn.nMaxFile = 2048;
ofn.lpstrDefExt = "cht";
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST;
ofn.lpstrInitialDir = FCEU_GetPath(FCEUMKF_CHEAT).c_str();
if (GetSaveFileName(&ofn))
{
FILE* file = FCEUD_UTF8fopen(nameo, "wb");
if (file)
{
savecheats = 1;
FCEU_FlushGameCheats(file, 0);
fclose(file);
}
}
}
SaveCheatAs(hwndDlg);
break;
case IDC_BTN_CHEAT_RESET:
FCEUI_CheatSearchBegin();
@ -768,6 +710,27 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
ShowResults(hwndDlg);
}
break;
case IDC_CHEAT_GLOBAL_SWITCH:
if (FCEUI_GlobalToggleCheat(IsDlgButtonChecked(hwndDlg, IDC_CHEAT_GLOBAL_SWITCH)))
{
UpdateCheatRelatedWindow();
UpdateCheatListGroupBoxUI();
}
break;
case IDC_CHEAT_AUTOLOADSAVE:
switch (IsDlgButtonChecked(hwndDlg, IDC_CHEAT_AUTOLOADSAVE))
{
case BST_CHECKED: disableAutoLSCheats = 0; break;
case BST_INDETERMINATE: disableAutoLSCheats = 1; break;
case BST_UNCHECKED:
if(MessageBox(hwndDlg, "If this option is unchecked, you must manually save the cheats by yourself, or all the changed you made to the cheat list would be discarded silently without any asking once you close the game!\nDo you really want to do it in this way?", "Cheat warning", MB_YESNO | MB_ICONWARNING) == IDYES)
disableAutoLSCheats = 2;
else
{
disableAutoLSCheats = 0;
CheckDlgButton(hwndDlg, IDC_CHEAT_AUTOLOADSAVE, BST_INDETERMINATE);
}
}
}
break;
case EN_SETFOCUS:
@ -869,7 +832,6 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
if (!s)
{
FCEUI_SetCheat(tmpsel, name, -1, -1, -2, s ^= 1, 1);
UpdateCheatRelatedWindow();
UpdateCheatListGroupBoxUI();
}
@ -1320,4 +1282,89 @@ void UpdateCheatRelatedWindow()
SendDlgItemMessage(RamWatchHWnd, IDC_WATCHLIST, LVM_GETCOUNTPERPAGE, 0, 0) + 1);
}
}
bool ShowCheatFileBox(HWND hwnd, char* buf, bool save)
{
if (!buf)
return false;
char filename[2048] = { 0 };
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hInstance = fceu_hInstance;
ofn.hwndOwner = hwnd;
ofn.lpstrTitle = save ? "Save cheats file" : "Open cheats file";
ofn.lpstrFilter = "Cheat files (*.cht)\0*.cht\0All Files (*.*)\0*.*\0\0";
// I gave up setting the default filename for import cheat dialog, since the filename display contains a bug.
if (save)
{
if (GameInfo)
{
char* _filename;
if ((_filename = strrchr(GameInfo->filename, '\\')) || (_filename = strrchr(GameInfo->filename, '/')))
strcpy(filename, _filename + 1);
else
strcpy(filename, GameInfo->filename);
_filename = strrchr(filename, '.');
if (_filename)
strcpy(_filename, ".cht");
else
strcat(filename, ".cht");
}
}
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename);
ofn.lpstrDefExt = "cht";
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_FILEMUSTEXIST;
ofn.lpstrInitialDir = FCEU_GetPath(FCEUMKF_CHEAT).c_str();
if (save ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn))
{
strcpy(buf, filename);
return true;
}
return false;
}
void AskSaveCheat()
{
if (cheats)
{
HWND hwnd = hCheat ? hCheat : hAppWnd;
if (MessageBox(hwnd, "Save cheats?", "Cheat Console", MB_YESNO | MB_ICONASTERISK) == IDYES)
SaveCheatAs(hwnd, true);
}
}
void SaveCheatAs(HWND hwnd, bool flush)
{
if (cheats)
{
char filename[2048];
if (ShowCheatFileBox(hwnd, filename, true))
{
FILE* file = FCEUD_UTF8fopen(filename, "wb");
if (file)
{
if (flush)
{
savecheats = 1;
FCEU_FlushGameCheats(file, 0);
}
else
FCEU_SaveGameCheats(file);
fclose(file);
}
else
MessageBox(hwnd, "Error saving cheats!", "Cheat Console", MB_OK | MB_ICONERROR);
}
}
}

View File

@ -22,8 +22,12 @@ inline void GetCheatStr(char* buf, int a, int v, int c);
extern unsigned int FrozenAddressCount;
extern std::vector<uint16> FrozenAddresses;
//void ConfigAddCheat(HWND wnd); //bbit edited:commented out this line
extern struct CHEATF* cheats;
void DisableAllCheats();
bool ShowCheatFileBox(HWND hwnd, char* buf, bool save = false);
void AskSaveCheat();
void SaveCheatAs(HWND hwnd, bool flush = false);
void UpdateCheatRelatedWindow();

View File

@ -56,6 +56,8 @@ extern bool rightClickEnabled;
extern bool fullscreenByDoubleclick;
extern int CurrentState;
extern bool pauseWhileActive; //adelikat: Cheats dialog
extern int globalCheatDisabled;
extern int disableAutoLSCheats;
extern bool enableHUDrecording;
extern bool disableMovieMessages;
extern bool replaceP2StartWithMicrophone;
@ -466,6 +468,8 @@ static CFGSTRUCT fceuconfig[] =
AC(backupSavestates),
AC(compressSavestates),
AC(pauseWhileActive),
AC(disableAutoLSCheats),
AC(globalCheatDisabled),
AC(enableHUDrecording),
AC(disableMovieMessages),
AC(replaceP2StartWithMicrophone),

View File

@ -2475,11 +2475,11 @@ void UpdatePatcher(HWND hwndDlg){
/// Updates debugger controls that should be enabled/disabled if a game is loaded.
/// @param enable Flag that indicates whether the menus should be enabled (1) or disabled (0).
void updateGameDependentMenusDebugger(unsigned int enable) {
void updateGameDependentMenusDebugger() {
if (!hDebug)
return;
//EnableWindow(GetDlgItem(hDebug,DEBUGLOADDEB),(enable ? 0 : 1));
// EnableWindow(GetDlgItem(hDebug,DEBUGLOADDEB), GameInfo != 0 ? FALSE : TRUE);
}
void DoDebug(uint8 halt)
@ -2496,7 +2496,7 @@ void DoDebug(uint8 halt)
ShowWindow(hDebug, SW_SHOWNORMAL);
SetForegroundWindow(hDebug);
updateGameDependentMenusDebugger(GameInfo != 0);
updateGameDependentMenusDebugger();
if (GameInfo)
UpdateDebugger(true);

View File

@ -43,7 +43,7 @@ void Disassemble(HWND hWnd, int id, int scrollid, unsigned int addr);
void PrintOffsetToSeekAndBookmarkFields(int offset);
void LoadGameDebuggerData(HWND hwndDlg);
void updateGameDependentMenusDebugger(unsigned int enable);
void updateGameDependentMenusDebugger();
extern bool inDebugger;

View File

@ -139,7 +139,10 @@ bool LoadHeader(HWND parent, iNES_HEADER* header)
OPEN_FAILED,
INVALID_HEADER,
FDS_HEADER,
UNIF_HEADER
UNIF_HEADER,
NSF_HEADER//,
// NSFE_HEADER,
// NSF2_HEADER
};
FCEUFILE* fp = FCEU_fopen(LoadedRomFName, NULL, "rb", NULL);
@ -154,7 +157,13 @@ bool LoadHeader(HWND parent, iNES_HEADER* header)
error = errors::FDS_HEADER;
else if (!memcmp(header, "UNIF", 4))
error = errors::UNIF_HEADER;
else
else if (!memcmp(header, "NESM", 4))
error = errors::NSF_HEADER;
/* else if (!memcmp(header, "NSFE", 4))
error = errors::NSFE_HEADER;
else if (!memcmp(header, "NESM\2", 4))
error = errors::NSF2_HEADER;
*/ else
error = errors::INVALID_HEADER;
FCEU_fclose(fp);
}
@ -169,17 +178,23 @@ bool LoadHeader(HWND parent, iNES_HEADER* header)
{
char buf[1024];
sprintf(buf, "Error opening %s!", LoadedRomFName);
MessageBox(parent, buf, "iNES Header Editor", MB_ICONERROR | MB_OK);
MessageBox(parent, buf, "iNES Header Editor", MB_OK | MB_ICONERROR);
break;
}
case errors::INVALID_HEADER:
MessageBox(parent, "Invalid iNES header.", "iNES Header Editor", MB_ICONERROR | MB_OK);
MessageBox(parent, "Invalid iNES header.", "iNES Header Editor", MB_OK | MB_ICONERROR);
break;
case errors::FDS_HEADER:
MessageBox(parent, "Editing header of an FDS file is not supported.", "iNES Header Editor", MB_ICONERROR | MB_OK);
MessageBox(parent, "Editing header of an FDS file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR);
break;
case errors::UNIF_HEADER:
MessageBox(parent, "Editing header of a UNIF file is not supported.", "iNES Header Editor", MB_ICONERROR | MB_OK);
MessageBox(parent, "Editing header of a UNIF file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR);
break;
case errors::NSF_HEADER:
// case errors::NSF2_HEADER:
// case errors::NSFE_HEADER:
MessageBox(parent, "Editing header of an NSF file is not supported.", "iNES Header Editor", MB_OK | MB_ICONERROR);
break;
}
return false;
}
@ -505,7 +520,7 @@ LRESULT CALLBACK HeaderEditorProc(HWND hDlg, UINT uMsg, WPARAM wP, LPARAM lP)
if (WriteHeaderData(hDlg, &newHeader))
{
char path[4096] = { 0 };
if (ShowINESFileBox(hDlg, true, path))
if (ShowINESFileBox(hDlg, path, true))
SaveINESFile(hDlg, path, &newHeader);
}
}
@ -1493,7 +1508,7 @@ bool GetComboBoxListItemData(HWND hwnd, UINT id, int* value, char* buf, bool exa
}
// Warning: when in save mode, the content of buf might be overwritten by the save filename which user changed.
bool ShowINESFileBox(HWND parent, bool save, char* buf)
bool ShowINESFileBox(HWND parent, char* buf, bool save)
{
char *filename = NULL, *path = NULL;
bool success = true;
@ -1532,19 +1547,20 @@ bool ShowINESFileBox(HWND parent, bool save, char* buf)
if (success)
{
OPENFILENAME ofDlg;
memset(&ofDlg, 0, sizeof(OPENFILENAME));
ofDlg.lStructSize = sizeof(OPENFILENAME);
ofDlg.lpstrTitle = save ? "Save NES file" : "Open NES file";
ofDlg.lpstrFilter = "NES ROM file(*.nes)\0*.nes\0All files(*.*)\0*.*\0\0";
ofDlg.hInstance = fceu_hInstance;
ofDlg.hwndOwner = parent;
ofDlg.lpstrFile = filename;
ofDlg.nMaxFile = 2048;
ofDlg.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
ofDlg.lpstrInitialDir = path;
OPENFILENAME ofn;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrTitle = save ? "Save NES file" : "Open NES file";
ofn.lpstrFilter = "NES ROM file (*.nes)\0*.nes\0All files (*.*)\0*.*\0\0";
ofn.hInstance = fceu_hInstance;
ofn.hwndOwner = parent;
ofn.lpstrFile = filename;
ofn.nMaxFile = 2048;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
ofn.lpstrInitialDir = path;
ofn.lpstrDefExt = "nes";
if (save ? GetSaveFileName(&ofDlg) : GetOpenFileName(&ofDlg))
if (save ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn))
strcpy(buf, filename);
else
success = false;

View File

@ -5,7 +5,7 @@ extern HWND hHeadEditor;
struct iNES_HEADER;
HWND InitHeaderEditDialog(HWND hwnd, iNES_HEADER* header);
bool ShowINESFileBox(HWND parent, bool save = false, char* buf = NULL);
bool ShowINESFileBox(HWND parent, char* buf = NULL, bool save = false);
void ToggleINES20(HWND hwnd, bool ines20);
void ToggleExtendSystemList(HWND hwnd, bool enable);
void ToggleVSSystemGroup(HWND hwnd, bool enable);

View File

@ -470,7 +470,7 @@ void DoFCEUExit()
if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR) && !exitTASEditor())
return;
if (CloseMemoryWatch() && AskSave()) //If user was asked to save changes in the memory watch dialog or ram watch, and chose cancel, don't close FCEUX!
if (CloseMemoryWatch() && AskSaveRamWatch()) //If user was asked to save changes in the memory watch dialog or ram watch, and chose cancel, don't close FCEUX!
{
if(goptions & GOO_CONFIRMEXIT)
{

View File

@ -316,7 +316,7 @@ static int GetFileData(uint32 offset){
}
static int WriteFileData(uint32 addr,int data){
if (addr < 16) MessageBox(hMemView, "Use iNES Header Editor to edit the header.", "Sorry", MB_OK | MB_ICONASTERISK);
if (addr < 16) MessageBox(hMemView, "You can't edit ROM header here, however you can use iNES Header Editor to edit the header if it's an iNES format file.", "Sorry", MB_OK | MB_ICONERROR);
if((addr >= 16) && (addr < PRGsize[0]+16)) *(uint8 *)(GetNesPRGPointer(addr-16)) = data;
if((addr >= PRGsize[0]+16) && (addr < CHRsize[0]+PRGsize[0]+16)) *(uint8 *)(GetNesCHRPointer(addr-16-PRGsize[0])) = data;

View File

@ -234,7 +234,7 @@ void Update_RAM_Watch()
}
}
bool AskSave()
bool AskSaveRamWatch()
{
//This function asks to save changes if the watch file contents have changed
//returns false only if a save was attempted but failed or was cancelled
@ -677,7 +677,7 @@ bool Load_Watches(bool clear)
bool ResetWatches()
{
if(!AskSave())
if(!AskSaveRamWatch())
return false;
for (;WatchCount >= 0; WatchCount--)
{

View File

@ -6,7 +6,7 @@ extern bool AutoRWLoad;
extern bool RWSaveWindowPos;
#define MAX_RECENT_WATCHES 5
extern char rw_recent_files[MAX_RECENT_WATCHES][1024];
extern bool AskSave();
extern bool AskSaveRamWatch();
extern int ramw_x;
extern int ramw_y;
extern bool RWfileChanged;

View File

@ -1978,48 +1978,51 @@ BEGIN
LTEXT "New Selection Name:",-1,5,240,68,8
END
CHEATCONSOLE DIALOGEX 0, 0, 387, 218
CHEATCONSOLE DIALOGEX 0, 0, 387, 226
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Cheat Search"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
GROUPBOX "Active Cheats",IDC_GROUPBOX_CHEATLIST,5,2,169,209,WS_TABSTOP
GROUPBOX "Cheat Search",IDC_GROUPBOX_CHEATSEARCH,180,2,201,198,WS_TABSTOP
CONTROL "",IDC_LIST_CHEATS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,11,11,157,133
LTEXT "Name:",IDC_STATIC,12,149,22,10
EDITTEXT IDC_CHEAT_NAME,37,147,131,12,ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "Address:",IDC_CHEAT_ADDRESS_LABEL,12,163,30,8
EDITTEXT IDC_CHEAT_ADDR,44,161,25,12,ES_UPPERCASE | ES_WANTRETURN
LTEXT "Value:",IDC_CHEAT_VAL_LABEL,73,163,22,8
EDITTEXT IDC_CHEAT_VAL,97,161,16,12,ES_UPPERCASE | ES_WANTRETURN
LTEXT "Compare:",IDC_CHEAT_COM_LABEL,117,163,34,8
EDITTEXT IDC_CHEAT_COM,152,161,16,12,ES_UPPERCASE | ES_WANTRETURN
LTEXT "Cheat code / Game Genie:",IDC_CHEAT_CODE_GG_LABEL,11,177,87,8
EDITTEXT IDC_CHEAT_TEXT,105,175,63,12,ES_UPPERCASE | ES_AUTOHSCROLL
DEFPUSHBUTTON "Add",IDC_BTN_CHEAT_ADD,7,192,30,16
PUSHBUTTON "Delete",IDC_BTN_CHEAT_DEL,37,192,30,16
PUSHBUTTON "Update",IDC_BTN_CHEAT_UPD,67,192,30,16
PUSHBUTTON "Import...",IDC_BTN_CHEAT_ADDFROMFILE,100,192,36,16
PUSHBUTTON "Export...",IDC_BTN_CHEAT_EXPORTTOFILE,136,192,36,16
GROUPBOX "Active Cheats",IDC_GROUPBOX_CHEATLIST,5,2,169,219,WS_TABSTOP
CONTROL "Enable cheats",IDC_CHEAT_GLOBAL_SWITCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,12,58,10
CONTROL "Auto load / save with game",IDC_CHEAT_AUTOLOADSAVE,
"Button",BS_AUTO3STATE | WS_TABSTOP,71,12,100,10
CONTROL "",IDC_LIST_CHEATS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,11,24,157,133
LTEXT "Name:",IDC_STATIC,12,162,22,10
EDITTEXT IDC_CHEAT_NAME,37,160,131,12,ES_AUTOHSCROLL | ES_WANTRETURN
LTEXT "Address:",IDC_CHEAT_ADDRESS_LABEL,12,176,30,8
EDITTEXT IDC_CHEAT_ADDR,44,174,25,12,ES_UPPERCASE | ES_WANTRETURN
LTEXT "Value:",IDC_CHEAT_VAL_LABEL,73,176,22,8
EDITTEXT IDC_CHEAT_VAL,97,174,16,12,ES_UPPERCASE | ES_WANTRETURN
LTEXT "Compare:",IDC_CHEAT_COM_LABEL,117,176,34,8
EDITTEXT IDC_CHEAT_COM,152,174,16,12,ES_UPPERCASE | ES_WANTRETURN
LTEXT "Cheat code / Game Genie:",IDC_CHEAT_CODE_GG_LABEL,11,190,87,8
EDITTEXT IDC_CHEAT_TEXT,105,188,63,12,ES_UPPERCASE | ES_AUTOHSCROLL
DEFPUSHBUTTON "Add",IDC_BTN_CHEAT_ADD,7,202,30,16
PUSHBUTTON "Delete",IDC_BTN_CHEAT_DEL,37,202,30,16
PUSHBUTTON "Update",IDC_BTN_CHEAT_UPD,67,202,30,16
PUSHBUTTON "Import...",IDC_BTN_CHEAT_ADDFROMFILE,100,202,36,16
PUSHBUTTON "Export...",IDC_BTN_CHEAT_EXPORTTOFILE,136,202,36,16
GROUPBOX "Cheat Search",IDC_GROUPBOX_CHEATSEARCH,180,2,201,206,WS_TABSTOP
PUSHBUTTON "Reset",IDC_BTN_CHEAT_RESET,192,12,55,15
PUSHBUTTON "Known Value:",IDC_BTN_CHEAT_KNOWN,192,32,55,15
LTEXT "0x",IDC_CHEAT_LABEL_KNOWN,217,51,9,8
EDITTEXT IDC_CHEAT_VAL_KNOWN,228,49,18,12,ES_UPPERCASE
GROUPBOX "Previous Compare",IDC_GROUP_PREV_COM,185,63,69,132
PUSHBUTTON "Equal",IDC_BTN_CHEAT_EQ,192,75,55,15,WS_GROUP
PUSHBUTTON "Not Equal",IDC_BTN_CHEAT_NE,192,96,55,15
CONTROL "By:",IDC_CHEAT_CHECK_NE_BY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,114,22,10
EDITTEXT IDC_CHEAT_VAL_NE_BY,228,113,18,12,ES_UPPERCASE | ES_WANTRETURN
PUSHBUTTON "Greater Than",IDC_BTN_CHEAT_GT,192,129,55,15
CONTROL "By:",IDC_CHEAT_CHECK_GT_BY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,147,22,10
EDITTEXT IDC_CHEAT_VAL_GT_BY,228,146,18,12,ES_UPPERCASE | ES_WANTRETURN
PUSHBUTTON "Less Than",IDC_BTN_CHEAT_LT,192,162,55,15
CONTROL "By:",IDC_CHEAT_CHECK_LT_BY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,180,22,10
EDITTEXT IDC_CHEAT_VAL_LT_BY,228,179,18,12,ES_UPPERCASE | ES_WANTRETURN
GROUPBOX "Possibilities",IDC_CHEAT_BOX_POSSIBILITIES,258,8,117,187,WS_TABSTOP
CONTROL "",IDC_CHEAT_LIST_POSSIBILITIES,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,264,18,106,172
CONTROL " Pause emulation when this window is active",IDC_CHEAT_PAUSEWHENACTIVE,
"Button",BS_AUTOCHECKBOX,180,202,157,10
PUSHBUTTON "Known Value:",IDC_BTN_CHEAT_KNOWN,192,36,55,15
LTEXT "0x",IDC_CHEAT_LABEL_KNOWN,217,55,9,8
EDITTEXT IDC_CHEAT_VAL_KNOWN,228,53,18,12,ES_UPPERCASE
GROUPBOX "Previous Compare",IDC_GROUP_PREV_COM,185,68,69,135
PUSHBUTTON "Equal",IDC_BTN_CHEAT_EQ,192,79,55,15,WS_GROUP
PUSHBUTTON "Not Equal",IDC_BTN_CHEAT_NE,192,99,55,15
CONTROL "By:",IDC_CHEAT_CHECK_NE_BY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,117,22,10
EDITTEXT IDC_CHEAT_VAL_NE_BY,228,116,18,12,ES_UPPERCASE | ES_WANTRETURN
PUSHBUTTON "Greater Than",IDC_BTN_CHEAT_GT,192,134,55,15
CONTROL "By:",IDC_CHEAT_CHECK_GT_BY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,152,22,10
EDITTEXT IDC_CHEAT_VAL_GT_BY,228,151,18,12,ES_UPPERCASE | ES_WANTRETURN
PUSHBUTTON "Less Than",IDC_BTN_CHEAT_LT,192,169,55,15
CONTROL "By:",IDC_CHEAT_CHECK_LT_BY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,204,187,22,10
EDITTEXT IDC_CHEAT_VAL_LT_BY,228,186,18,12,ES_UPPERCASE | ES_WANTRETURN
GROUPBOX "Possibilities",IDC_CHEAT_BOX_POSSIBILITIES,258,8,117,195,WS_TABSTOP
CONTROL "",IDC_CHEAT_LIST_POSSIBILITIES,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,264,18,106,179
CONTROL "Pause emulation when this window is active",IDC_CHEAT_PAUSEWHENACTIVE,
"Button",BS_AUTOCHECKBOX,180,211,157,10
END
IDD_LUA DIALOGEX 0, 0, 270, 150
@ -2511,7 +2514,7 @@ BEGIN
"CHEATCONSOLE", DIALOG
BEGIN
RIGHTMARGIN, 386
BOTTOMMARGIN, 217
BOTTOMMARGIN, 225
END
"VIDEOCONFIG", DIALOG

View File

@ -473,6 +473,7 @@
#define IDSAVE 1012
#define MW_ADDR04 1013
#define IDC_CHECK1 1013
#define IDC_CHEAT_AUTOLOADSAVE 1013
#define IDC_RESTORE_BUTTON 1014
#define MW_ADDR05 1016
#define IDC_PRGROM_COMBO 1018
@ -536,7 +537,7 @@
#define IDC_RADIO_VERSION_INES20 1073
#define IDC_VERSION_GROUP 1074
#define IDC_MAPPER_GROUP 1075
#define IDC_CHECK_BATTERYNVRAM 1076
#define IDC_CHECK_BATTERYNVRAM 1076
#define IDC_INPUT_DEVICE_TEXT 1077
#define IDC_PRG_GROUP 1078
#define IDC_CHR_GROUP 1079
@ -545,11 +546,13 @@
#define IDC_CHECK_UNOFFICIAL_EXTRA_REGION 1083
#define IDC_CHECK_UNOFFICIAL_BUS_CONFLICT 1084
#define IDC_CHECK_UNOFFICIAL 1085
#define IDC_MISCELLANEOUS_ROMS_TEXT 1086
#define IDC_MISCELLANEOUS_ROMS_EDIT 1087
#define IDC_MISCELLANEOUS_ROMS_TEXT 1086
#define IDC_MISCELLANEOUS_ROMS_EDIT 1087
#define IDC_EXTEND_SYSTEM_GROUP 1089
#define IDC_EXTEND_SYSTEM_TEXT 1090
#define IDC_BUTTON1 1094
#define IDC_CHEAT_SWITCH 1096
#define IDC_CHEAT_GLOBAL_SWITCH 1096
#define BTN_ALLOW_LRUD 1117
#define BTN_PRESET_SET1 1119
#define BTN_PRESET_SET2 1120
@ -766,7 +769,7 @@
#define IDC_CHEAT_VAL_LABEL 1314
#define IDC_CHEAT_COM_LABEL 1315
#define IDC_CHEAT_LABEL_KNOWN 1316
#define MENU_INESHEADEREDITOR 40001
#define MENU_INESHEADEREDITOR 40001
#define MENU_NETWORK 40040
#define MENU_PALETTE 40041
#define MENU_SOUND 40042
@ -1062,7 +1065,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 305
#define _APS_NEXT_COMMAND_VALUE 40002
#define _APS_NEXT_CONTROL_VALUE 1095
#define _APS_NEXT_CONTROL_VALUE 1097
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -299,11 +299,11 @@ BOOL CALLBACK newProjectProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM l
break;
case IDC_COPY_INPUT:
p->copyCurrentInput ^= 1;
CheckDlgButton(hwndDlg, IDC_COPY_INPUT, p->copyCurrentInput?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_COPY_INPUT, p->copyCurrentInput? BST_CHECKED : BST_UNCHECKED);
break;
case IDC_COPY_MARKERS:
p->copyCurrentMarkers ^= 1;
CheckDlgButton(hwndDlg, IDC_COPY_MARKERS, p->copyCurrentMarkers?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_COPY_MARKERS, p->copyCurrentMarkers? BST_CHECKED : BST_UNCHECKED);
break;
case IDOK:
{
@ -792,7 +792,7 @@ BOOL CALLBACK ExportProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lPara
break;
}
}
CheckDlgButton(hwndDlg, IDC_NOTES_TO_SUBTITLES, taseditorConfig.lastExportedSubtitlesStatus?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_NOTES_TO_SUBTITLES, taseditorConfig.lastExportedSubtitlesStatus ? BST_CHECKED : BST_UNCHECKED);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
@ -808,7 +808,7 @@ BOOL CALLBACK ExportProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lPara
break;
case IDC_NOTES_TO_SUBTITLES:
taseditorConfig.lastExportedSubtitlesStatus ^= 1;
CheckDlgButton(hwndDlg, IDC_NOTES_TO_SUBTITLES, taseditorConfig.lastExportedSubtitlesStatus?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_NOTES_TO_SUBTITLES, taseditorConfig.lastExportedSubtitlesStatus ? BST_CHECKED : BST_UNCHECKED);
break;
case IDOK:
EndDialog(hwndDlg, 1);

View File

@ -630,7 +630,7 @@ BOOL CALLBACK findNoteWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM
if (taseditorConfig.findnoteWindowY == -32000) taseditorConfig.findnoteWindowY = 0;
SetWindowPos(hwndDlg, 0, taseditorConfig.findnoteWindowX, taseditorConfig.findnoteWindowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase ? BST_CHECKED : BST_UNCHECKED);
if (taseditorConfig.findnoteSearchUp)
Button_SetCheck(GetDlgItem(hwndDlg, IDC_RADIO_UP), BST_CHECKED);
else
@ -680,7 +680,7 @@ BOOL CALLBACK findNoteWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM
break;
case IDC_MATCH_CASE:
taseditorConfig.findnoteMatchCase ^= 1;
CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase?MF_CHECKED : MF_UNCHECKED);
CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase? BST_CHECKED : BST_UNCHECKED);
break;
case IDOK:
{

View File

@ -367,8 +367,9 @@ void CalcWindowSize(RECT *al)
/// Updates the menu items that should only be enabled if a game is loaded.
/// @param enable Flag that indicates whether the menus should be enabled (1) or disabled (0).
void updateGameDependentMenus(unsigned int enable)
void updateGameDependentMenus()
{
// they are quite simple, enabled only when game is loaded
const int menu_ids[]= {
MENU_CLOSE_FILE,
ID_FILE_SCREENSHOT,
@ -396,10 +397,14 @@ void updateGameDependentMenus(unsigned int enable)
ID_TOOLS_TEXTHOOKER
};
bool enable = GameInfo != 0;
for (unsigned int i = 0; i < sizeof(menu_ids) / sizeof(*menu_ids); i++)
{
EnableMenuItem(fceumenu, menu_ids[i], MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED));
}
EnableMenuItem(fceumenu, menu_ids[i], MF_BYCOMMAND | enable ? MF_ENABLED : MF_GRAYED | MF_DISABLED);
// Special treatment for the iNES head editor, only when no game is loaded or an NES game is loaded
extern iNES_HEADER head;
enable = GameInfo == 0 || !strncmp((const char*)&head, "NES\x1A", 4);
EnableMenuItem(fceumenu, MENU_INESHEADEREDITOR, MF_BYCOMMAND | enable ? MF_ENABLED : MF_GRAYED | MF_DISABLED);
}
//Updates menu items which need to be checked or unchecked.
@ -1059,8 +1064,8 @@ void CloseGame()
{
FCEUI_CloseGame();
KillMemView();
updateGameDependentMenus(GameInfo != 0);
updateGameDependentMenusDebugger(GameInfo != 0);
updateGameDependentMenus();
updateGameDependentMenusDebugger();
SetMainWindowText();
}
}
@ -1121,8 +1126,8 @@ bool ALoad(const char *nameo, char* innerFilename, bool silent)
SetMainWindowText();
ParseGIInput(GameInfo);
updateGameDependentMenus(GameInfo != 0);
updateGameDependentMenusDebugger(GameInfo != 0);
updateGameDependentMenus();
updateGameDependentMenusDebugger();
EmulationPaused = oldPaused;
return true;
}
@ -2682,8 +2687,8 @@ int CreateMainWindow()
UpdateLuaRMenu(recentluamenu, recent_lua, MENU_LUA_RECENT, LUA_FIRST_RECENT_FILE);
UpdateMovieRMenu(recentmoviemenu, recent_movie, MENU_MOVIE_RECENT, MOVIE_FIRST_RECENT_FILE);
updateGameDependentMenus(0);
updateGameDependentMenusDebugger(0);
updateGameDependentMenus();
updateGameDependentMenusDebugger();
if (MainWindow_wndx==-32000) MainWindow_wndx=0; //Just in case
if (MainWindow_wndy==-32000) MainWindow_wndy=0;
hAppWnd = CreateWindowEx(

View File

@ -189,7 +189,12 @@ static void FCEU_CloseGame(void)
}
if (GameInfo->type != GIT_NSF) {
FCEU_FlushGameCheats(0, 0);
if (disableAutoLSCheats == 2)
FCEU_FlushGameCheats(0, 1);
else if (disableAutoLSCheats == 1)
AskSaveCheat();
else if (disableAutoLSCheats == 0)
FCEU_FlushGameCheats(0, 0);
}
GameInterface(GI_CLOSE);
@ -521,7 +526,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
FCEUI_printf("NTSC mode set");
}
if (GameInfo->type != GIT_NSF)
if (GameInfo->type != GIT_NSF && !disableAutoLSCheats)
FCEU_LoadGameCheats(0);
if (AutoResumePlay)