From 9d16d5e42207615beb824d2f618ea35628ef5fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 22 Nov 2024 15:45:14 +0100 Subject: [PATCH] Add search functionality to disassembler --- UI/ImDebugger/ImDebugger.cpp | 41 +++++++++++++++++------ UI/ImDebugger/ImDebugger.h | 2 ++ UI/ImDebugger/ImDisasmView.cpp | 61 +++++++++++++++++++--------------- UI/ImDebugger/ImDisasmView.h | 5 +-- Windows/MainWindowMenu.cpp | 3 +- 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 998952748f..9e21c8c14b 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -375,30 +375,31 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu ImGui::EndMenu(); } if (ImGui::BeginMenu("CPU")) { - ImGui::Checkbox("CPU debugger", &cfg_.disasmOpen); - ImGui::Checkbox("Registers", &cfg_.regsOpen); - ImGui::Checkbox("Callstacks", &cfg_.callstackOpen); + ImGui::MenuItem("CPU debugger", nullptr, &cfg_.disasmOpen); + ImGui::MenuItem("Registers", nullptr, &cfg_.regsOpen); + ImGui::MenuItem("Callstacks", nullptr, &cfg_.callstackOpen); ImGui::EndMenu(); } if (ImGui::BeginMenu("OS HLE")) { - ImGui::Checkbox("HLE Threads", &cfg_.threadsOpen); - ImGui::Checkbox("HLE Modules", &cfg_.modulesOpen); - ImGui::Checkbox("sceAtrac", &cfg_.atracOpen); + ImGui::MenuItem("HLE Threads", nullptr, &cfg_.threadsOpen); + ImGui::MenuItem("HLE Modules",nullptr, &cfg_.modulesOpen); + ImGui::MenuItem("sceAtrac", nullptr, &cfg_.atracOpen); ImGui::EndMenu(); } if (ImGui::BeginMenu("Ge (GPU)")) { - ImGui::Checkbox("Framebuffers", &cfg_.framebuffersOpen); + ImGui::MenuItem("Framebuffers", nullptr, &cfg_.framebuffersOpen); + // More to come here... ImGui::EndMenu(); } if (ImGui::BeginMenu("Tools")) { - ImGui::Checkbox("Struct viewer", &cfg_.structViewerOpen); + ImGui::MenuItem("Struct viewer", nullptr, &cfg_.structViewerOpen); ImGui::EndMenu(); } if (ImGui::BeginMenu("Misc")) { if (ImGui::MenuItem("Close Debugger")) { g_Config.bShowImDebugger = false; } - ImGui::Checkbox("Dear ImGUI Demo", &cfg_.demoOpen); + ImGui::MenuItem("Dear ImGUI Demo", nullptr, &cfg_.demoOpen); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); @@ -501,6 +502,25 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c disasmView_.gotoPC(); } + if (ImGui::BeginPopup("disSearch")) { + if (ImGui::InputText("Search", searchTerm_, sizeof(searchTerm_), ImGuiInputTextFlags_EnterReturnsTrue)) { + disasmView_.Search(searchTerm_); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + ImGui::SameLine(); + if (ImGui::SmallButton("Search")) { + // Open a small popup + ImGui::OpenPopup("disSearch"); + } + + ImGui::SameLine(); + if (ImGui::SmallButton("Next")) { + disasmView_.SearchNext(true); + } + ImGui::SameLine(); ImGui::Checkbox("Follow PC", &disasmView_.followPC_); @@ -517,8 +537,9 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c ImGui::TableSetColumnIndex(0); ImVec2 sz = ImGui::GetContentRegionAvail(); if (ImGui::BeginListBox("##symbols", ImVec2(150.0, sz.y - ImGui::GetTextLineHeightWithSpacing() * 2))) { - if (symCache_.empty()) { + if (symCache_.empty() || symsDirty_) { symCache_ = g_symbolMap->GetAllSymbols(SymbolType::ST_FUNCTION); + symsDirty_ = false; } ImGuiListClipper clipper; clipper.Begin((int)symCache_.size(), -1); diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 1db197d8b2..28c67bc511 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -41,8 +41,10 @@ private: // Symbol cache std::vector symCache_; + bool symsDirty_ = true; ImDisasmView disasmView_; + char searchTerm_[64]{}; }; class ImLuaConsole { diff --git a/UI/ImDebugger/ImDisasmView.cpp b/UI/ImDebugger/ImDisasmView.cpp index b933013cbd..611bdd12ca 100644 --- a/UI/ImDebugger/ImDisasmView.cpp +++ b/UI/ImDebugger/ImDisasmView.cpp @@ -458,12 +458,8 @@ void ImDisasmView::Draw(ImDrawList *drawList) { windowStart_ = manager.getNthNextAddress(windowStart_, 4); } } - if (ImGui::IsKeyPressed(ImGuiKey_PageDown)) { - windowStart_ = manager.getNthNextAddress(windowStart_, visibleRows_); - } - if (ImGui::IsKeyPressed(ImGuiKey_PageUp)) { - windowStart_ = manager.getNthPreviousAddress(windowStart_, visibleRows_); - } + + ProcessKeyboardShortcuts(); int coreStep = Core_GetSteppingCounter(); if (coreStep != lastSteppingCount_) { @@ -560,9 +556,21 @@ void ImDisasmView::editBreakpoint() { */ } -void ImDisasmView::onKeyDown(ImGuiKey key) { +void ImDisasmView::ProcessKeyboardShortcuts() { u32 windowEnd = manager.getNthNextAddress(windowStart_, visibleRows_); keyTaken = true; + if (ImGui::IsKeyPressed(ImGuiKey_PageDown)) { + windowStart_ = manager.getNthNextAddress(windowStart_, visibleRows_); + } + if (ImGui::IsKeyPressed(ImGuiKey_PageUp)) { + windowStart_ = manager.getNthPreviousAddress(windowStart_, visibleRows_); + } + if (ImGui::IsKeyPressed(ImGuiKey_F3)) { + SearchNext(!ImGui::IsKeyPressed(ImGuiKey_LeftShift)); + } + if (ImGui::IsKeyPressed(ImGuiKey_X)) { + disassembleToFile(); + } /* if (KeyDownAsync(VK_CONTROL)) { @@ -1010,26 +1018,24 @@ void ImDisasmView::calculatePixelPositions() { pixelPositions_.arrowsStart = pixelPositions_.argumentsStart + 30 * charWidth_; } -void ImDisasmView::search(bool continueSearch) { - auto memLock = Memory::Lock(); - u32 searchAddress; - - if (continueSearch == false || searchQuery_[0] == 0) { - /* - if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), L"Search for:", searchQuery, searchQuery) == false - || searchQuery[0] == 0) { - SetFocus(wnd); - return; - } - */ - - for (size_t i = 0; i < searchQuery_.size(); i++) { - searchQuery_[i] = tolower(searchQuery_[i]); - } - searchAddress = manager.getNthNextAddress(curAddress_, 1); - } else { - searchAddress = manager.getNthNextAddress(matchAddress_, 1); +void ImDisasmView::Search(std::string_view needle) { + searchQuery_ = needle; + for (size_t i = 0; i < searchQuery_.size(); i++) { + searchQuery_[i] = tolower(searchQuery_[i]); } + matchAddress_ = curAddress_; + SearchNext(true); +} + +void ImDisasmView::SearchNext(bool forward) { + if (searchQuery_.empty()) { + return; + } + + auto memLock = Memory::Lock(); + + // Note: Search will replace matchAddress_ with the current address. + u32 searchAddress = manager.getNthNextAddress(matchAddress_, 1); // limit address to sensible ranges if (searchAddress < 0x04000000) @@ -1082,7 +1088,8 @@ void ImDisasmView::search(bool continueSearch) { if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; } - // MessageBox(wnd, L"Not found", L"Search", MB_OK); + statusBarText_ = "Not found: "; + statusBarText_.append(searchQuery_); searching_ = false; } diff --git a/UI/ImDebugger/ImDisasmView.h b/UI/ImDebugger/ImDisasmView.h index 5fdb8e1475..84f36529a5 100644 --- a/UI/ImDebugger/ImDisasmView.h +++ b/UI/ImDebugger/ImDisasmView.h @@ -29,7 +29,6 @@ public: void ScrollRelative(int amount); void onChar(int c); - void onKeyDown(ImGuiKey key); void onMouseDown(float x, float y, int button); void onMouseUp(float x, float y, int button); void onMouseMove(float x, float y, int button); @@ -96,6 +95,8 @@ public: positionLocked_--; _assert_(positionLocked_ >= 0); } + void Search(std::string_view needle); + void SearchNext(bool forward); // Check these every frame! const std::string &StatusBarText() const { @@ -121,10 +122,10 @@ private: float bottom; }; + void ProcessKeyboardShortcuts(); void assembleOpcode(u32 address, const std::string &defaultText); std::string disassembleRange(u32 start, u32 size); void disassembleToFile(); - void search(bool continueSearch); void FollowBranch(); void calculatePixelPositions(); bool getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 12f260a7d8..df47c40d41 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -556,7 +556,8 @@ namespace MainWindow { case ID_FILE_SAVESTATE_NEXT_SLOT_HC: { if (!Achievements::WarnUserIfHardcoreModeActive(true)) { - if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) { + // We let F3 (search next) in the imdebugger take priority, if active. + if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT) && !g_Config.bShowImDebugger) { SaveState::NextSlot(); System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT); }