diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index fb88fdca2f..b505521631 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -18,6 +18,7 @@ #include #include "Common/Log.h" #include "Common/StringUtils.h" +#include "Common/TimeUtil.h" #include "GPU/GPU.h" #include "GPU/Debugger/Breakpoints.h" #include "GPU/Debugger/Debugger.h" @@ -35,6 +36,8 @@ static int primsLastFrame = 0; static int primsThisFrame = 0; static int thisFlipNum = 0; +static double lastStepTime = -1.0; + static std::vector> restrictPrimRanges; static std::string restrictPrimRule; @@ -56,6 +59,7 @@ void SetActive(bool flag) { breakNext = BreakNext::NONE; breakAtCount = -1; GPUStepping::ResumeFromStepping(); + lastStepTime = -1.0; } } @@ -79,6 +83,7 @@ void SetBreakNext(BreakNext next) { GPUBreakpoints::AddCmdBreakpoint(GE_CMD_SPLINE, true); } GPUStepping::ResumeFromStepping(); + lastStepTime = next == BreakNext::NONE ? -1.0 : time_now_d(); } void SetBreakCount(int c, bool relative) { @@ -130,7 +135,12 @@ bool NotifyCommand(u32 pc) { GPUBreakpoints::ClearTempBreakpoints(); auto info = gpuDebug->DissassembleOp(pc); - NOTICE_LOG(G3D, "Waiting at %08x, %s", pc, info.desc.c_str()); + if (lastStepTime >= 0.0) { + NOTICE_LOG(G3D, "Waiting at %08x, %s (%fms)", pc, info.desc.c_str(), (time_now_d() - lastStepTime) * 1000.0); + lastStepTime = -1.0; + } else { + NOTICE_LOG(G3D, "Waiting at %08x, %s", pc, info.desc.c_str()); + } GPUStepping::EnterStepping(); } @@ -141,7 +151,12 @@ void NotifyDraw() { if (!active) return; if (breakNext == BreakNext::DRAW && !GPUStepping::IsStepping()) { - NOTICE_LOG(G3D, "Waiting at a draw"); + if (lastStepTime >= 0.0) { + NOTICE_LOG(G3D, "Waiting at a draw (%fms)", (time_now_d() - lastStepTime) * 1000.0); + lastStepTime = -1.0; + } else { + NOTICE_LOG(G3D, "Waiting at a draw"); + } GPUStepping::EnterStepping(); } } diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index 657a0193d2..1849070afc 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -288,9 +288,49 @@ int GenericListControl::HandleNotify(LPARAM lParam) { return 0; } + if (mhdr->code == LVN_INCREMENTALSEARCH) { + NMLVFINDITEM *request = (NMLVFINDITEM *)lParam; + uint32_t supported = LVFI_WRAP | LVFI_STRING | LVFI_PARTIAL | LVFI_SUBSTRING; + if ((request->lvfi.flags & ~supported) == 0 && (request->lvfi.flags & LVFI_STRING) != 0) { + bool wrap = (request->lvfi.flags & LVFI_WRAP) != 0; + bool partial = (request->lvfi.flags & (LVFI_PARTIAL | LVFI_SUBSTRING)) != 0; + + // It seems like 0 is always sent for start, let's override. + int startRow = request->iStart; + if (startRow == 0) + startRow = GetSelectedIndex(); + int result = OnIncrementalSearch(startRow, request->lvfi.psz, wrap, partial); + if (result != -1) { + request->lvfi.flags = LVFI_PARAM; + request->lvfi.lParam = (LPARAM)result; + } + } + } + return 0; } +int GenericListControl::OnIncrementalSearch(int startRow, const wchar_t *str, bool wrap, bool partial) { + int size = GetRowCount(); + size_t searchlen = wcslen(str); + if (!wrap) + size -= startRow; + + // We start with the earliest column, preferring matches on the leftmost columns by default. + for (int c = 0; c < columnCount; ++c) { + for (int i = 0; i < size; ++i) { + int r = (startRow + i) % size; + stringBuffer[0] = 0; + GetColumnText(stringBuffer, r, c); + int difference = partial ? _wcsnicmp(str, stringBuffer, searchlen) : _wcsicmp(str, stringBuffer); + if (difference == 0) + return r; + } + } + + return -1; +} + void GenericListControl::Update() { if (!updateScheduled_) { SetTimer(handle, IDT_UPDATE, UPDATE_DELAY, nullptr); diff --git a/Windows/W32Util/Misc.h b/Windows/W32Util/Misc.h index 8a43c55b59..1b723cc241 100644 --- a/Windows/W32Util/Misc.h +++ b/Windows/W32Util/Misc.h @@ -68,6 +68,8 @@ protected: virtual bool OnRowPrePaint(int row, LPNMLVCUSTOMDRAW msg) { return false; } virtual bool OnColPrePaint(int row, int col, LPNMLVCUSTOMDRAW msg) { return false; } + virtual int OnIncrementalSearch(int startRow, const wchar_t *str, bool wrap, bool partial); + private: static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void ProcessUpdate();