Add search functionality to disassembler

This commit is contained in:
Henrik Rydgård 2024-11-22 15:45:14 +01:00
parent d068f79f78
commit 9d16d5e422
5 changed files with 72 additions and 40 deletions

View File

@ -375,30 +375,31 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("CPU")) { if (ImGui::BeginMenu("CPU")) {
ImGui::Checkbox("CPU debugger", &cfg_.disasmOpen); ImGui::MenuItem("CPU debugger", nullptr, &cfg_.disasmOpen);
ImGui::Checkbox("Registers", &cfg_.regsOpen); ImGui::MenuItem("Registers", nullptr, &cfg_.regsOpen);
ImGui::Checkbox("Callstacks", &cfg_.callstackOpen); ImGui::MenuItem("Callstacks", nullptr, &cfg_.callstackOpen);
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("OS HLE")) { if (ImGui::BeginMenu("OS HLE")) {
ImGui::Checkbox("HLE Threads", &cfg_.threadsOpen); ImGui::MenuItem("HLE Threads", nullptr, &cfg_.threadsOpen);
ImGui::Checkbox("HLE Modules", &cfg_.modulesOpen); ImGui::MenuItem("HLE Modules",nullptr, &cfg_.modulesOpen);
ImGui::Checkbox("sceAtrac", &cfg_.atracOpen); ImGui::MenuItem("sceAtrac", nullptr, &cfg_.atracOpen);
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Ge (GPU)")) { if (ImGui::BeginMenu("Ge (GPU)")) {
ImGui::Checkbox("Framebuffers", &cfg_.framebuffersOpen); ImGui::MenuItem("Framebuffers", nullptr, &cfg_.framebuffersOpen);
// More to come here...
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Tools")) { if (ImGui::BeginMenu("Tools")) {
ImGui::Checkbox("Struct viewer", &cfg_.structViewerOpen); ImGui::MenuItem("Struct viewer", nullptr, &cfg_.structViewerOpen);
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Misc")) { if (ImGui::BeginMenu("Misc")) {
if (ImGui::MenuItem("Close Debugger")) { if (ImGui::MenuItem("Close Debugger")) {
g_Config.bShowImDebugger = false; g_Config.bShowImDebugger = false;
} }
ImGui::Checkbox("Dear ImGUI Demo", &cfg_.demoOpen); ImGui::MenuItem("Dear ImGUI Demo", nullptr, &cfg_.demoOpen);
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
@ -501,6 +502,25 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c
disasmView_.gotoPC(); 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::SameLine();
ImGui::Checkbox("Follow PC", &disasmView_.followPC_); ImGui::Checkbox("Follow PC", &disasmView_.followPC_);
@ -517,8 +537,9 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c
ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
ImVec2 sz = ImGui::GetContentRegionAvail(); ImVec2 sz = ImGui::GetContentRegionAvail();
if (ImGui::BeginListBox("##symbols", ImVec2(150.0, sz.y - ImGui::GetTextLineHeightWithSpacing() * 2))) { 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); symCache_ = g_symbolMap->GetAllSymbols(SymbolType::ST_FUNCTION);
symsDirty_ = false;
} }
ImGuiListClipper clipper; ImGuiListClipper clipper;
clipper.Begin((int)symCache_.size(), -1); clipper.Begin((int)symCache_.size(), -1);

View File

@ -41,8 +41,10 @@ private:
// Symbol cache // Symbol cache
std::vector<SymbolEntry> symCache_; std::vector<SymbolEntry> symCache_;
bool symsDirty_ = true;
ImDisasmView disasmView_; ImDisasmView disasmView_;
char searchTerm_[64]{};
}; };
class ImLuaConsole { class ImLuaConsole {

View File

@ -458,12 +458,8 @@ void ImDisasmView::Draw(ImDrawList *drawList) {
windowStart_ = manager.getNthNextAddress(windowStart_, 4); windowStart_ = manager.getNthNextAddress(windowStart_, 4);
} }
} }
if (ImGui::IsKeyPressed(ImGuiKey_PageDown)) {
windowStart_ = manager.getNthNextAddress(windowStart_, visibleRows_); ProcessKeyboardShortcuts();
}
if (ImGui::IsKeyPressed(ImGuiKey_PageUp)) {
windowStart_ = manager.getNthPreviousAddress(windowStart_, visibleRows_);
}
int coreStep = Core_GetSteppingCounter(); int coreStep = Core_GetSteppingCounter();
if (coreStep != lastSteppingCount_) { if (coreStep != lastSteppingCount_) {
@ -560,9 +556,21 @@ void ImDisasmView::editBreakpoint() {
*/ */
} }
void ImDisasmView::onKeyDown(ImGuiKey key) { void ImDisasmView::ProcessKeyboardShortcuts() {
u32 windowEnd = manager.getNthNextAddress(windowStart_, visibleRows_); u32 windowEnd = manager.getNthNextAddress(windowStart_, visibleRows_);
keyTaken = true; 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)) { if (KeyDownAsync(VK_CONTROL)) {
@ -1010,26 +1018,24 @@ void ImDisasmView::calculatePixelPositions() {
pixelPositions_.arrowsStart = pixelPositions_.argumentsStart + 30 * charWidth_; pixelPositions_.arrowsStart = pixelPositions_.argumentsStart + 30 * charWidth_;
} }
void ImDisasmView::search(bool continueSearch) { void ImDisasmView::Search(std::string_view needle) {
auto memLock = Memory::Lock(); searchQuery_ = needle;
u32 searchAddress; for (size_t i = 0; i < searchQuery_.size(); i++) {
searchQuery_[i] = tolower(searchQuery_[i]);
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);
} }
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 // limit address to sensible ranges
if (searchAddress < 0x04000000) if (searchAddress < 0x04000000)
@ -1082,7 +1088,8 @@ void ImDisasmView::search(bool continueSearch) {
if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
} }
// MessageBox(wnd, L"Not found", L"Search", MB_OK); statusBarText_ = "Not found: ";
statusBarText_.append(searchQuery_);
searching_ = false; searching_ = false;
} }

View File

@ -29,7 +29,6 @@ public:
void ScrollRelative(int amount); void ScrollRelative(int amount);
void onChar(int c); void onChar(int c);
void onKeyDown(ImGuiKey key);
void onMouseDown(float x, float y, int button); void onMouseDown(float x, float y, int button);
void onMouseUp(float x, float y, int button); void onMouseUp(float x, float y, int button);
void onMouseMove(float x, float y, int button); void onMouseMove(float x, float y, int button);
@ -96,6 +95,8 @@ public:
positionLocked_--; positionLocked_--;
_assert_(positionLocked_ >= 0); _assert_(positionLocked_ >= 0);
} }
void Search(std::string_view needle);
void SearchNext(bool forward);
// Check these every frame! // Check these every frame!
const std::string &StatusBarText() const { const std::string &StatusBarText() const {
@ -121,10 +122,10 @@ private:
float bottom; float bottom;
}; };
void ProcessKeyboardShortcuts();
void assembleOpcode(u32 address, const std::string &defaultText); void assembleOpcode(u32 address, const std::string &defaultText);
std::string disassembleRange(u32 start, u32 size); std::string disassembleRange(u32 start, u32 size);
void disassembleToFile(); void disassembleToFile();
void search(bool continueSearch);
void FollowBranch(); void FollowBranch();
void calculatePixelPositions(); void calculatePixelPositions();
bool getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData); bool getDisasmAddressText(u32 address, char* dest, bool abbreviateLabels, bool showData);

View File

@ -556,7 +556,8 @@ namespace MainWindow {
case ID_FILE_SAVESTATE_NEXT_SLOT_HC: case ID_FILE_SAVESTATE_NEXT_SLOT_HC:
{ {
if (!Achievements::WarnUserIfHardcoreModeActive(true)) { 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(); SaveState::NextSlot();
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT); System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
} }