diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index df701bcf33..e654438772 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -149,6 +149,8 @@ void CtrlDisplayListView::onPaint(WPARAM wParam, LPARAM lParam) HPEN oldPen=(HPEN)SelectObject(hdc,nullPen); HBRUSH oldBrush=(HBRUSH)SelectObject(hdc,nullBrush); HFONT oldFont = (HFONT)SelectObject(hdc,(HGDIOBJ)font); + + HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP); for (int i = 0; i < visibleRows+2; i++) { @@ -185,6 +187,13 @@ void CtrlDisplayListView::onPaint(WPARAM wParam, LPARAM lParam) DeleteObject(backgroundBrush); DeleteObject(backgroundPen); + // display address/symbol + if (CGEDebugger::IsAddressBreakPoint(address)) + { + textColor = 0x0000FF; + int yOffset = std::max(-1,(rowHeight-14+1)/2); + DrawIconEx(hdc,2,rowY1+1+yOffset,breakPoint,32,32,0,0,DI_NORMAL); + } SetTextColor(hdc,textColor); GPUDebugOp op = gpuDebug->DissassembleOp(address); @@ -219,9 +228,16 @@ void CtrlDisplayListView::onPaint(WPARAM wParam, LPARAM lParam) DeleteObject(nullBrush); DeleteObject(currentBrush); + DestroyIcon(breakPoint); + EndPaint(wnd, &ps); } +void CtrlDisplayListView::toggleBreakpoint() +{ + SendMessage(GetParent(wnd),WM_GEDBG_TOGGLEPCBREAKPOINT,curAddress,0); +} + void CtrlDisplayListView::onMouseDown(WPARAM wParam, LPARAM lParam, int button) { int x = LOWORD(lParam); @@ -229,6 +245,15 @@ void CtrlDisplayListView::onMouseDown(WPARAM wParam, LPARAM lParam, int button) int line = y/rowHeight; u32 newAddress = windowStart + line*instructionSize; + + if (button == 1) + { + if (newAddress == curAddress && hasFocus) + { + toggleBreakpoint(); + } + } + setCurAddress(newAddress); SetFocus(wnd); diff --git a/Windows/GEDebugger/CtrlDisplayListView.h b/Windows/GEDebugger/CtrlDisplayListView.h index cb46183ffb..c8293f346a 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.h +++ b/Windows/GEDebugger/CtrlDisplayListView.h @@ -26,6 +26,8 @@ class CtrlDisplayListView int addressStart; int opcodeStart; } pixelPositions; + + void toggleBreakpoint(); public: CtrlDisplayListView(HWND _wnd); ~CtrlDisplayListView(); diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index b6ffa2709b..3e6863ae90 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -66,6 +66,10 @@ void CGEDebugger::Init() { CtrlDisplayListView::registerClass(); } +bool CGEDebugger::IsAddressBreakPoint(u32 pc) { + return breakPCs.find(pc) != breakPCs.end(); +} + static void SetPauseAction(PauseAction act) { { lock_guard guard(pauseLock); @@ -341,6 +345,19 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { breakNextOp = true; breakNextDraw = false; break; + + case WM_GEDBG_TOGGLEPCBREAKPOINT: + { + // TODO: does this need mutexes? + u32 pc = wParam; + auto iter = breakPCs.find(pc); + if (iter != breakPCs.end()) + breakPCs.erase(iter); + else + breakPCs.insert(pc); + } + break; + } return FALSE; diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index 25f4faedfd..dec741f1c1 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -28,6 +28,7 @@ enum { WM_GEDBG_BREAK_CMD = WM_USER + 200, WM_GEDBG_BREAK_DRAW, WM_GEDBG_STEPDISPLAYLIST, + WM_GEDBG_TOGGLEPCBREAKPOINT }; class CtrlDisplayListView; @@ -43,6 +44,8 @@ public: ~CGEDebugger(); static void Init(); + + static bool IsAddressBreakPoint(u32 pc); protected: BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam); diff --git a/Windows/GEDebugger/TabDisplayLists.cpp b/Windows/GEDebugger/TabDisplayLists.cpp index 899d2b7228..a228b548f5 100644 --- a/Windows/GEDebugger/TabDisplayLists.cpp +++ b/Windows/GEDebugger/TabDisplayLists.cpp @@ -263,6 +263,11 @@ BOOL TabDisplayLists::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { displayList->gotoAddr(pc); } break; + + case WM_GEDBG_TOGGLEPCBREAKPOINT: + SendMessage(GetParent(m_hDlg),message,wParam,lParam); + break; + } return FALSE;