winport:
- add memory viewer features (navigate using a keyboard, toggle view all ASCII chars, saving latest 20 addresses to ini-file, go to address on [ENTER] key hit..)
This commit is contained in:
parent
0567969202
commit
d7b92c0840
|
@ -132,6 +132,9 @@ public:
|
|||
// Refreshes the window. Called by RefreshAllToolWindows().
|
||||
void Refresh() { InvalidateRect(hWnd, NULL, FALSE); }
|
||||
|
||||
// SetFocus
|
||||
void SetFocus() { ::SetFocus(hWnd); }
|
||||
|
||||
// Double-linked toolwindow list.
|
||||
CToolWindow* prev;
|
||||
CToolWindow* next;
|
||||
|
|
|
@ -30,12 +30,15 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
#define MAX_ADDRESS_SAVE 20
|
||||
|
||||
typedef u32 HWAddressType;
|
||||
|
||||
enum RegionType {
|
||||
MEMVIEW_ARM9 = 0,
|
||||
MEMVIEW_ARM7,
|
||||
MEMVIEW_FIRMWARE
|
||||
MEMVIEW_FIRMWARE,
|
||||
MEMVIEW_FULL
|
||||
};
|
||||
|
||||
struct MemViewRegion
|
||||
|
@ -43,7 +46,7 @@ struct MemViewRegion
|
|||
char name[16]; // name of this region (ex. ARM9, region dropdown)
|
||||
char longname[16]; // name of this region (ex. ARM9 memory, window title)
|
||||
HWAddressType hardwareAddress; // hardware address of the start of this region
|
||||
unsigned int size; // number of bytes to the end of this region
|
||||
u32 size; // number of bytes to the end of this region
|
||||
};
|
||||
|
||||
const HWAddressType arm9InitAddress = 0x02000000;
|
||||
|
@ -51,9 +54,13 @@ const HWAddressType arm7InitAddress = 0x02000000;
|
|||
static const MemViewRegion s_arm9Region = { "ARM9", "ARM9 memory", arm9InitAddress, 0x1000000 };
|
||||
static const MemViewRegion s_arm7Region = { "ARM7", "ARM7 memory", arm7InitAddress, 0x1000000 };
|
||||
static const MemViewRegion s_firmwareRegion = { "Firmware", "Firmware", 0x00000000, 0x40000 };
|
||||
static const MemViewRegion s_fullRegion = { "Full", "Full dump", 0x00000000, 0xFFFFFFF0 };
|
||||
|
||||
typedef std::vector<MemViewRegion> MemoryList;
|
||||
static MemoryList s_memoryRegions;
|
||||
static HWND gAddrText = NULL;
|
||||
static LONG_PTR oldEditAddrProc = NULL;
|
||||
static HWND gAddress = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -77,6 +84,9 @@ u8 memRead8 (RegionType regionType, HWAddressType address)
|
|||
case MEMVIEW_FIRMWARE:
|
||||
value = MMU.fw.data[address];
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 1, &value);
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -101,6 +111,9 @@ u16 memRead16 (RegionType regionType, HWAddressType address)
|
|||
case MEMVIEW_FIRMWARE:
|
||||
value = *(u16*)(&MMU.fw.data[address]);
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 2, (u8*)&value);
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -125,6 +138,9 @@ u32 memRead32 (RegionType regionType, HWAddressType address)
|
|||
case MEMVIEW_FIRMWARE:
|
||||
value = *(u32*)(&MMU.fw.data[address]);
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 4, (u8*)&value);
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -225,6 +241,7 @@ CMemView::CMemView()
|
|||
s_memoryRegions.push_back(s_arm9Region);
|
||||
s_memoryRegions.push_back(s_arm7Region);
|
||||
s_memoryRegions.push_back(s_firmwareRegion);
|
||||
s_memoryRegions.push_back(s_fullRegion);
|
||||
}
|
||||
|
||||
PostInitialize();
|
||||
|
@ -239,6 +256,24 @@ CMemView::~CMemView()
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
INT_PTR CALLBACK EditAddrProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case CB_GETDROPPEDSTATE:
|
||||
return 1;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
if (wParam == VK_RETURN)
|
||||
{
|
||||
SendMessage(GetParent(hWnd), WM_COMMAND, IDC_GO, 0);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc((WNDPROC)oldEditAddrProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -277,13 +312,56 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Halfwords");
|
||||
SendMessage(cur, CB_ADDSTRING, 0, (LPARAM)"Words");
|
||||
SendMessage(cur, CB_SETCURSEL, 0, 0);
|
||||
cur = GetDlgItem(hDlg, IDC_ADDRESS);
|
||||
SendMessage(cur, EM_SETLIMITTEXT, 8, 0);
|
||||
|
||||
gAddress = GetDlgItem(hDlg, IDC_ADDRESS);
|
||||
SendMessage(gAddress, EM_SETLIMITTEXT, 8, 0);
|
||||
char addressText[9];
|
||||
wsprintf(addressText, "%08X", wnd->address);
|
||||
SetWindowText(cur, addressText);
|
||||
SetWindowText(gAddress, addressText);
|
||||
SendMessage(gAddress, CB_LIMITTEXT, 8, 0);
|
||||
oldEditAddrProc = SetWindowLongPtr(gAddress, GWLP_WNDPROC, (LONG_PTR)EditAddrProc);
|
||||
|
||||
for (u16 i = 0; i < MAX_ADDRESS_SAVE; i++)
|
||||
{
|
||||
char hex[9] = {0};
|
||||
char buf[9] = {0};
|
||||
|
||||
sprintf(buf, "addr%03d", i);
|
||||
|
||||
u16 len = GetPrivateProfileString("Tools.MemoryViewer", buf, 0, &hex[0], 8, IniName);
|
||||
if (!len) break;
|
||||
|
||||
ComboBox_InsertString(gAddress, 0, hex);
|
||||
}
|
||||
|
||||
gAddrText = GetDlgItem(hDlg, IDC_CURRENT_ADDR);
|
||||
char buf[10] = {0};
|
||||
sprintf(buf, "%08Xh", wnd->address);
|
||||
SetWindowText(gAddrText, buf);
|
||||
|
||||
CheckDlgButton(hDlg, IDC_FULL_CHARS, MF_CHECKED);
|
||||
|
||||
wnd->sel = TRUE;
|
||||
wnd->selAddress = wnd->address;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
wnd->Refresh();
|
||||
wnd->SetFocus();
|
||||
}
|
||||
return 1;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
u16 num = ComboBox_GetCount(gAddress);
|
||||
for (u16 i = 0; i < num; i++)
|
||||
{
|
||||
char hex[9] = {0};
|
||||
char buf[9] = {0};
|
||||
|
||||
sprintf(buf, "addr%03d", i);
|
||||
ComboBox_GetLBText(gAddress, i, (LPCTSTR)&hex[0]);
|
||||
WritePrivateProfileString("Tools.MemoryViewer", buf, hex, IniName);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
|
@ -294,7 +372,7 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
case IDCANCEL:
|
||||
CloseToolWindow(wnd);
|
||||
return 1;
|
||||
|
||||
|
@ -308,13 +386,14 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
SetScrollRange(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, 0x00000000, (region.size - 1) >> 4, TRUE);
|
||||
SetScrollPos(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, 0x00000000, TRUE);
|
||||
|
||||
wnd->sel = FALSE;
|
||||
wnd->selAddress = 0x00000000;
|
||||
wnd->sel = TRUE;
|
||||
wnd->selAddress = wnd->address;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
|
||||
wnd->SetTitle(region.longname);
|
||||
|
||||
wnd->SetFocus();
|
||||
wnd->Refresh();
|
||||
}
|
||||
return 1;
|
||||
|
@ -324,11 +403,12 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
{
|
||||
wnd->viewMode = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||
|
||||
wnd->sel = FALSE;
|
||||
wnd->selAddress = 0x00000000;
|
||||
wnd->sel = TRUE;
|
||||
//wnd->selAddress = 0x00000000;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
|
||||
wnd->SetFocus();
|
||||
wnd->Refresh();
|
||||
}
|
||||
return 1;
|
||||
|
@ -342,7 +422,7 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
BOOL error = FALSE;
|
||||
u32 address = 0x00000000;
|
||||
|
||||
len = GetWindowText(GetDlgItem(hDlg, IDC_ADDRESS), addrstr, 9);
|
||||
len = GetWindowText(gAddress, addrstr, 9);
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
|
@ -367,7 +447,7 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
if(error)
|
||||
{
|
||||
MessageBox(hDlg, "Error:\nInvalid address specified.\nThe address must be an hexadecimal value.", "DeSmuME", (MB_OK | MB_ICONERROR));
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_ADDRESS), "");
|
||||
SetWindowText(gAddress, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -389,15 +469,20 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
region.hardwareAddress = address & 0xFF000000;
|
||||
}
|
||||
HWAddressType addrMin = (region.hardwareAddress) & 0xFFFFFF00;
|
||||
HWAddressType addrMax = max(addrMin, (region.hardwareAddress + region.size - 0x100 - 1) & 0xFFFFFF00);
|
||||
HWAddressType addrMax = max((u32)addrMin, (region.hardwareAddress + region.size - 0x100 - 1) & 0xFFFFFF00);
|
||||
|
||||
wnd->address = max((u32)addrMin, min((u32)addrMax, (address & 0xFFFFFFF0)));
|
||||
|
||||
wnd->sel = FALSE;
|
||||
wnd->selAddress = 0x00000000;
|
||||
wnd->sel = TRUE;
|
||||
wnd->selAddress = wnd->address;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
|
||||
if (ComboBox_GetCount(gAddress) == MAX_ADDRESS_SAVE)
|
||||
ComboBox_DeleteString(gAddress, ComboBox_GetCount(gAddress) - 1);
|
||||
|
||||
ComboBox_InsertString(gAddress, 0, addrstr);
|
||||
|
||||
SetScrollPos(GetDlgItem(hDlg, IDC_MEMVIEWBOX), SB_VERT, (((wnd->address - region.hardwareAddress) >> 4) & 0x000FFFFF), TRUE);
|
||||
wnd->Refresh();
|
||||
}
|
||||
|
@ -549,6 +634,10 @@ INT_PTR CALLBACK MemView_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
|||
case IDC_BIG_ENDIAN:
|
||||
wnd->Refresh();
|
||||
return 1;
|
||||
|
||||
case IDC_FULL_CHARS:
|
||||
wnd->Refresh();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -758,17 +847,37 @@ LRESULT MemView_ViewBoxPaint(CMemView* wnd, HWND hCtl, WPARAM wParam, LPARAM lPa
|
|||
SetBkColor(mem_hdc, RGB(255, 255, 255));
|
||||
SetTextColor(mem_hdc, RGB(0, 0, 0));
|
||||
|
||||
for(i = 0; i < 16; i++)
|
||||
u8 endChar = IsDlgCheckboxChecked(wnd->hWnd, IDC_FULL_CHARS)?0xFF:0x7F;
|
||||
text[1] = 0; bool change = false;
|
||||
|
||||
for(i = 0; i < 16; i++, curx+=fontsize.cx)
|
||||
{
|
||||
u8 val = T1ReadByte(memory, ((line << 4) + i));
|
||||
|
||||
if((val >= 32) && (val <= 127))
|
||||
text[i] = (char)val;
|
||||
if(wnd->sel && wnd->selAddress == (addr + i))
|
||||
{
|
||||
SetBkColor(mem_hdc, GetSysColor(COLOR_HIGHLIGHT));
|
||||
SetTextColor(mem_hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
change = true;
|
||||
}
|
||||
else
|
||||
text[i] = '.';
|
||||
if (change)
|
||||
{
|
||||
SetBkColor(mem_hdc, RGB(255, 255, 255));
|
||||
SetTextColor(mem_hdc, RGB(0, 0, 0));
|
||||
change = false;
|
||||
}
|
||||
|
||||
if((val >= 0x20) && (val <= endChar))
|
||||
text[0] = (char)val;
|
||||
else
|
||||
text[0] = '.';
|
||||
|
||||
TextOut(mem_hdc, curx, cury, text, 1);
|
||||
}
|
||||
text[16] = '\0';
|
||||
TextOut(mem_hdc, curx, cury, text, strlen(text));
|
||||
|
||||
SetBkColor(mem_hdc, RGB(255, 255, 255));
|
||||
SetTextColor(mem_hdc, RGB(0, 0, 0));
|
||||
|
||||
cury += fontsize.cy;
|
||||
}
|
||||
|
@ -780,6 +889,10 @@ LRESULT MemView_ViewBoxPaint(CMemView* wnd, HWND hCtl, WPARAM wParam, LPARAM lPa
|
|||
|
||||
EndPaint(hCtl, &ps);
|
||||
|
||||
char buf[10] = {0};
|
||||
sprintf(buf, "%08Xh", wnd->selAddress);
|
||||
SetWindowText(gAddrText, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -884,6 +997,81 @@ LRESULT CALLBACK MemView_ViewBoxProc(HWND hCtl, UINT uMsg, WPARAM wParam, LPARAM
|
|||
}
|
||||
return 1;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
s16 offset = 0, offset2 = 0;
|
||||
const u8 step[] = {1, 2, 4};
|
||||
MemViewRegion& region = s_memoryRegions[wnd->region];
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_LEFT: offset -= step[wnd->viewMode]; break;
|
||||
case VK_RIGHT: offset += step[wnd->viewMode]; break;
|
||||
case VK_UP: offset -= 16; break;
|
||||
case VK_DOWN: offset += 16; break;
|
||||
case VK_PRIOR: offset -= 0x100; offset2 -= 0x100; break;
|
||||
case VK_NEXT: offset += 0x100; offset2 += 0x100; break;
|
||||
|
||||
case VK_HOME:
|
||||
if (GetKeyState(VK_LCONTROL) || GetKeyState(VK_RCONTROL))
|
||||
{
|
||||
wnd->address = region.hardwareAddress;
|
||||
wnd->selAddress = wnd->address;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
SetScrollPos(hCtl, SB_VERT, 0, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
wnd->selAddress = wnd->address;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_END:
|
||||
if (GetKeyState(VK_LCONTROL) || GetKeyState(VK_RCONTROL))
|
||||
{
|
||||
wnd->address = (region.hardwareAddress + region.size - 0x100);
|
||||
wnd->selAddress = wnd->address;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
SetScrollPos(hCtl, SB_VERT, (region.size - 1) >> 4, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
wnd->selAddress = wnd->address + 0xFF;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
s64 addr = (s64)(wnd->selAddress + offset);
|
||||
s64 addr2 = (s64)(wnd->address + offset2);
|
||||
|
||||
if (addr < region.hardwareAddress) return 1;
|
||||
if (addr2 < region.hardwareAddress) return 1;
|
||||
if (addr >= (region.hardwareAddress + region.size)) return 1;
|
||||
if (addr2 >= (region.hardwareAddress + region.size)) return 1;
|
||||
|
||||
wnd->address = (u32)addr2;
|
||||
wnd->selAddress = (u32)addr;
|
||||
wnd->selPart = 0;
|
||||
wnd->selNewVal = 0x00000000;
|
||||
|
||||
if (wnd->selAddress < wnd->address)
|
||||
wnd->address -= 16;
|
||||
if (wnd->selAddress >= wnd->address + 0x100)
|
||||
wnd->address += 16;
|
||||
|
||||
SetScrollPos(hCtl, SB_VERT, (wnd->address - region.hardwareAddress) >> 4, TRUE);
|
||||
wnd->Refresh();
|
||||
}
|
||||
return 1;
|
||||
|
||||
case WM_CHAR:
|
||||
{
|
||||
char ch = (char)wParam;
|
||||
|
@ -924,7 +1112,7 @@ LRESULT CALLBACK MemView_ViewBoxProc(HWND hCtl, UINT uMsg, WPARAM wParam, LPARAM
|
|||
{
|
||||
MemViewRegion& region = s_memoryRegions[wnd->region];
|
||||
HWAddressType addrMin = (region.hardwareAddress) & 0xFFFFFF00;
|
||||
HWAddressType addrMax = max(addrMin, (region.hardwareAddress + region.size - 0x100 - 1) & 0xFFFFFF00);
|
||||
HWAddressType addrMax = max((u32)addrMin, (region.hardwareAddress + region.size - 0x100 - 1) & 0xFFFFFF00);
|
||||
if (wnd->address + 0x10 <= addrMax)
|
||||
{
|
||||
wnd->address += 0x10;
|
||||
|
|
|
@ -434,7 +434,9 @@
|
|||
#define IDC_IMP_AUTO_ADVANSCENE 1054
|
||||
#define IDC_JIT_BLOCK_SIZE 1054
|
||||
#define IDC_SDEVELOPER 1054
|
||||
#define IDC_CURRENT_ADDR 1054
|
||||
#define IDC_IMP_MANUAL 1055
|
||||
#define IDC_FULL_CHARS 1055
|
||||
#define IDC_LIST1 1056
|
||||
#define IDC_IMP_INFO_CURRENT 1056
|
||||
#define IDC_BADD_AR 1057
|
||||
|
@ -1021,7 +1023,7 @@
|
|||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 128
|
||||
#define _APS_NEXT_COMMAND_VALUE 40108
|
||||
#define _APS_NEXT_CONTROL_VALUE 1054
|
||||
#define _APS_NEXT_CONTROL_VALUE 1056
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue