From dcf442349f4d46d834d1281b7f11335180076c9f Mon Sep 17 00:00:00 2001 From: Artem Lytkin Date: Sat, 5 Sep 2026 10:09:46 +0300 Subject: [PATCH] Win32 debugger: show VFPU values, make the register list scrollable PrintRegValue returned "N/A" for the VFPU category, and CtrlRegisterList had its WM_VSCROLL case commented out, so only the rows that fit in the window were reachable - about a quarter of the 128 VFPU registers. Print the float the same way the FPU tab does, give the list a real scrollbar with mouse wheel support, keep the keyboard selection in view, and reset the position when switching tabs. The category header hit test now uses the client rect so the tab boundaries match what's drawn once the scrollbar takes its share of the width. KernelThreadDebugInterface gets the same one-line fix for parity. --- Core/HLE/KernelThreadDebugInterface.h | 2 +- Core/MIPS/MIPSDebugInterface.h | 2 +- Windows/Debugger/CtrlRegisterList.cpp | 86 +++++++++++++++++++++++---- Windows/Debugger/CtrlRegisterList.h | 5 ++ 4 files changed, 83 insertions(+), 12 deletions(-) diff --git a/Core/HLE/KernelThreadDebugInterface.h b/Core/HLE/KernelThreadDebugInterface.h index 13cfb3fad8..0a9029ccfe 100644 --- a/Core/HLE/KernelThreadDebugInterface.h +++ b/Core/HLE/KernelThreadDebugInterface.h @@ -42,7 +42,7 @@ public: switch (cat) { case 0: snprintf(out, outSize, "%08X", ctx.r[index]); break; case 1: snprintf(out, outSize, "%f", ctx.f[index]); break; - case 2: snprintf(out, outSize, "N/A"); break; + case 2: snprintf(out, outSize, "%f", ctx.v[voffset[index]]); break; } } diff --git a/Core/MIPS/MIPSDebugInterface.h b/Core/MIPS/MIPSDebugInterface.h index 1eb2ee2e52..17df75bf7e 100644 --- a/Core/MIPS/MIPSDebugInterface.h +++ b/Core/MIPS/MIPSDebugInterface.h @@ -62,7 +62,7 @@ public: switch (cat) { case 0: snprintf(out, outSize, "%08X", cpu->r[index]); break; case 1: snprintf(out, outSize, "%f", cpu->f[index]); break; - case 2: snprintf(out, outSize, "N/A"); break; + case 2: snprintf(out, outSize, "%f", cpu->v[voffset[index]]); break; } } diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index 9ea4db02a4..5731a552ea 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -71,15 +71,21 @@ LRESULT CALLBACK CtrlRegisterList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, L case WM_SETFONT: break; case WM_SIZE: - ccp->redraw(); + if (ccp->cpu) ccp->scrollTo(ccp->scrollRow_); break; case WM_PAINT: ccp->onPaint(wParam,lParam); - break; -/* + break; case WM_VSCROLL: ccp->onVScroll(wParam,lParam); - break;*/ + break; + case WM_MOUSEWHEEL: + if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) { + ccp->scrollTo(ccp->scrollRow_ - 3); + } else if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) { + ccp->scrollTo(ccp->scrollRow_ + 3); + } + break; case WM_ERASEBKGND: return FALSE; case WM_KEYDOWN: @@ -130,6 +136,7 @@ CtrlRegisterList *CtrlRegisterList::getFrom(HWND hwnd) CtrlRegisterList::CtrlRegisterList(HWND _wnd) : wnd(_wnd) { SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)this); + SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL); const float fontScale = 1.0f / g_display.dpi_scale_real_y; rowHeight = g_Config.iFontHeight * fontScale; @@ -199,6 +206,12 @@ void CtrlRegisterList::onPaint(WPARAM wParam, LPARAM lParam) int numRows=rect.bottom/rowHeight; + SCROLLINFO si{ sizeof(si), SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL }; + si.nMax = totalRows() - 1; + si.nPage = visibleRows(); + si.nPos = scrollRow_; + SetScrollInfo(wnd, SB_VERT, &si, TRUE); + // Reading live CPU-thread-owned register state here on the GUI thread would otherwise race // with the CPU thread - hold g_frameMutex for the duration of the read, which NativeFrame() // also holds while it's actually touching that state. See g_frameMutex in Core.h. @@ -208,10 +221,10 @@ void CtrlRegisterList::onPaint(WPARAM wParam, LPARAM lParam) // to highlight "changes" that are really just noise at that point. bool running = !Core_IsStepping(); - for (int i=0; i= totalRows()) selection = totalRows() - 1; + if (selection < 0) selection = 0; + // Keep the selection in view. + if (selection < scrollRow_) + scrollTo(selection); + else if (selection >= scrollRow_ + visibleRows()) + scrollTo(selection - visibleRows() + 1); + redraw(); +} + +void CtrlRegisterList::onVScroll(WPARAM wParam, LPARAM lParam) +{ + switch (wParam & 0xFFFF) + { + case SB_LINEDOWN: + scrollTo(scrollRow_ + 1); + break; + case SB_LINEUP: + scrollTo(scrollRow_ - 1); + break; + case SB_PAGEDOWN: + scrollTo(scrollRow_ + visibleRows()); + break; + case SB_PAGEUP: + scrollTo(scrollRow_ - visibleRows()); + break; + case SB_THUMBTRACK: + case SB_THUMBPOSITION: + scrollTo(HIWORD(wParam)); + break; + } +} + +// Rows in the current category, including pc/hi/lo for the GPR tab. +int CtrlRegisterList::totalRows() +{ + return category == 0 ? REGISTERS_END : cpu->GetNumRegsInCategory(category); +} + +// Rows that fit below the category header. +int CtrlRegisterList::visibleRows() +{ + GetClientRect(wnd, &rect); + int rows = rect.bottom / rowHeight - 1; + return rows < 1 ? 1 : rows; +} + +void CtrlRegisterList::scrollTo(int row) +{ + int maxRow = totalRows() - visibleRows(); + if (row > maxRow) row = maxRow; + if (row < 0) row = 0; + scrollRow_ = row; redraw(); } @@ -486,14 +552,14 @@ void CtrlRegisterList::onMouseDown(WPARAM wParam, LPARAM lParam, int button) { RECT rc; SetCapture(wnd); - GetWindowRect(wnd,&rc); + GetClientRect(wnd,&rc); int lastCat = category; category = (x*cpu->GetNumCategories())/(rc.right-rc.left); if (category<0) category=0; if (category>=cpu->GetNumCategories()) category=cpu->GetNumCategories()-1; if (category!=lastCat) - redraw(); + scrollTo(0); } } else @@ -597,7 +663,7 @@ int CtrlRegisterList::yToIndex(int y) // int ydiff=y-rect.bottom/2-rowHeight_/2; // ydiff=(int)(floorf((float)ydiff / (float)rowHeight_))+1; // return curAddress + ydiff * align; - int n = (y/rowHeight) - 1; + int n = (y/rowHeight) - 1 + scrollRow_; if (n<0) n=0; return n; } diff --git a/Windows/Debugger/CtrlRegisterList.h b/Windows/Debugger/CtrlRegisterList.h index 5bc31d9b41..115bc7b54c 100644 --- a/Windows/Debugger/CtrlRegisterList.h +++ b/Windows/Debugger/CtrlRegisterList.h @@ -26,6 +26,7 @@ class CtrlRegisterList { int rowHeight; int selection = 0; int category = 0; + int scrollRow_ = 0; int oldSelection = 0; @@ -41,6 +42,9 @@ class CtrlRegisterList { u32 getSelectedRegValue(char *out, size_t size); void copyRegisterValue(); void editRegisterValue(); + int totalRows(); + int visibleRows(); + void scrollTo(int row); public: CtrlRegisterList(HWND _wnd); ~CtrlRegisterList(); @@ -50,6 +54,7 @@ public: static CtrlRegisterList * getFrom(HWND wnd); void onPaint(WPARAM wParam, LPARAM lParam); + void onVScroll(WPARAM wParam, LPARAM lParam); void onKeyDown(WPARAM wParam, LPARAM lParam); void onMouseDown(WPARAM wParam, LPARAM lParam, int button); void onMouseUp(WPARAM wParam, LPARAM lParam, int button);