Merge pull request #47 from owomomo/master

Some features for RAM search and watch.
This commit is contained in:
CaH4e3 2019-04-05 21:55:08 +03:00 committed by GitHub
commit 0eed8fa234
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1103 additions and 1019 deletions

View File

@ -136,6 +136,14 @@ void FCEU_PowerCheats()
RebuildSubCheats(); RebuildSubCheats();
} }
int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size) {
int count = 0;
for (int i = 0; i < numsubcheats && count < size; ++i)
if (SubCheats[i].addr >= address && SubCheats[i].addr < address + size)
++count;
return count;
}
static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type); static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int status, int type);
static void CheatMemErr(void) static void CheatMemErr(void)
{ {

View File

@ -5,6 +5,8 @@ void FCEU_LoadGameCheats(FILE *override);
void FCEU_FlushGameCheats(FILE *override, int nosave); void FCEU_FlushGameCheats(FILE *override, int nosave);
void FCEU_ApplyPeriodicCheats(void); void FCEU_ApplyPeriodicCheats(void);
void FCEU_PowerCheats(void); void FCEU_PowerCheats(void);
int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size);
int FCEU_CheatGetByte(uint32 A); int FCEU_CheatGetByte(uint32 A);
void FCEU_CheatSetByte(uint32 A, uint8 V); void FCEU_CheatSetByte(uint32 A, uint8 V);
@ -29,3 +31,10 @@ struct CHEATF {
int type; /* 0 for replace, 1 for substitute(GG). */ int type; /* 0 for replace, 1 for substitute(GG). */
int status; int status;
}; };
#define CalcAddressRangeCheatCount(count, address, size) \
count = 0; \
for (int i = 0; i < numsubcheats && count < size; ++i) \
if (SubCheats[i].addr >= address && SubCheats[i].addr < address + size) \
++count;

View File

@ -471,7 +471,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)"");
SetDlgItemText(hwndDlg,IDC_CHEAT_NAME,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_NAME,(LPTSTR)"");
} }
if (hMemView) UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well UpdateCheatWindowRelatedWindow();
UpdateCheatsAdded(); UpdateCheatsAdded();
break; break;
case ID_CHEATLISTPOPUP_DELETESELECTEDCHEATS: case ID_CHEATLISTPOPUP_DELETESELECTEDCHEATS:
@ -490,7 +490,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
SetDlgItemText(hwndDlg,IDC_CHEAT_VAL,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_VAL,(LPTSTR)"");
SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)"");
SetDlgItemText(hwndDlg,IDC_CHEAT_NAME,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_NAME,(LPTSTR)"");
if (hMemView) UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well UpdateCheatWindowRelatedWindow();
UpdateCheatsAdded(); UpdateCheatsAdded();
} }
} else { } else {
@ -503,7 +503,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)"");
SetDlgItemText(hwndDlg,IDC_CHEAT_NAME,(LPTSTR)""); SetDlgItemText(hwndDlg,IDC_CHEAT_NAME,(LPTSTR)"");
} }
if (hMemView) UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well UpdateCheatWindowRelatedWindow();
UpdateCheatsAdded(); UpdateCheatsAdded();
} }
break; break;
@ -551,7 +551,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
SetDlgItemText(hwndDlg,IDC_CHEAT_VAL,(LPTSTR)U8ToStr(v)); SetDlgItemText(hwndDlg,IDC_CHEAT_VAL,(LPTSTR)U8ToStr(v));
if(c == -1) SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)""); if(c == -1) SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)"");
else SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)U8ToStr(c)); else SetDlgItemText(hwndDlg,IDC_CHEAT_COM,(LPTSTR)U8ToStr(c));
if(hMemView)UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well UpdateCheatWindowRelatedWindow();
break; break;
case IDC_BTN_CHEAT_ADDFROMFILE: case IDC_BTN_CHEAT_ADDFROMFILE:
{ {
@ -577,7 +577,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
if (file) if (file)
{ {
FCEU_LoadGameCheats(file); FCEU_LoadGameCheats(file);
if (hMemView) UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well UpdateCheatWindowRelatedWindow();
UpdateCheatsAdded(); UpdateCheatsAdded();
savecheats = 1; savecheats = 1;
} }
@ -670,7 +670,7 @@ BOOL CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
} }
} }
UpdateCheatsAdded(); UpdateCheatsAdded();
UpdateColorTable(); UpdateCheatWindowRelatedWindow();
SendDlgItemMessage(hwndDlg,IDC_LIST_CHEATS,LB_SETCURSEL,selcheat,0); SendDlgItemMessage(hwndDlg,IDC_LIST_CHEATS,LB_SETCURSEL,selcheat,0);
SendDlgItemMessage(hwndDlg,IDC_LIST_CHEATS,LB_SETSEL,(WPARAM)1,selcheat); SendDlgItemMessage(hwndDlg,IDC_LIST_CHEATS,LB_SETSEL,(WPARAM)1,selcheat);
break; break;
@ -1031,27 +1031,43 @@ CPoint test = point;
void DisableAllCheats() void DisableAllCheats()
{ {
if(!FCEU_DisableAllCheats() || !hCheat){ if(FCEU_DisableAllCheats() && hCheat){
return;
}
int selcheattemp = SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_GETCOUNT, 0, 0) - 1;
LRESULT sel; char str[259]; LRESULT sel; char str[259];
while(selcheattemp >= 0) for (int tempSelCheat = SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_GETCOUNT, 0, 0) - 1; tempSelCheat >= 0; --tempSelCheat)
{ {
SendDlgItemMessage(hCheat,IDC_LIST_CHEATS,LB_GETTEXT,selcheattemp, (LPARAM)(LPCTSTR)str); SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_GETTEXT, tempSelCheat, (LPARAM)(LPCTSTR)str);
if (str[0] == '*') if (str[0] == '*')
{ {
sel = SendDlgItemMessage(hCheat,IDC_LIST_CHEATS,LB_GETSEL,selcheattemp,0);
str[0] = ' '; str[0] = ' ';
SendDlgItemMessage(hCheat,IDC_LIST_CHEATS,LB_DELETESTRING,selcheattemp,0); sel = SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_GETSEL, tempSelCheat, 0);
SendDlgItemMessage(hCheat,IDC_LIST_CHEATS,LB_INSERTSTRING,selcheattemp, (LPARAM)(LPSTR)str); SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_DELETESTRING, tempSelCheat, 0);
SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_INSERTSTRING, tempSelCheat, (LPARAM)(LPSTR)str);
if (sel) if (sel)
{ SendDlgItemMessage(hCheat, IDC_LIST_CHEATS, LB_SETSEL, 1, tempSelCheat);
SendDlgItemMessage(hCheat,IDC_LIST_CHEATS,LB_SETSEL,1,selcheattemp);
} }
} }
selcheattemp--;
}
sprintf(str, "Active Cheats %d", 0); sprintf(str, "Active Cheats %d", 0);
SetDlgItemText(hCheat, 201, str); SetDlgItemText(hCheat, 201, str);
} }
}
void UpdateCheatWindowRelatedWindow()
{
// hex editor
if (hMemView)
UpdateColorTable(); //if the memory viewer is open then update any blue freeze locations in it as well
extern HWND RamSearchHWnd;
// ram search
if (RamSearchHWnd)
RedrawWindow(GetDlgItem(RamSearchHWnd, IDC_RAMLIST), NULL, NULL, RDW_INVALIDATE); // if ram search is open then update the ram list.
// ram watch
extern void UpdateWatchCheats();
UpdateWatchCheats();
extern HWND RamWatchHWnd;
if (RamWatchHWnd)
RedrawWindow(GetDlgItem(RamWatchHWnd, IDC_WATCHLIST), NULL, NULL, RDW_INVALIDATE); // update the data in watch list to the newest.
}

View File

@ -16,3 +16,5 @@ extern std::vector<uint16> FrozenAddresses;
//void ConfigAddCheat(HWND wnd); //bbit edited:commented out this line //void ConfigAddCheat(HWND wnd); //bbit edited:commented out this line
void DisableAllCheats(); void DisableAllCheats();
void UpdateCheatWindowRelatedWindow();

View File

@ -1263,7 +1263,7 @@ LRESULT CALLBACK MemViewCallB(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
// update menus // update menus
for (i = MODE_NES_MEMORY; i <= MODE_NES_FILE; i++) for (i = MODE_NES_MEMORY; i <= MODE_NES_FILE; i++)
if(EditingMode == i) { if(EditingMode == i) {
CheckMenuRadioItem(GetMenu(hMemView), MENU_MV_VIEW_RAM, MENU_MV_VIEW_ROM, MENU_MV_VIEW_RAM + i, MF_BYCOMMAND); CheckMenuRadioItem(GetMenu(hwnd), MENU_MV_VIEW_RAM, MENU_MV_VIEW_ROM, MENU_MV_VIEW_RAM, MF_BYCOMMAND);
break; break;
} }
CheckMenuItem(GetMenu(hwnd), ID_HIGHLIGHTING_HIGHLIGHT_ACTIVITY, (MemView_HighlightActivity) ? MF_CHECKED: MF_UNCHECKED); CheckMenuItem(GetMenu(hwnd), ID_HIGHLIGHTING_HIGHLIGHT_ACTIVITY, (MemView_HighlightActivity) ? MF_CHECKED: MF_UNCHECKED);

View File

@ -85,7 +85,7 @@ struct MemoryRegion
unsigned int virtualIndex; // index into s_prevValues, s_curValues, and s_numChanges, valid after being initialized in ResetMemoryRegions() unsigned int virtualIndex; // index into s_prevValues, s_curValues, and s_numChanges, valid after being initialized in ResetMemoryRegions()
unsigned int itemIndex; // index into listbox items, valid when s_itemIndicesInvalid is false unsigned int itemIndex; // index into listbox items, valid when s_itemIndicesInvalid is false
unsigned int cheatAffect; // how many bytes affected by the cheats. 0 indicates for free, max value is the size. unsigned int cheatCount; // how many bytes affected by the cheats. 0 indicates for free, max value is the size.
}; };
int MAX_RAM_SIZE = 0; int MAX_RAM_SIZE = 0;
@ -423,10 +423,7 @@ void ItemIndexToVirtualRegion(unsigned int itemIndex, MemoryRegion& virtualRegio
virtualRegion.virtualIndex = region->virtualIndex + bytesWithinRegion; virtualRegion.virtualIndex = region->virtualIndex + bytesWithinRegion;
virtualRegion.itemIndex = itemIndex; virtualRegion.itemIndex = itemIndex;
virtualRegion.cheatAffect = 0; virtualRegion.cheatCount = FCEU_CalcCheatAffectedBytes(virtualRegion.hardwareAddress, virtualRegion.size);
for (int i = 0; i < numsubcheats; ++i)
if (SubCheats[i].addr >= virtualRegion.hardwareAddress && SubCheats[i].addr < virtualRegion.hardwareAddress + virtualRegion.size)
++virtualRegion.cheatAffect;
} }
template<typename stepType, typename compareType> template<typename stepType, typename compareType>
@ -494,11 +491,11 @@ unsigned int GetHardwareAddressFromItemIndex(unsigned int itemIndex)
return virtualRegion.hardwareAddress; return virtualRegion.hardwareAddress;
} }
template<typename stepType, typename compareType> template<typename stepType, typename compareType>
unsigned int GetCheatStatusFromItemIndex(unsigned int itemIndex) unsigned int GetNumCheatsFromIndex(unsigned int itemIndex)
{ {
MemoryRegion virtualRegion; MemoryRegion virtualRegion;
ItemIndexToVirtualRegion<stepType, compareType>(itemIndex, virtualRegion); ItemIndexToVirtualRegion<stepType, compareType>(itemIndex, virtualRegion);
return virtualRegion.cheatAffect; return virtualRegion.cheatCount;
} }
// this one might be unreliable, haven't used it much // this one might be unreliable, haven't used it much
@ -995,7 +992,6 @@ bool WriteValueAtHardwareAddress(HWAddressType address, unsigned int value, unsi
int ResultCount=0; int ResultCount=0;
bool AutoSearch=false; bool AutoSearch=false;
bool AutoSearchAutoRetry=false; bool AutoSearchAutoRetry=false;
LRESULT CALLBACK PromptWatchNameProc(HWND, UINT, WPARAM, LPARAM);
void UpdatePossibilities(int rs_possible, int regions); void UpdatePossibilities(int rs_possible, int regions);
@ -1269,20 +1265,30 @@ LRESULT CustomDraw (LPARAM lParam)
case CDDS_ITEMPREPAINT: case CDDS_ITEMPREPAINT:
{ {
int rv = CDRF_DODEFAULT; int rv = CDRF_DODEFAULT;
int cheat = CALL_WITH_T_SIZE_TYPES_1(GetNumCheatsFromIndex, rs_type_size, rs_t == 's', noMisalign, lplvcd->nmcd.dwItemSpec);
switch (cheat) {
default:
case 0:
if (lplvcd->nmcd.dwItemSpec % 2) if (lplvcd->nmcd.dwItemSpec % 2)
{
// alternate the background color slightly
lplvcd->clrTextBk = RGB(248, 248, 255); lplvcd->clrTextBk = RGB(248, 248, 255);
rv = CDRF_NEWFONT; break;
case 1:
lplvcd->clrTextBk = RGB(216, 203, 253); break;
case 2:
lplvcd->clrTextBk = RGB(195, 186, 253); break;
case 3:
lplvcd->clrTextBk = RGB(176, 139, 252); break;
case 4:
lplvcd->clrTextBk = RGB(175, 94, 253);
lplvcd->clrText = RGB(255, 255, 255); break; // use a more visual color in dark background
} }
if(!IsSatisfied(lplvcd->nmcd.dwItemSpec)) if(!IsSatisfied(lplvcd->nmcd.dwItemSpec))
{
// tint red any items that would be eliminated if a search were to run now // tint red any items that would be eliminated if a search were to run now
lplvcd->clrText = RGB(192,64,64); // changed to a more visual color in dark background
lplvcd->clrText = cheat == 4 ? RGB(255,192,0) : RGB(192,64,64);
rv = CDRF_NEWFONT; rv = CDRF_NEWFONT;
}
return rv; return rv;
} break; } break;
@ -1518,8 +1524,8 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
SendDlgItemMessage(hDlg,IDC_C_SEARCHROM,BM_SETCHECK,ShowROM?BST_CHECKED:BST_UNCHECKED,0); SendDlgItemMessage(hDlg,IDC_C_SEARCHROM,BM_SETCHECK,ShowROM?BST_CHECKED:BST_UNCHECKED,0);
//const char* names[5] = {"Address","Value","Previous","Changes","Notes"}; //const char* names[5] = {"Address","Value","Previous","Changes","Notes"};
//int widths[5] = {62,64,64,55,55}; //int widths[5] = {62,64,64,55,55};
const char* names[5] = {"Addr.","Value","Previous","Changes","Cheats"}; const char* names[5] = {"Addr.","Value","Previous","Changes"};
int widths[5] = {48,80,80,66,52}; int widths[5] = {68,76,76,68};
if (!ResultCount) if (!ResultCount)
reset_address_info(); reset_address_info();
else else
@ -1528,7 +1534,7 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
CompactAddrs(); CompactAddrs();
} }
void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths); void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths);
init_list_box(GetDlgItem(hDlg,IDC_RAMLIST),names,5,widths); init_list_box(GetDlgItem(hDlg,IDC_RAMLIST),names,4,widths);
//ListView_SetItemCount(GetDlgItem(hDlg,IDC_RAMLIST),ResultCount); //ListView_SetItemCount(GetDlgItem(hDlg,IDC_RAMLIST),ResultCount);
if (!noMisalign) SendDlgItemMessage(hDlg, IDC_MISALIGN, BM_SETCHECK, BST_CHECKED, 0); if (!noMisalign) SendDlgItemMessage(hDlg, IDC_MISALIGN, BM_SETCHECK, BST_CHECKED, 0);
//if (littleEndian) SendDlgItemMessage(hDlg, IDC_ENDIAN, BM_SETCHECK, BST_CHECKED, 0); //if (littleEndian) SendDlgItemMessage(hDlg, IDC_ENDIAN, BM_SETCHECK, BST_CHECKED, 0);
@ -1627,7 +1633,7 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
} return true; } return true;
case 4: case 4:
{ {
int cheat = CALL_WITH_T_SIZE_TYPES_1(GetCheatStatusFromItemIndex, rs_type_size, rs_t=='s', noMisalign, iNum); int cheat = CALL_WITH_T_SIZE_TYPES_1(GetNumCheatsFromIndex, rs_type_size, rs_t=='s', noMisalign, iNum);
sprintf(num, "%d", cheat); sprintf(num, "%d", cheat);
Item->item.pszText = num; Item->item.pszText = num;
} }
@ -2175,9 +2181,9 @@ void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidt
{ {
LVCOLUMN Col; LVCOLUMN Col;
Col.mask = LVCF_FMT | LVCF_ORDER | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH; Col.mask = LVCF_FMT | LVCF_ORDER | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
Col.fmt = LVCFMT_RIGHT;
for (int i = 0; i < numColumns; i++) for (int i = 0; i < numColumns; i++)
{ {
Col.fmt = !strcmp(Strs[i], "Value") || !strcmp(Strs[i], "Previous") || !strcmp(Strs[i], "Changes") ? LVCFMT_RIGHT : LVCFMT_LEFT;
Col.iOrder = i; Col.iOrder = i;
Col.iSubItem = i; Col.iSubItem = i;
Col.pszText = (LPSTR)(Strs[i]); Col.pszText = (LPSTR)(Strs[i]);

View File

@ -48,7 +48,7 @@ HWND RamWatchHWnd;
#define gamefilename GetRomName() #define gamefilename GetRomName()
#define hWnd hAppWnd #define hWnd hAppWnd
#define hInst fceu_hInstance #define hInst fceu_hInstance
static char Str_Tmp [1024]; // static char Str_Tmp [1024];
void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths); //initializes the ram search and/or ram watch listbox void init_list_box(HWND Box, const char* Strs[], int numColumns, int *columnWidths); //initializes the ram search and/or ram watch listbox
@ -105,15 +105,22 @@ bool InsertWatch(const AddressWatcher& Watch, char *Comment)
AddressWatcher& NewWatch = rswatches[i]; AddressWatcher& NewWatch = rswatches[i];
NewWatch = Watch; NewWatch = Watch;
//if (NewWatch.comment) free(NewWatch.comment); //if (NewWatch.comment) free(NewWatch.comment);
if (NewWatch.comment == NULL)
NewWatch.comment = (char *)malloc(strlen(Comment) + 2); NewWatch.comment = (char *)malloc(strlen(Comment) + 2);
NewWatch.CurValue = GetCurrentValue(NewWatch); else
NewWatch.comment = (char *)realloc(NewWatch.comment, strlen(Comment) + 2);
strcpy(NewWatch.comment, Comment); strcpy(NewWatch.comment, Comment);
NewWatch.CurValue = GetCurrentValue(NewWatch);
extern int FCEU_CalcCheatAffectedBytes(uint32, uint32);
NewWatch.Cheats = FCEU_CalcCheatAffectedBytes(NewWatch.Address, WatchSizeConv(NewWatch));
ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount); ListView_SetItemCount(GetDlgItem(RamWatchHWnd,IDC_WATCHLIST),WatchCount);
RWfileChanged=true; RWfileChanged=true;
return true; return true;
} }
/*
LRESULT CALLBACK PromptWatchNameProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets the description of a watched address LRESULT CALLBACK PromptWatchNameProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets the description of a watched address
{ {
RECT r; RECT r;
@ -168,7 +175,7 @@ LRESULT CALLBACK PromptWatchNameProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM
return false; return false;
} }
*/
bool InsertWatch(const AddressWatcher& Watch, HWND parent) bool InsertWatch(const AddressWatcher& Watch, HWND parent)
{ {
if(!VerifyWatchNotAlreadyAdded(Watch)) if(!VerifyWatchNotAlreadyAdded(Watch))
@ -183,7 +190,7 @@ bool InsertWatch(const AddressWatcher& Watch, HWND parent)
rswatches[WatchCount] = Watch; rswatches[WatchCount] = Watch;
rswatches[WatchCount].CurValue = GetCurrentValue(rswatches[WatchCount]); rswatches[WatchCount].CurValue = GetCurrentValue(rswatches[WatchCount]);
DialogBox(hInst, MAKEINTRESOURCE(IDD_PROMPT), parent, (DLGPROC) PromptWatchNameProc); DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), parent, (DLGPROC) EditWatchProc, (LPARAM)WatchCount);
return WatchCount > prevWatchCount; return WatchCount > prevWatchCount;
} }
@ -242,7 +249,7 @@ bool AskSave()
//returns false only if a save was attempted but failed or was cancelled //returns false only if a save was attempted but failed or was cancelled
if (RWfileChanged) if (RWfileChanged)
{ {
int answer = MessageBox(MESSAGEBOXPARENT, "Save Changes?", "Ram Watch", MB_YESNOCANCEL); int answer = MessageBox(MESSAGEBOXPARENT, "Save Changes?", "Ram Watch", MB_YESNOCANCEL | MB_ICONQUESTION);
if(answer == IDYES) if(answer == IDYES)
if(!QuickSaveWatches()) if(!QuickSaveWatches())
return false; return false;
@ -402,6 +409,7 @@ void OpenRWRecentFile(int memwRFileNumber)
} }
} }
char Str_Tmp[1024];
strcpy(currentWatch,x); strcpy(currentWatch,x);
strcpy(Str_Tmp,currentWatch); strcpy(Str_Tmp,currentWatch);
@ -409,7 +417,7 @@ void OpenRWRecentFile(int memwRFileNumber)
FILE *WatchFile = fopen(Str_Tmp,"rb"); FILE *WatchFile = fopen(Str_Tmp,"rb");
if (!WatchFile) if (!WatchFile)
{ {
int answer = MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OKCANCEL); int answer = MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OKCANCEL | MB_ICONERROR);
if (answer == IDOK) if (answer == IDOK)
{ {
rw_recent_files[rnum][0] = '\0'; //Clear file from list rw_recent_files[rnum][0] = '\0'; //Clear file from list
@ -425,6 +433,7 @@ void OpenRWRecentFile(int memwRFileNumber)
Temp.Address = 0; // default values Temp.Address = 0; // default values
Temp.Size = 'b'; Temp.Size = 'b';
Temp.Type = 'h'; Temp.Type = 'h';
Temp.comment = NULL;
char mode; char mode;
fgets(Str_Tmp,1024,WatchFile); fgets(Str_Tmp,1024,WatchFile);
sscanf(Str_Tmp,"%c%*s",&mode); sscanf(Str_Tmp,"%c%*s",&mode);
@ -536,6 +545,7 @@ int Change_File_S(char *Dest, const char *Dir, const char *Titre, const char *Fi
bool Save_Watches() bool Save_Watches()
{ {
char Str_Tmp[1024];
string initdir = FCEU_GetPath(FCEUMKF_MEMW); string initdir = FCEU_GetPath(FCEUMKF_MEMW);
const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/'))); const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/')));
strcpy(Str_Tmp,slash ? slash+1 : gamefilename); strcpy(Str_Tmp,slash ? slash+1 : gamefilename);
@ -568,10 +578,9 @@ bool QuickSaveWatches()
{ {
if (RWfileChanged==false) return true; //If file has not changed, no need to save changes if (RWfileChanged==false) return true; //If file has not changed, no need to save changes
if (currentWatch[0] == NULL) //If there is no currently loaded file, run to Save as and then return if (currentWatch[0] == NULL) //If there is no currently loaded file, run to Save as and then return
{
return Save_Watches(); return Save_Watches();
}
char Str_Tmp[1024];
strcpy(Str_Tmp,currentWatch); strcpy(Str_Tmp,currentWatch);
FILE *WatchFile = fopen(Str_Tmp,"w+b"); FILE *WatchFile = fopen(Str_Tmp,"w+b");
fputc('\n',WatchFile); fputc('\n',WatchFile);
@ -594,7 +603,7 @@ bool Load_Watches(bool clear, const char* filename)
FILE* WatchFile = fopen(filename,"rb"); FILE* WatchFile = fopen(filename,"rb");
if (!WatchFile) if (!WatchFile)
{ {
MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OK); MessageBox(MESSAGEBOXPARENT,"Error opening file.","ERROR",MB_OK | MB_ICONERROR);
return false; return false;
} }
if(clear) if(clear)
@ -612,6 +621,7 @@ bool Load_Watches(bool clear, const char* filename)
Temp.Size = 'b'; Temp.Size = 'b';
Temp.Type = 'h'; Temp.Type = 'h';
char mode; char mode;
char Str_Tmp[1024];
fgets(Str_Tmp,1024,WatchFile); fgets(Str_Tmp,1024,WatchFile);
sscanf(Str_Tmp,"%c%*s",&mode); sscanf(Str_Tmp,"%c%*s",&mode);
int WatchAdd; int WatchAdd;
@ -656,6 +666,7 @@ bool Load_Watches(bool clear, const char* filename)
bool Load_Watches(bool clear) bool Load_Watches(bool clear)
{ {
char Str_Tmp[1024];
string initdir = FCEU_GetPath(FCEUMKF_MEMW); string initdir = FCEU_GetPath(FCEUMKF_MEMW);
const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/'))); const char* slash = max(strrchr(gamefilename, '|'), max(strrchr(gamefilename, '\\'), strrchr(gamefilename, '/')));
strcpy(Str_Tmp,slash ? slash+1 : gamefilename); strcpy(Str_Tmp,slash ? slash+1 : gamefilename);
@ -714,36 +725,24 @@ void RefreshWatchListSelectedItemControlStatus(HWND hDlg)
LRESULT CALLBACK EditWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets info for a RAM Watch, and then inserts it into the Watch List LRESULT CALLBACK EditWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //Gets info for a RAM Watch, and then inserts it into the Watch List
{ {
RECT r;
RECT r2;
int dx1, dy1, dx2, dy2;
static int index; static int index;
static char s,t = s = 0;
switch(uMsg) switch(uMsg)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
//Clear_Sound_Buffer(); {
RECT r;
GetWindowRect(hWnd, &r); GetWindowRect(hWnd, &r);
dx1 = (r.right - r.left) / 2;
dy1 = (r.bottom - r.top) / 2;
GetWindowRect(hDlg, &r2);
dx2 = (r2.right - r2.left) / 2;
dy2 = (r2.bottom - r2.top) / 2;
//SetWindowPos(hDlg, NULL, max(0, r.left + (dx1 - dx2)), max(0, r.top + (dy1 - dy2)), NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); SetWindowPos(hDlg, NULL, r.left, r.top, NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
index = (int)lParam; index = (int)lParam;
sprintf(Str_Tmp,"%04X",rswatches[index].Address); AddressWatcher* watcher = &rswatches[index];
if (watcher->Type != 'S') {
char Str_Tmp[1024];
sprintf(Str_Tmp, "%04X", watcher->Address);
SetDlgItemText(hDlg, IDC_EDIT_COMPAREADDRESS, Str_Tmp); SetDlgItemText(hDlg, IDC_EDIT_COMPAREADDRESS, Str_Tmp);
if (rswatches[index].comment != NULL) switch (watcher->Size)
SetDlgItemText(hDlg,IDC_PROMPT_EDIT,rswatches[index].comment);
s = rswatches[index].Size;
t = rswatches[index].Type;
switch (s)
{ {
case 'b': case 'b':
SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_SETCHECK, BST_CHECKED, 0);
@ -754,11 +753,8 @@ LRESULT CALLBACK EditWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
case 'd': case 'd':
SendDlgItemMessage(hDlg, IDC_4_BYTES, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_4_BYTES, BM_SETCHECK, BST_CHECKED, 0);
break; break;
default:
s = 0;
break;
} }
switch (t) switch (watcher->Type)
{ {
case 's': case 's':
SendDlgItemMessage(hDlg, IDC_SIGNED, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_SIGNED, BM_SETCHECK, BST_CHECKED, 0);
@ -769,77 +765,103 @@ LRESULT CALLBACK EditWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
case 'h': case 'h':
SendDlgItemMessage(hDlg, IDC_HEX, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hDlg, IDC_HEX, BM_SETCHECK, BST_CHECKED, 0);
break; break;
default:
t = 0;
break;
} }
} else
SetDlgItemText(hDlg, IDC_EDIT_COMPAREADDRESS, "---------");
if (watcher->comment != NULL)
SetDlgItemText(hDlg, IDC_PROMPT_EDIT, watcher->comment);
if (watcher->Type == 'S' || GetParent(hDlg) == RamSearchHWnd)
{
EnableWindow(GetDlgItem(hDlg, IDC_SPECIFICADDRESS), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DATATYPE_GROUPBOX), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_DATASIZE_GROUPBOX), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_COMPAREADDRESS), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_SIGNED), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_UNSIGNED), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_HEX), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_1_BYTE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_2_BYTES), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_4_BYTES), FALSE);
SetFocus(GetDlgItem(hDlg, IDC_PROMPT_EDIT));
}
}
return true; return true;
break; break;
case WM_COMMAND: case WM_COMMAND:
switch(LOWORD(wParam)) switch(LOWORD(wParam))
{ {
case IDC_SIGNED:
t='s';
return true;
case IDC_UNSIGNED:
t='u';
return true;
case IDC_HEX:
t='h';
return true;
case IDC_1_BYTE:
s = 'b';
return true;
case IDC_2_BYTES:
s = 'w';
return true;
case IDC_4_BYTES:
s = 'd';
return true;
case IDOK: case IDOK:
{ {
if (s && t) char Str_Tmp[1024];
// a normal watch, copy it to a temporary one
AddressWatcher watcher = rswatches[index];
if (watcher.comment != NULL)
watcher.comment = strcpy((char*)malloc(strlen(watcher.comment) + 2), watcher.comment);
// It's from ram watch window, not a separator
if (RamWatchHWnd && RamWatchHWnd == GetParent(hDlg) && watcher.Type != 'S')
{ {
AddressWatcher Temp; GetDlgItemText(hDlg, IDC_PROMPT_EDIT, Str_Tmp, 1024);
Temp.Size = s;
Temp.Type = t; // type
Temp.WrongEndian = false; //replace this when I get little endian working properly if (SendDlgItemMessage(hDlg, IDC_SIGNED, BM_GETCHECK, 0, 0) == BST_CHECKED)
watcher.Type = 's';
else if (SendDlgItemMessage(hDlg, IDC_UNSIGNED, BM_GETCHECK, 0, 0) == BST_CHECKED)
watcher.Type = 'u';
else if (SendDlgItemMessage(hDlg, IDC_HEX, BM_GETCHECK, 0, 0) == BST_CHECKED)
watcher.Type = 'h';
else {
MessageBox(hDlg, "Type must be specified.", "Error", MB_OK | MB_ICONERROR);
return true;
}
// size
if (SendDlgItemMessage(hDlg, IDC_1_BYTE, BM_GETCHECK, 0, 0) == BST_CHECKED)
watcher.Size = 'b';
else if (SendDlgItemMessage(hDlg, IDC_2_BYTES, BM_GETCHECK, 0, 0) == BST_CHECKED)
watcher.Size = 'w';
else if (SendDlgItemMessage(hDlg, IDC_4_BYTES, BM_GETCHECK, 0, 0) == BST_CHECKED)
watcher.Size = 'd';
else {
MessageBox(hDlg, "Size must be specified.", "Error", MB_OK | MB_ICONERROR);
return true;
}
// address
GetDlgItemText(hDlg, IDC_EDIT_COMPAREADDRESS, Str_Tmp, 1024); GetDlgItemText(hDlg, IDC_EDIT_COMPAREADDRESS, Str_Tmp, 1024);
char *addrstr = Str_Tmp; char *addrstr = Str_Tmp;
if (strlen(Str_Tmp) > 8) addrstr = &(Str_Tmp[strlen(Str_Tmp) - 9]); if (strlen(Str_Tmp) > 8)
for(int i = 0; addrstr[i]; i++) {if(toupper(addrstr[i]) == 'O') addrstr[i] = '0';} addrstr = &Str_Tmp[strlen(Str_Tmp) - 9];
sscanf(addrstr,"%04X",&(Temp.Address)); for (int i = 0; addrstr[i]; ++i)
if (toupper(addrstr[i]) == 'O')
addrstr[i] = '0';
sscanf(addrstr, "%04X", &watcher.Address);
if((Temp.Address & ~0xFFFFFF) == ~0xFFFFFF) if ((watcher.Address & ~0xFFFFFF) == ~0xFFFFFF)
Temp.Address &= 0xFFFFFF; watcher.Address &= 0xFFFFFF;
if(IsHardwareAddressValid(Temp.Address)) if (!IsHardwareAddressValid(watcher.Address))
{ {
MessageBox(hDlg, "Invalid Address.", "Error", MB_OK | MB_ICONERROR);
return true;
}
}
// comment
GetDlgItemText(hDlg, IDC_PROMPT_EDIT, Str_Tmp, 80); GetDlgItemText(hDlg, IDC_PROMPT_EDIT, Str_Tmp, 80);
if (index < WatchCount) RemoveWatch(index);
InsertWatch(Temp,Str_Tmp); // finallly update the watch list
if (index < WatchCount)
// it's a watch editing operation, and the dialog is from Ram Watch Window, remove then insert;
RemoveWatch(index);
InsertWatch(watcher, Str_Tmp);
if (RamWatchHWnd) if (RamWatchHWnd)
{
ListView_SetItemCount(GetDlgItem(RamWatchHWnd, IDC_WATCHLIST), WatchCount); ListView_SetItemCount(GetDlgItem(RamWatchHWnd, IDC_WATCHLIST), WatchCount);
}
EndDialog(hDlg, true); EndDialog(hDlg, true);
}
else
{
MessageBox(hDlg,"Invalid Address","ERROR",MB_OK);
}
}
else
{
strcpy(Str_Tmp,"Error:");
if (!s)
strcat(Str_Tmp," Size must be specified.");
if (!t)
strcat(Str_Tmp," Type must be specified.");
MessageBox(hDlg,Str_Tmp,"ERROR",MB_OK);
}
RWfileChanged = true; RWfileChanged = true;
return true; return true;
break; break;
@ -1037,9 +1059,13 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
switch (Item->item.iSubItem) switch (Item->item.iSubItem)
{ {
case 0: case 0:
sprintf(num,"%04X",rswatches[iNum].Address); {
int size = WatchSizeConv(rswatches[iNum]);
int addr = rswatches[iNum].Address;
sprintf(num, rswatches[iNum].Type == 'S' ? "------" : size > 1 ? "%04X-%04X" : "%04X", addr, addr + size - 1);
Item->item.pszText = num; Item->item.pszText = num;
return true; return true;
}
case 1: { case 1: {
int i = rswatches[iNum].CurValue; int i = rswatches[iNum].CurValue;
int t = rswatches[iNum].Type; int t = rswatches[iNum].Type;
@ -1072,6 +1098,42 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
SetWindowLong(hDlg, DWL_MSGRESULT, ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST))); SetWindowLong(hDlg, DWL_MSGRESULT, ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)));
return 1; return 1;
} }
case NM_CUSTOMDRAW:
{
LPNMCUSTOMDRAW nmcd = (LPNMCUSTOMDRAW)lParam;
switch (nmcd->dwDrawStage)
{
case CDDS_ITEMPREPAINT:
{
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
if (rswatches[nmcd->dwItemSpec].Type == 'S')
lplvcd->clrTextBk = RGB(247, 187, 67);
else
switch (rswatches[nmcd->dwItemSpec].Cheats)
{
default:
case 0:
SetWindowLong(hDlg, DWL_MSGRESULT, CDRF_DODEFAULT);
return TRUE;
case 1:
lplvcd->clrTextBk = RGB(216, 203, 253); break;
case 2:
lplvcd->clrTextBk = RGB(195, 186, 253); break;
case 3:
lplvcd->clrTextBk = RGB(176, 139, 252); break;
case 4:
lplvcd->clrTextBk = RGB(175, 94, 253);
lplvcd->clrText = RGB(255, 255, 255); break; // use a more visual color in dark background
}
SetWindowLong(hDlg, DWL_MSGRESULT, CDRF_NEWFONT);
}
break;
case CDDS_PREPAINT:
SetWindowLong(hDlg, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW);
}
return TRUE;
}
} }
} }
} }
@ -1114,13 +1176,13 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST)); watchIndex = ListView_GetSelectionMark(GetDlgItem(hDlg,IDC_WATCHLIST));
if(watchIndex != -1) if(watchIndex != -1)
{ {
if(rswatches[watchIndex].Size == 'S') return true;
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM)watchIndex); DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM)watchIndex);
SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST));
} }
return true; return true;
case IDC_C_WATCH: case IDC_C_WATCH:
rswatches[WatchCount].Address = rswatches[WatchCount].WrongEndian = 0; rswatches[WatchCount].Address = 0;
rswatches[WatchCount].WrongEndian = 0;
rswatches[WatchCount].Size = 'b'; rswatches[WatchCount].Size = 'b';
rswatches[WatchCount].Type = 's'; rswatches[WatchCount].Type = 's';
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM)WatchCount); DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM)WatchCount);
@ -1134,18 +1196,21 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
rswatches[WatchCount].WrongEndian = rswatches[watchIndex].WrongEndian; rswatches[WatchCount].WrongEndian = rswatches[watchIndex].WrongEndian;
rswatches[WatchCount].Size = rswatches[watchIndex].Size; rswatches[WatchCount].Size = rswatches[watchIndex].Size;
rswatches[WatchCount].Type = rswatches[watchIndex].Type; rswatches[WatchCount].Type = rswatches[watchIndex].Type;
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,(LPARAM) WatchCount); rswatches[WatchCount].comment = strcpy((char*)malloc(strlen(rswatches[watchIndex].comment) + 2), rswatches[watchIndex].comment);
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC) EditWatchProc,WatchCount);
SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST));
} }
return true; return true;
case IDC_C_WATCH_SEPARATE: case IDC_C_WATCH_SEPARATE:
AddressWatcher separator; rswatches[WatchCount].Address = 0;
separator.Address = 0; rswatches[WatchCount].WrongEndian = false;
separator.WrongEndian = false; rswatches[WatchCount].Size = 'S';
separator.Size = 'S'; rswatches[WatchCount].Type = 'S';
separator.Type = 'S';
InsertWatch(separator, "----------------------------"); DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EDITWATCH), hDlg, (DLGPROC)EditWatchProc, (LPARAM)WatchCount);
// InsertWatch(separator, "----------------------------");
SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST)); SetFocus(GetDlgItem(hDlg,IDC_WATCHLIST));
return true; return true;
@ -1245,6 +1310,7 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
} }
UpdateCheatsAdded(); UpdateCheatsAdded();
UpdateCheatWindowRelatedWindow();
} }
} }
break; break;
@ -1287,6 +1353,7 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
case WM_DROPFILES: case WM_DROPFILES:
{ {
char Str_Tmp[1024];
HDROP hDrop = (HDROP)wParam; HDROP hDrop = (HDROP)wParam;
DragQueryFile(hDrop, 0, Str_Tmp, 1024); DragQueryFile(hDrop, 0, Str_Tmp, 1024);
DragFinish(hDrop); DragFinish(hDrop);
@ -1296,3 +1363,10 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
return false; return false;
} }
// TODO: This function may be too slow when both cheats and watches are near the max limit.
void UpdateWatchCheats() {
extern int FCEU_CalcCheatAffectedBytes(uint32, uint32);
for (int i = 0; i < WatchCount; ++i)
rswatches[i].Cheats = FCEU_CalcCheatAffectedBytes(rswatches[i].Address, WatchSizeConv(rswatches[i]));
}

View File

@ -26,6 +26,7 @@ struct AddressWatcher
bool WrongEndian; bool WrongEndian;
char Size; //'d' = 4 bytes, 'w' = 2 bytes, 'b' = 1 byte, and 'S' means it's a separator. char Size; //'d' = 4 bytes, 'w' = 2 bytes, 'b' = 1 byte, and 'S' means it's a separator.
char Type;//'s' = signed integer, 'u' = unsigned, 'h' = hex, 'S' = separator char Type;//'s' = signed integer, 'u' = unsigned, 'h' = hex, 'S' = separator
short Cheats; // how many bytes are affected by cheat
}; };
#define MAX_WATCH_COUNT 256 #define MAX_WATCH_COUNT 256
extern AddressWatcher rswatches[MAX_WATCH_COUNT]; extern AddressWatcher rswatches[MAX_WATCH_COUNT];
@ -41,8 +42,13 @@ bool InsertWatch(const AddressWatcher& Watch, HWND parent=NULL); // asks user fo
void Update_RAM_Watch(); void Update_RAM_Watch();
bool Load_Watches(bool clear, const char* filename); bool Load_Watches(bool clear, const char* filename);
void RWAddRecentFile(const char *filename); void RWAddRecentFile(const char *filename);
void UpdateWatchCheats();
LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK EditWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern HWND RamWatchHWnd; extern HWND RamWatchHWnd;
#define WatchSizeConv(watch) (watch.Type == 'S' ? 0 : watch.Size == 'd' ? 4 : watch.Size == 'w' ? 2 : watch.Size == 'b' ? 1 : 0)
#define SizeConvWatch(size) (size == 4 ? 'd' : size == 2 ? 'w' : size == 1 : 'b' : 0)
#endif #endif

View File

@ -731,6 +731,8 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
case IDYES: case IDYES:
extern void DisableAllCheats(); extern void DisableAllCheats();
DisableAllCheats(); DisableAllCheats();
extern void UpdateCheatWindowRelatedWindow();
UpdateCheatWindowRelatedWindow();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -195,7 +195,6 @@
#define IDD_RAMSEARCH 154 #define IDD_RAMSEARCH 154
#define IDD_RAMWATCH 155 #define IDD_RAMWATCH 155
#define IDD_EDITWATCH 156 #define IDD_EDITWATCH 156
#define IDD_PROMPT 157
#define IDR_RWACCELERATOR 158 #define IDR_RWACCELERATOR 158
#define IDD_LUA 159 #define IDD_LUA 159
#define IDB_BITMAP0 163 #define IDB_BITMAP0 163
@ -789,6 +788,8 @@
#define IDC_AUTOSAVE_PERIOD_MINUTES_TEXT 1307 #define IDC_AUTOSAVE_PERIOD_MINUTES_TEXT 1307
#define IDC_VBLANK_SCANLINES_TEXT 1308 #define IDC_VBLANK_SCANLINES_TEXT 1308
#define IDC_EXTRA_SCANLINES_TEXT 1309 #define IDC_EXTRA_SCANLINES_TEXT 1309
#define IDC_DATASIZE_GROUPBOX 1310
#define IDC_DATATYPE_GROUPBOX 1311
#define MENU_NETWORK 40040 #define MENU_NETWORK 40040
#define MENU_PALETTE 40041 #define MENU_PALETTE 40041
#define MENU_SOUND 40042 #define MENU_SOUND 40042
@ -1282,9 +1283,9 @@
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 302 #define _APS_NEXT_RESOURCE_VALUE 303
#define _APS_NEXT_COMMAND_VALUE 40600 #define _APS_NEXT_COMMAND_VALUE 40600
#define _APS_NEXT_CONTROL_VALUE 1310 #define _APS_NEXT_CONTROL_VALUE 1312
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif