Ram search show cheat count in current range.

This commit is contained in:
owomomo 2019-01-09 17:28:05 +08:00
parent a5572c1b06
commit 9407df7d2c
9 changed files with 120 additions and 57 deletions

View File

@ -60,26 +60,8 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
} }
struct CHEATF { CHEATF_SUBFAST SubCheats[256];
struct CHEATF *next; int numsubcheats=0;
char *name;
uint16 addr;
uint8 val;
int compare; /* -1 for no compare. */
int type; /* 0 for replace, 1 for substitute(GG). */
int status;
};
typedef struct {
uint16 addr;
uint8 val;
int compare;
readfunc PrevRead;
} CHEATF_SUBFAST;
static CHEATF_SUBFAST SubCheats[256];
static int numsubcheats=0;
struct CHEATF *cheats=0,*cheatsl=0; struct CHEATF *cheats=0,*cheatsl=0;

View File

@ -11,4 +11,21 @@ void FCEU_CheatSetByte(uint32 A, uint8 V);
extern int savecheats; extern int savecheats;
int FCEU_DisableAllCheats(); int FCEU_DisableAllCheats();
typedef struct {
uint16 addr;
uint8 val;
int compare;
readfunc PrevRead;
} CHEATF_SUBFAST;
struct CHEATF {
struct CHEATF *next;
char *name;
uint16 addr;
uint8 val;
int compare; /* -1 for no compare. */
int type; /* 0 for replace, 1 for substitute(GG). */
int status;
};

View File

@ -578,8 +578,8 @@ void PopulateMappingDisplay(HWND hwndDlg)
else else
listView.iSubItem = mapInputSortCol; listView.iSubItem = mapInputSortCol;
SendMessage(hwndListView, LVM_SORTITEMS, (WPARAM)&listView, (LPARAM)ItemSortFunc); int ret = SendMessage(hwndListView, LVM_SORTITEMS, (WPARAM)&listView, (LPARAM)MapInputItemSortFunc);
UpdateSortColumnIcon(hwndListView); UpdateSortColumnIcon(hwndListView, mapInputSortCol, mapInputSortAsc);
} }
} }
@ -811,8 +811,8 @@ BOOL CALLBACK MapInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
else else
lpListView->iSubItem = mapInputSortCol; lpListView->iSubItem = mapInputSortCol;
SendMessage(hwndListView, LVM_SORTITEMS, (WPARAM)lpListView, (LPARAM)ItemSortFunc); int ret = SendMessage(hwndListView, LVM_SORTITEMS, (WPARAM)lpListView, (LPARAM)MapInputItemSortFunc);
UpdateSortColumnIcon(hwndListView); UpdateSortColumnIcon(hwndListView, mapInputSortCol, mapInputSortAsc);
} }
return TRUE; return TRUE;
} }
@ -846,7 +846,7 @@ void MapInput(void)
free(backupmapping); free(backupmapping);
} }
int CALLBACK ItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort) static int CALLBACK MapInputItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort)
{ {
NMLISTVIEW* lpListView = (NMLISTVIEW*)lpSort; NMLISTVIEW* lpListView = (NMLISTVIEW*)lpSort;
HWND hwndListView = lpListView->hdr.hwndFrom; HWND hwndListView = lpListView->hdr.hwndFrom;
@ -894,21 +894,3 @@ int CALLBACK ItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort)
return ret; return ret;
} }
int UpdateSortColumnIcon(HWND hwndListView)
{
HWND header = (HWND)SendMessage(hwndListView, LVM_GETHEADER, 0, 0);
for (int i = SendMessage(header, HDM_GETITEMCOUNT, 0, 0) - 1; i >= 0; --i)
{
HDITEM hdItem = { 0 };
hdItem.mask = HDI_FORMAT;
if (SendMessage(header, HDM_GETITEM, i, (LPARAM)&hdItem))
{
hdItem.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN);
if (i == mapInputSortCol)
hdItem.fmt |= mapInputSortAsc ? HDF_SORTUP : HDF_SORTDOWN;
SendMessage(header, HDM_SETITEM, i, (LPARAM)&hdItem);
}
}
return 0;
}

View File

@ -1,6 +1,6 @@
#ifndef WIN_MAPINPUT_h #ifndef WIN_MAPINPUT_h
#define WIN_MAPINPUT_h #define WIN_MAPINPUT_h
char* GetKeyComboName(int c); char* GetKeyComboName(int c);
int CALLBACK ItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort); static int CALLBACK MapInputItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort);
int UpdateSortColumnIcon(HWND hwndListView); void UpdateSortColumnIcon(HWND hwndListView, int sortColumn, bool sortAsc);
#endif #endif

View File

@ -29,6 +29,7 @@
#include "common.h" #include "common.h"
#include "fceu.h" #include "fceu.h"
#include "../../debug.h" #include "../../debug.h"
#include "../../cheat.h"
#include "resource.h" #include "resource.h"
#include "ram_search.h" #include "ram_search.h"
@ -48,6 +49,17 @@
bool ShowROM = false; bool ShowROM = false;
// Too much work to do for resorting the values, and finding the biggest number
// by sorting in ram list doesn't help too much in usually use, so I gave it up.
// whitch column does the sort based on, the default status is 0 which means sorted by address
// static int ramSearchSortCol = 0;
// whether it's asc or desc sorting
// static bool ramSearchSortAsc = true;
// used for changing colors of cheated address.
extern int numsubcheats;
extern CHEATF_SUBFAST SubCheats[256];
bool IsHardwareAddressValid(HWAddressType address) bool IsHardwareAddressValid(HWAddressType address)
{ {
if (!GameInfo) if (!GameInfo)
@ -73,6 +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.
}; };
int MAX_RAM_SIZE = 0; int MAX_RAM_SIZE = 0;
@ -169,6 +182,19 @@ void ResetMemoryRegions()
LeaveCriticalSection(&s_activeMemoryRegionsCS); LeaveCriticalSection(&s_activeMemoryRegionsCS);
} }
/* currently not used, only virtual region is to show the cheat status
void UpdateMemoryCheatStatus()
{
EnterCriticalSection(&s_activeMemoryRegionsCS);
for (MemoryList::iterator iter = s_activeMemoryRegions.begin(); iter != s_activeMemoryRegions.end(); ++iter)
{
MemoryRegion& region = *iter;
UpdateRegionCheatStatus(region);
}
LeaveCriticalSection(&s_activeMemoryRegionsCS);
}
*/
// eliminates a range of hardware addresses from the search results // eliminates a range of hardware addresses from the search results
// returns 2 if it changed the region and moved the iterator to another region // returns 2 if it changed the region and moved the iterator to another region
// returns 1 if it changed the region but didn't move the iterator // returns 1 if it changed the region but didn't move the iterator
@ -249,7 +275,7 @@ void CalculateItemIndices(int itemSize)
int startSkipSize = ((unsigned int)(itemSize - (unsigned int)region.hardwareAddress)) % itemSize; // FIXME: is this still ok? int startSkipSize = ((unsigned int)(itemSize - (unsigned int)region.hardwareAddress)) % itemSize; // FIXME: is this still ok?
unsigned int start = startSkipSize; unsigned int start = startSkipSize;
unsigned int end = region.size; unsigned int end = region.size;
for(unsigned int i = start; i < end; i += itemSize) for (unsigned int i = start; i < end; i += itemSize)
s_itemIndexToRegionPointer[itemIndex++] = &region; s_itemIndexToRegionPointer[itemIndex++] = &region;
} }
s_maxItemIndex = itemIndex; s_maxItemIndex = itemIndex;
@ -397,7 +423,11 @@ void ItemIndexToVirtualRegion(unsigned int itemIndex, MemoryRegion& virtualRegio
virtualRegion.hardwareAddress = region.hardwareAddress + bytesWithinRegion; virtualRegion.hardwareAddress = region.hardwareAddress + bytesWithinRegion;
virtualRegion.virtualIndex = region.virtualIndex + bytesWithinRegion; virtualRegion.virtualIndex = region.virtualIndex + bytesWithinRegion;
virtualRegion.itemIndex = itemIndex; virtualRegion.itemIndex = itemIndex;
return;
region.cheatAffect = 0;
for (int i = 0; i < numsubcheats; i++)
if (SubCheats[i].addr >= region.hardwareAddress && SubCheats[i].addr < region.hardwareAddress + region.size)
++region.cheatAffect;
} }
template<typename stepType, typename compareType> template<typename stepType, typename compareType>
@ -464,6 +494,13 @@ unsigned int GetHardwareAddressFromItemIndex(unsigned int itemIndex)
ItemIndexToVirtualRegion<stepType,compareType>(itemIndex, virtualRegion); ItemIndexToVirtualRegion<stepType,compareType>(itemIndex, virtualRegion);
return virtualRegion.hardwareAddress; return virtualRegion.hardwareAddress;
} }
template<typename stepType, typename compareType>
unsigned int GetCheatStatusFromItemIndex(unsigned int itemIndex)
{
MemoryRegion virtualRegion;
ItemIndexToVirtualRegion<stepType, compareType>(itemIndex, virtualRegion);
return virtualRegion.cheatAffect;
}
// this one might be unreliable, haven't used it much // this one might be unreliable, haven't used it much
template<typename stepType, typename compareType> template<typename stepType, typename compareType>
@ -987,6 +1024,7 @@ void soft_reset_address_info ()
}*/ }*/
s_prevValuesNeedUpdate = false; s_prevValuesNeedUpdate = false;
ResetMemoryRegions(); ResetMemoryRegions();
// UpdateMemoryCheatStatus();
if(!RamSearchHWnd) if(!RamSearchHWnd)
{ {
EnterCriticalSection(&s_activeMemoryRegionsCS); EnterCriticalSection(&s_activeMemoryRegionsCS);
@ -1015,6 +1053,7 @@ void reset_address_info ()
memcpy(s_prevValues, s_curValues, (sizeof(*s_prevValues)*(MAX_RAM_SIZE))); memcpy(s_prevValues, s_curValues, (sizeof(*s_prevValues)*(MAX_RAM_SIZE)));
s_prevValuesNeedUpdate = false; s_prevValuesNeedUpdate = false;
ResetMemoryRegions(); ResetMemoryRegions();
// UpdateMemoryCheatStatus();
if(!RamSearchHWnd) if(!RamSearchHWnd)
{ {
EnterCriticalSection(&s_activeMemoryRegionsCS); EnterCriticalSection(&s_activeMemoryRegionsCS);
@ -1374,7 +1413,6 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
RECT r2; RECT r2;
int dx1, dy1, dx2, dy2; int dx1, dy1, dx2, dy2;
static int watchIndex=0; static int watchIndex=0;
switch(uMsg) switch(uMsg)
{ {
case WM_INITDIALOG: { case WM_INITDIALOG: {
@ -1481,8 +1519,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[] = {"Address","Value","Previous","Changes"}; const char* names[5] = {"Addr.","Value","Previous","Changes","Cheats"};
int widths[4] = {68,76,76,68}; int widths[5] = {48,80,80,66,52};
if (!ResultCount) if (!ResultCount)
reset_address_info(); reset_address_info();
else else
@ -1491,7 +1529,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,4,widths); init_list_box(GetDlgItem(hDlg,IDC_RAMLIST),names,5,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);
@ -1516,7 +1554,6 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
return true; return true;
} break; } break;
case WM_NOTIFY: case WM_NOTIFY:
{ {
LPNMHDR lP = (LPNMHDR) lParam; LPNMHDR lP = (LPNMHDR) lParam;
@ -1589,6 +1626,12 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
Item->item.pszText = num; Item->item.pszText = num;
} return true; } return true;
case 4:
{
int cheat = CALL_WITH_T_SIZE_TYPES_1(GetCheatStatusFromItemIndex, rs_type_size, rs_t=='s', noMisalign, iNum);
sprintf(num, "%d", cheat);
Item->item.pszText = num;
}
//case 4: //case 4:
// Item->item.pszText = rsaddrs[rsresults[iNum].Index].comment ? rsaddrs[rsresults[iNum].Index].comment : ""; // Item->item.pszText = rsaddrs[rsresults[iNum].Index].comment ? rsaddrs[rsresults[iNum].Index].comment : "";
// return true; // return true;
@ -1596,7 +1639,23 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
return false; return false;
} }
} }
/*
Too much work to do for resorting the values, and finding the biggest number
by sorting in ram list doesn't help too much in usually use, so I gave it up.
case LVN_COLUMNCLICK:
{
NMLISTVIEW* pNMListView = (NMLISTVIEW*)lParam;
if (ramSearchSortCol != pNMListView->iSubItem) {
ramSearchSortCol = pNMListView->iSubItem;
ramSearchSortAsc = true;
}
else
ramSearchSortAsc = !ramSearchSortAsc;
UpdateSortColumnIcon(pNMListView->hdr.hwndFrom, ramSearchSortCol, ramSearchSortAsc);
break;
}
*/
case NM_RCLICK: case NM_RCLICK:
{ {
// go to the address in Hex Editor // go to the address in Hex Editor
@ -1610,6 +1669,7 @@ LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
break; break;
} }
//case LVN_ODCACHEHINT: //Copied this bit from the MSDN virtual listbox code sample. Eventually it should probably do something. //case LVN_ODCACHEHINT: //Copied this bit from the MSDN virtual listbox code sample. Eventually it should probably do something.
//{ //{
// LPNMLVCACHEHINT lpCacheHint = (LPNMLVCACHEHINT)lParam; // LPNMLVCACHEHINT lpCacheHint = (LPNMLVCACHEHINT)lParam;
@ -2116,7 +2176,7 @@ 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_CENTER; Col.fmt = LVCFMT_RIGHT;
for (int i = 0; i < numColumns; i++) for (int i = 0; i < numColumns; i++)
{ {
Col.iOrder = i; Col.iOrder = i;

View File

@ -32,4 +32,9 @@ void DoRamSearchOperation(); //Perform a search
extern HWND RamSearchHWnd; extern HWND RamSearchHWnd;
extern LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); extern LRESULT CALLBACK RamSearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Too much work to do for resorting the values, and finding the biggest number
// by sorting in ram list doesn't help too much in usually use, so I gave it up.
// static int CALLBACK RamSearchItemSortFunc(LPARAM lp1, LPARAM lp2, LPARAM lpSort);
// extern void UpdateSortColumnIcon(HWND hwndListView, int sortColumn, bool sortAsc);
#endif #endif

View File

@ -1449,7 +1449,7 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_
CAPTION " RAM Search" CAPTION " RAM Search"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
CONTROL "",IDC_RAMLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,9,9,214,151,WS_EX_CLIENTEDGE CONTROL "",IDC_RAMLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,9,9,214,151,WS_EX_CLIENTEDGE
PUSHBUTTON "&Search",IDC_C_SEARCH,226,9,52,16 PUSHBUTTON "&Search",IDC_C_SEARCH,226,9,52,16
PUSHBUTTON "&Add Cheat",IDC_C_ADDCHEAT,226,130,52,14,WS_DISABLED PUSHBUTTON "&Add Cheat",IDC_C_ADDCHEAT,226,130,52,14,WS_DISABLED
PUSHBUTTON "&Watch",IDC_C_WATCH,226,114,52,14 PUSHBUTTON "&Watch",IDC_C_WATCH,226,114,52,14

View File

@ -3159,7 +3159,7 @@ void OpenRamSearch()
if (GameInfo) if (GameInfo)
{ {
reset_address_info(); reset_address_info();
RamSearchHWnd = CreateDialog(fceu_hInstance, MAKEINTRESOURCE(IDD_RAMSEARCH), MainhWnd, (DLGPROC) RamSearchProc); RamSearchHWnd = CreateDialog(fceu_hInstance, MAKEINTRESOURCE(IDD_RAMSEARCH), MainhWnd, (DLGPROC)RamSearchProc);
} }
} }
@ -3194,4 +3194,22 @@ void SaveSnapshotAs()
if(GetSaveFileName(&ofn)) if(GetSaveFileName(&ofn))
FCEUI_SetSnapshotAsName(nameo); FCEUI_SetSnapshotAsName(nameo);
FCEUI_SaveSnapshotAs(); FCEUI_SaveSnapshotAs();
}
void UpdateSortColumnIcon(HWND hwndListView, int sortColumn, bool sortAsc)
{
HWND header = (HWND)SendMessage(hwndListView, LVM_GETHEADER, 0, 0);
for (int i = SendMessage(header, HDM_GETITEMCOUNT, 0, 0) - 1; i >= 0; --i)
{
HDITEM hdItem = { 0 };
hdItem.mask = HDI_FORMAT;
if (SendMessage(header, HDM_GETITEM, i, (LPARAM)&hdItem))
{
hdItem.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN);
if (i == sortColumn)
hdItem.fmt |= sortAsc ? HDF_SORTUP : HDF_SORTDOWN;
SendMessage(header, HDM_SETITEM, i, (LPARAM)&hdItem);
}
}
} }

View File

@ -126,5 +126,4 @@ struct HOTKEYMENUINDEX {
void UpdateMenuHotkeys(FCEUMENU_INDEX index); void UpdateMenuHotkeys(FCEUMENU_INDEX index);
int GetCurrentContextIndex(); int GetCurrentContextIndex();
#endif #endif