diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 331126a00e3d..4dda0822e1b9 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -2,14 +2,13 @@ #include #include - +#include #include "Core/Config.h" #include "Windows/resource.h" #include "Core/MemMap.h" #include "Windows/W32Util/Misc.h" #include "Windows/InputBox.h" #include "Windows/main.h" -#include "Core/Debugger/SymbolMap.h" #include "base/display.h" #include "Debugger_Disasm.h" @@ -174,8 +173,6 @@ CtrlMemView *CtrlMemView::getFrom(HWND hwnd) } - - void CtrlMemView::onPaint(WPARAM wParam, LPARAM lParam) { auto memLock = Memory::Lock(); @@ -634,14 +631,49 @@ void CtrlMemView::scrollCursor(int bytes) redraw(); } + +std::vector CtrlMemView::searchString(std::string searchQuery) +{ + std::vector searchResAddrs; + std::vector searchData; + + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return searchResAddrs; + + size_t queryLength = searchQuery.length(); + u32 segmentStart = PSP_GetKernelMemoryBase(); //RAM start + const u32 segmentEnd = PSP_GetUserMemoryEnd() - (u32)queryLength; //RAM end + u8* ptr; + + redraw(); + for (segmentStart = PSP_GetKernelMemoryBase(); segmentStart < segmentEnd; segmentStart++) { + if (KeyDownAsync(VK_ESCAPE)) + { + return searchResAddrs; + } + + ptr = Memory::GetPointer(segmentStart); + if (memcmp(ptr, searchQuery.c_str(), queryLength) == 0) { + searchResAddrs.push_back(segmentStart); + } + }; + redraw(); + + return searchResAddrs; +}; + void CtrlMemView::search(bool continueSearch) { auto memLock = Memory::Lock(); if (!PSP_IsInited()) return; - u32 searchAddress; - if (continueSearch == false || searchQuery[0] == 0) + u32 searchAddress = 0; + u32 segmentStart = 0; + u32 segmentEnd = 0; + u8* dataPointer = 0; + if (continueSearch == false || searchQuery.empty()) { if (InputBox_GetString(GetModuleHandle(NULL),wnd,L"Search for", "",searchQuery) == false) { @@ -673,7 +705,7 @@ void CtrlMemView::search(bool continueSearch) } u8 value = 0; - for (int i = 0; i < 2; i++) + for (int i = 0; i < 2 && index < searchQuery.size(); i++) { char c = tolower(searchQuery[index++]); if (c >= 'a' && c <= 'f') @@ -693,35 +725,32 @@ void CtrlMemView::search(bool continueSearch) } std::vector> memoryAreas; - memoryAreas.push_back(std::pair(0x04000000,0x04200000)); - memoryAreas.push_back(std::pair(0x08000000,0x0A000000)); + memoryAreas.push_back(std::pair(0x04000000, 0x04200000)); + memoryAreas.push_back(std::pair(0x08000000, 0x0A000000)); searching = true; redraw(); // so the cursor is disabled - for (size_t i = 0; i < memoryAreas.size(); i++) - { - u32 segmentStart = memoryAreas[i].first; - u32 segmentEnd = memoryAreas[i].second; - u8* dataPointer = Memory::GetPointer(segmentStart); + + for (size_t i = 0; i < memoryAreas.size(); i++) { + segmentStart = memoryAreas[i].first; + segmentEnd = memoryAreas[i].second; + + dataPointer = Memory::GetPointer(segmentStart); if (dataPointer == NULL) continue; // better safe than sorry, I guess if (searchAddress < segmentStart) searchAddress = segmentStart; if (searchAddress >= segmentEnd) continue; int index = searchAddress-segmentStart; - int endIndex = segmentEnd-segmentStart-(int)searchData.size(); + int endIndex = segmentEnd-segmentStart - (int)searchData.size(); - while (index < endIndex) - { + while (index < endIndex) { // cancel search - if ((index % 256) == 0 && KeyDownAsync(VK_ESCAPE)) - { + if ((index % 256) == 0 && KeyDownAsync(VK_ESCAPE)) { searching = false; return; } - - if (memcmp(&dataPointer[index],searchData.data(),searchData.size()) == 0) - { + if (memcmp(&dataPointer[index], searchData.data(), searchData.size()) == 0) { matchAddress = index+segmentStart; searching = false; gotoAddr(matchAddress); @@ -746,17 +775,15 @@ void CtrlMemView::drawOffsetScale(HDC hdc) currentX = addressStart + ((8 + 1)*charWidth); // the start offset, the size of the hex addresses and one space char temp[64]; - for (int i = 0; i < 16; i++) { sprintf(temp, "%02X", i); TextOutA(hdc, currentX, offsetPositionY, temp, 2); currentX += 3 * charWidth; // hex and space } - } -void CtrlMemView::toggleOffsetScale(OffsetToggles toggle) +void CtrlMemView::toggleOffsetScale(CommonToggles toggle) { if (toggle == On) displayOffsetScale = true; diff --git a/Windows/Debugger/CtrlMemView.h b/Windows/Debugger/CtrlMemView.h index d5f8079d7fb1..44ab3bcdf02b 100644 --- a/Windows/Debugger/CtrlMemView.h +++ b/Windows/Debugger/CtrlMemView.h @@ -24,7 +24,7 @@ enum OffsetSpacing { offsetLine = 1, // the line on which the offsets should be written }; -enum OffsetToggles { +enum CommonToggles { On, Off, }; @@ -54,8 +54,11 @@ class CtrlMemView int visibleRows; std::string searchQuery; + + int matchAddress; bool searching; + bool searchStringValue; bool hasFocus; static wchar_t szClassName[]; @@ -78,7 +81,7 @@ class CtrlMemView { return debugger; } - + std::vector searchString(std::string searchQuery); void onPaint(WPARAM wParam, LPARAM lParam); void onVScroll(WPARAM wParam, LPARAM lParam); void onKeyDown(WPARAM wParam, LPARAM lParam); @@ -94,5 +97,6 @@ class CtrlMemView void scrollCursor(int bytes); void drawOffsetScale(HDC hdc); - void toggleOffsetScale(OffsetToggles toggle); -}; \ No newline at end of file + void toggleOffsetScale(CommonToggles toggle); + void toggleStringSearch(CommonToggles toggle); +}; diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index dd4a3b91ce9b..c2bcd0d18f89 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -13,11 +13,15 @@ #include "Debugger_MemoryDlg.h" #include "CtrlMemView.h" #include "DebuggerShared.h" +#include "LogManager.h" +#include "winnt.h" +#include +#include -RECT CMemoryDlg::slRect; +RECT CMemoryDlg::slRect; //sym list rect -FAR WNDPROC DefAddressEditProc; +FAR WNDPROC DefAddressEditProc; HWND AddressEditParentHwnd = 0; LRESULT CALLBACK AddressEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) @@ -58,22 +62,30 @@ CMemoryDlg::CMemoryDlg(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu SetWindowText(m_hDlg,temp); ShowWindow(m_hDlg,SW_HIDE); - CtrlMemView *ptr = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); - ptr->setDebugger(_cpu); + + memViewHdl = GetDlgItem(m_hDlg, IDC_MEMVIEW); + symListHdl = GetDlgItem(m_hDlg, IDC_SYMBOLS); + searchBoxHdl = GetDlgItem(m_hDlg, IDC_SEARCH_BOX); + srcListHdl = GetDlgItem(m_hDlg, IDC_SEARCH_RESULTS); + + memView = CtrlMemView::getFrom(memViewHdl); + memView->setDebugger(_cpu); Button_SetCheck(GetDlgItem(m_hDlg,IDC_RAM), TRUE); Button_SetCheck(GetDlgItem(m_hDlg,IDC_MODESYMBOLS), TRUE); - GetWindowRect(GetDlgItem(m_hDlg,IDC_SYMBOLS),&slRect); + GetWindowRect(symListHdl, &slRect); + GetWindowRect(srcListHdl, &srRect); + // subclass the edit box - HWND editWnd = GetDlgItem(m_hDlg,IDC_ADDRESS); + editWnd = GetDlgItem(m_hDlg,IDC_ADDRESS); DefAddressEditProc = (WNDPROC)GetWindowLongPtr(editWnd,GWLP_WNDPROC); SetWindowLongPtr(editWnd,GWLP_WNDPROC,(LONG_PTR)AddressEditProc); AddressEditParentHwnd = m_hDlg; Size(); -} +} CMemoryDlg::~CMemoryDlg(void) @@ -84,22 +96,32 @@ void CMemoryDlg::Update(void) { if (m_hDlg != NULL) { - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); - if (mv != NULL) - mv->redraw(); + if (memView != NULL) + memView->redraw(); } } +void CMemoryDlg::searchBoxRedraw(std::vector results) { + wchar_t temp[256]{}; + SendMessage(srcListHdl, WM_SETREDRAW, FALSE, 0); + ListBox_ResetContent(srcListHdl); + for (int i = 0; i < results.size(); i++) { + wsprintf(temp, L"0x%08X", results[i]); + int index = (int)ListBox_AddString(srcListHdl, temp); + ListBox_SetItemData(srcListHdl, index, results[i]); + } + SendMessage(srcListHdl, WM_SETREDRAW, TRUE, 0); + RedrawWindow(srcListHdl, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); +} + + void CMemoryDlg::NotifyMapLoaded() { if (m_hDlg) { - HWND list = GetDlgItem(m_hDlg,IDC_SYMBOLS); - if (g_symbolMap) - g_symbolMap->FillSymbolListBox(list, ST_DATA); - HWND lb = GetDlgItem(m_hDlg,IDC_REGIONS); - int sel = ComboBox_GetCurSel(lb); - ComboBox_ResetContent(lb); + g_symbolMap->FillSymbolListBox(symListHdl,ST_DATA); + int sel = ComboBox_GetCurSel(memViewHdl); + ComboBox_ResetContent(memViewHdl); /* for (int i = 0; i < cpu->getMemMap()->numRegions; i++) { @@ -107,84 +129,91 @@ void CMemoryDlg::NotifyMapLoaded() int n = ComboBox_AddString(lb,cpu->getMemMap()->regions[i].name); ComboBox_SetItemData(lb,n,cpu->getMemMap()->regions[i].start); }*/ - ComboBox_SetCurSel(lb,sel>=0?sel:0); + ComboBox_SetCurSel(memViewHdl,sel>=0?sel:0); } Update(); } - BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { - - switch(message) - { - case WM_COMMAND: - { - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); - switch (LOWORD(wParam)) - { - case IDC_REGIONS: - switch (HIWORD(wParam)) - { - case LBN_DBLCLK: - { - HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam)); - int n = ComboBox_GetCurSel(lb); - if (n!=-1) - { - unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n); - mv->gotoAddr(addr); - } + switch(message){ + case WM_COMMAND:{ + HWND lb = GetDlgItem(m_hDlg, LOWORD(wParam)); + switch (LOWORD(wParam)){ + case IDC_REGIONS: + switch (HIWORD(wParam)) { + case LBN_DBLCLK:{ + int n = ComboBox_GetCurSel(lb); + if (n != -1) { + unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n); + memView->gotoAddr(addr); } - break; - }; + } break; - case IDC_SYMBOLS: - switch (HIWORD(wParam)) - { - case LBN_DBLCLK: - { - - HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam)); - int n = ListBox_GetCurSel(lb); - if (n!=-1) - { - unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n); - mv->gotoAddr(addr); - } + }; + break; + case IDC_SYMBOLS: + switch (HIWORD(wParam)) { + case LBN_DBLCLK:{ + int n = ListBox_GetCurSel(lb); + if (n != -1) { + unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n); + memView->gotoAddr(addr); + } + } + break; + }; + case IDC_SEARCH_RESULTS: + switch (HIWORD(wParam)) { + case LBN_DBLCLK: { + int n = ListBox_GetCurSel(lb); + if (n != -1) { + unsigned int addr = (unsigned int)ListBox_GetItemData(lb, n); + memView->gotoAddr(addr); } - break; - }; + } + break; + }; + break; + case IDC_SHOWOFFSETS: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + if (SendDlgItemMessage(m_hDlg, IDC_SHOWOFFSETS, BM_GETCHECK, 0, 0)) + memView->toggleOffsetScale(On); + else + memView->toggleOffsetScale(Off); break; - case IDC_SHOWOFFSETS: - switch (HIWORD(wParam)) - { - case BN_CLICKED: - if (SendDlgItemMessage(m_hDlg, IDC_SHOWOFFSETS, BM_GETCHECK, 0, 0)) - mv->toggleOffsetScale(On); - else - mv->toggleOffsetScale(Off); - break; + } + break; + case IDC_BUTTON_SEARCH: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + wchar_t temp[256]; + GetWindowText(searchBoxHdl, temp, 255); + std::vector results = memView->searchString(ConvertWStringToUTF8(temp).c_str()); + if (results.size() > 0){ + searchBoxRedraw(results); } break; } } + } break; case WM_DEB_MAPLOADED: NotifyMapLoaded(); break; - case WM_DEB_GOTOADDRESSEDIT: - { - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); + case WM_DEB_GOTOADDRESSEDIT:{ wchar_t temp[256]; u32 addr; - GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),temp,255); + GetWindowText(editWnd,temp,255); if (parseExpression(ConvertWStringToUTF8(temp).c_str(),cpu,addr) == false) { displayExpressionError(m_hDlg); } else { - mv->gotoAddr(addr); - SetFocus(GetDlgItem(m_hDlg,IDC_MEMVIEW)); + memView->gotoAddr(addr); + SetFocus(memViewHdl); } break; } @@ -198,6 +227,7 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) return TRUE; } break; + case WM_SIZE: Size(); break; @@ -212,9 +242,8 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) void CMemoryDlg::Goto(u32 addr) { Show(true); - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW)); - mv->gotoAddr(addr); - SetFocus(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW)); + memView->gotoAddr(addr); + SetFocus(memViewHdl); } @@ -222,15 +251,17 @@ void CMemoryDlg::Size() { const float fontScale = 1.0f / g_dpi_scale_real_y; - RECT rc; - GetClientRect(m_hDlg,&rc); - int dw=rc.right-rc.left; - int dh=rc.bottom-rc.top; - HWND memView = GetDlgItem(m_hDlg, IDC_MEMVIEW); - HWND symList = GetDlgItem(m_hDlg, IDC_SYMBOLS); + GetClientRect(m_hDlg,&winRect); + int dlg_w = winRect.right - winRect.left; + int dlg_h = winRect.bottom - winRect.top; + + int wf = slRect.right-slRect.left; - int w = dw - 3 * fontScale - wf; + int w = dlg_w - 3 * fontScale - wf*2; int top = 48 * fontScale; - MoveWindow(symList,0,top,wf,dh-top,TRUE); - MoveWindow(memView,wf+4,top,w,dh-top,TRUE); + int height = dlg_h - top; + //HWND, X, Y, width, height, repaint + MoveWindow(symListHdl, 0 ,top, wf, height, TRUE); + MoveWindow(memViewHdl, wf+4 ,top, w, height, TRUE); + MoveWindow(srcListHdl, wf + 4 + w+ 4, top, wf-4, height, TRUE); } diff --git a/Windows/Debugger/Debugger_MemoryDlg.h b/Windows/Debugger/Debugger_MemoryDlg.h index d8e2c5fef454..91bf07e9864c 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.h +++ b/Windows/Debugger/Debugger_MemoryDlg.h @@ -6,7 +6,7 @@ #include "Core/MemMap.h" #include "Core/Debugger/DebugInterface.h" - +#include "CtrlMemView.h" #include "Common/CommonWindows.h" class CMemoryDlg : public Dialog @@ -14,11 +14,16 @@ class CMemoryDlg : public Dialog private: DebugInterface *cpu; static RECT slRect; - + RECT winRect, srRect; + CtrlMemView *memView; + HWND memViewHdl, symListHdl, editWnd, searchBoxHdl, srcListHdl; BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam); + public: int index; //helper + void searchBoxRedraw(std::vector results); + // constructor CMemoryDlg(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu); @@ -29,6 +34,8 @@ class CMemoryDlg : public Dialog void Update(void); void NotifyMapLoaded(); + void NotifySearchCompleted(); + void Size(void); }; diff --git a/Windows/InputBox.cpp b/Windows/InputBox.cpp index f3aebb85827f..d661e39a9c56 100644 --- a/Windows/InputBox.cpp +++ b/Windows/InputBox.cpp @@ -108,10 +108,10 @@ bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, co return false; } -bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue) +bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t* title, u32 defaultvalue, u32& outvalue) { wchar_t temp[256]; - wsprintf(temp,L"%08x",defaultvalue); + wsprintf(temp, L"%08x", defaultvalue); textBoxContents = temp; INT_PTR value = DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc); @@ -124,9 +124,9 @@ bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 de return true; return false; } - else + else { outvalue = 0; return false; } -} \ No newline at end of file +} diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 99da8d11f6ac..07c3c49fd68a 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -306,7 +306,7 @@ END #include "aboutbox.rc" #endif -IDD_MEMORY DIALOGEX 0, 0, 566, 287 +IDD_MEMORY DIALOGEX 0, 0, 700, 287 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_TOOLWINDOW CAPTION "Memory View" @@ -316,11 +316,18 @@ BEGIN EDITTEXT IDC_ADDRESS,23,5,61,13,ES_AUTOHSCROLL CONTROL "Custom2",IDC_MEMVIEW,"CtrlMemView",WS_BORDER | WS_TABSTOP,126,23,316,263 LISTBOX IDC_SYMBOLS,1,23,120,263,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - CONTROL "Normal",IDC_MODENORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,248,9,40,9 - CONTROL "Symbols",IDC_MODESYMBOLS,"Button",BS_AUTORADIOBUTTON,291,9,43,8 - GROUPBOX "Mode",IDC_STATIC,241,0,104,22 - AUTOCHECKBOX "Show Offsets",IDC_SHOWOFFSETS,365,9,55,8 + + CONTROL "Normal",IDC_MODENORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,198,9,40,9 + CONTROL "Symbols",IDC_MODESYMBOLS,"Button",BS_AUTORADIOBUTTON,241,9,43,8 + GROUPBOX "Mode",IDC_STATIC,191,0,104,22 + AUTOCHECKBOX "Show Offsets",IDC_SHOWOFFSETS,300,9,55,8 COMBOBOX IDC_REGIONS,87,5,88,139,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LISTBOX IDC_SEARCH_RESULTS,557,14,140,272,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + + EDITTEXT IDC_SEARCH_BOX,397,6,100,13,ES_AUTOHSCROLL + PUSHBUTTON "Search",IDC_BUTTON_SEARCH,504,5,50,14 + LTEXT "Search:",IDC_STATIC,369,6,27,8 END IDD_INPUTBOX DIALOGEX 0, 0, 163, 55 diff --git a/Windows/resource.h b/Windows/resource.h index 3e9cc8ad9368..e5e3307fae3e 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -86,6 +86,7 @@ #define IDC_STOPGO 1001 #define IDC_ADDRESS 1002 #define IDC_DEBUG_COUNT 1003 +#define IDC_SEARCH_BOX 1004 #define IDC_MEMORY 1006 #define IDC_SH4REGISTERS 1007 #define IDC_REGISTERS 1007 @@ -115,6 +116,7 @@ #define IDC_MODENORMAL 1099 #define IDC_MODESYMBOLS 1100 #define IDC_LOG_SHOW 1101 +#define IDC_SEARCH_RESULTS 1102 #define IDC_UPDATELOG 1108 #define IDC_SETPC 1118 #define IDC_UPDATEMISC 1134 @@ -167,6 +169,7 @@ #define IDC_BREAKPOINT_LOG_FORMAT 1199 #define IDC_SHOWOFFSETS 1200 #define IDC_GEDBG_PRIMCOUNTER 1201 +#define IDC_BUTTON_SEARCH 1204 #define ID_SHADERS_BASE 5000