diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 49b0d4a6cf..59e8fb018d 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -281,12 +281,13 @@ void CGEDebugger::SetupPreviews() { primaryWindow->SetHoverCallback([&] (int x, int y) { PrimaryPreviewHover(x, y); }); - primaryWindow->SetRightClickMenu(ContextMenuID::GEDBG_PREVIEW, [&] (int cmd) { + primaryWindow->SetRightClickMenu(ContextMenuID::GEDBG_PREVIEW, [&] (int cmd, int x, int y) { HMENU subMenu = GetContextMenu(ContextMenuID::GEDBG_PREVIEW); switch (cmd) { case 0: // Setup. CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 1) ? MF_CHECKED : MF_UNCHECKED)); + EnableMenuItem(subMenu, ID_GEDBG_TRACK_PIXEL_STOP, primaryTrackX_ == 0xFFFFFFFF ? MF_GRAYED : MF_ENABLED); break; case ID_GEDBG_EXPORT_IMAGE: PreviewExport(primaryBuffer_); @@ -297,6 +298,14 @@ void CGEDebugger::SetupPreviews() { case ID_GEDBG_COPY_IMAGE_ALPHA: PreviewToClipboard(primaryBuffer_, true); break; + case ID_GEDBG_TRACK_PIXEL: + primaryTrackX_ = x; + primaryTrackY_ = y; + break; + case ID_GEDBG_TRACK_PIXEL_STOP: + primaryTrackX_ = 0xFFFFFFFF; + primaryTrackX_ = 0xFFFFFFFF; + break; case ID_GEDBG_ENABLE_PREVIEW: previewsEnabled_ ^= 1; primaryWindow->Redraw(); @@ -317,12 +326,13 @@ void CGEDebugger::SetupPreviews() { secondWindow->SetHoverCallback([&] (int x, int y) { SecondPreviewHover(x, y); }); - secondWindow->SetRightClickMenu(ContextMenuID::GEDBG_PREVIEW, [&] (int cmd) { + secondWindow->SetRightClickMenu(ContextMenuID::GEDBG_PREVIEW, [&] (int cmd, int x, int y) { HMENU subMenu = GetContextMenu(ContextMenuID::GEDBG_PREVIEW); switch (cmd) { case 0: // Setup. CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 2) ? MF_CHECKED : MF_UNCHECKED)); + EnableMenuItem(subMenu, ID_GEDBG_TRACK_PIXEL_STOP, secondTrackX_ == 0xFFFFFFFF ? MF_GRAYED : MF_ENABLED); break; case ID_GEDBG_EXPORT_IMAGE: PreviewExport(secondBuffer_); @@ -333,6 +343,14 @@ void CGEDebugger::SetupPreviews() { case ID_GEDBG_COPY_IMAGE_ALPHA: PreviewToClipboard(secondBuffer_, true); break; + case ID_GEDBG_TRACK_PIXEL: + secondTrackX_ = x; + secondTrackY_ = y; + break; + case ID_GEDBG_TRACK_PIXEL_STOP: + secondTrackX_ = 0xFFFFFFFF; + secondTrackX_ = 0xFFFFFFFF; + break; case ID_GEDBG_ENABLE_PREVIEW: previewsEnabled_ ^= 2; secondWindow->Redraw(); @@ -350,6 +368,12 @@ void CGEDebugger::SetupPreviews() { } void CGEDebugger::DescribePrimaryPreview(const GPUgstate &state, char desc[256]) { + if (primaryTrackX_ < primaryBuffer_->GetStride() && primaryTrackY_ < primaryBuffer_->GetHeight()) { + u32 pix = primaryBuffer_->GetRawPixel(primaryTrackX_, primaryTrackY_); + DescribePixel(pix, primaryBuffer_->GetFormat(), primaryTrackX_, primaryTrackY_, desc); + return; + } + if (showClut_) { // In this case, we're showing the texture here. snprintf(desc, 256, "Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_)); @@ -374,6 +398,22 @@ void CGEDebugger::DescribePrimaryPreview(const GPUgstate &state, char desc[256]) } void CGEDebugger::DescribeSecondPreview(const GPUgstate &state, char desc[256]) { + if (secondTrackX_ != 0xFFFFFFFF) { + uint32_t x = secondTrackX_; + uint32_t y = secondTrackY_; + if (showClut_) { + uint32_t clutWidth = secondBuffer_->GetStride() / 16; + x = y * clutWidth + x; + y = 0; + } + + if (x < secondBuffer_->GetStride() && y < secondBuffer_->GetHeight()) { + u32 pix = secondBuffer_->GetRawPixel(x, y); + DescribePixel(pix, secondBuffer_->GetFormat(), x, y, desc); + return; + } + } + if (showClut_) { snprintf(desc, 256, "CLUT: 0x%08x (%d)", state.getClutAddress(), state.getClutPaletteFormat()); } else { diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index ba73f479a0..9488c6ec21 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -140,6 +140,11 @@ private: const GPUDebugBuffer *primaryBuffer_ = nullptr; const GPUDebugBuffer *secondBuffer_ = nullptr; + uint32_t primaryTrackX_ = 0xFFFFFFFF; + uint32_t primaryTrackY_ = 0xFFFFFFFF; + uint32_t secondTrackX_ = 0xFFFFFFFF; + uint32_t secondTrackY_ = 0xFFFFFFFF; + bool updating_ = false; int previewsEnabled_ = 3; int minWidth_; diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index e04053ed3d..6f0464a87c 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -519,25 +519,34 @@ bool SimpleGLWindow::ToggleZoom() { return true; } -bool SimpleGLWindow::Hover(int mouseX, int mouseY) { - if (hoverCallback_ == nullptr) { - return false; - } - +POINT SimpleGLWindow::PosFromMouse(int mouseX, int mouseY) { float fw, fh; float x, y; GetContentSize(x, y, fw, fh); if (mouseX < x || mouseX >= x + fw || mouseY < y || mouseY >= y + fh) { // Outside of bounds. - hoverCallback_(-1, -1); - return true; + return POINT{ -1, -1 }; } float tx = (mouseX - x) * (tw_ / fw); float ty = (mouseY - y) * (th_ / fh); - hoverCallback_((int)tx, (int)ty); + return POINT{ (int)tx, (int)ty }; +} + +bool SimpleGLWindow::Hover(int mouseX, int mouseY) { + if (hoverCallback_ == nullptr) { + return false; + } + + POINT pos = PosFromMouse(mouseX, mouseY); + hoverCallback_(pos.x, pos.y); + + if (pos.x == -1 || pos.y == -1) { + // Outside of bounds, don't track. + return true; + } // Find out when they are done. TRACKMOUSEEVENT tracking = {0}; @@ -564,11 +573,12 @@ bool SimpleGLWindow::RightClick(int mouseX, int mouseY) { } POINT pt{mouseX, mouseY}; + POINT pos = PosFromMouse(mouseX, mouseY); - rightClickCallback_(0); + rightClickCallback_(0, pos.x, pos.y); int result = TriggerContextMenu(rightClickMenu_, hWnd_, ContextPoint::FromClient(pt)); if (result > 0) { - rightClickCallback_(result); + rightClickCallback_(result, pos.x, pos.y); } return true; diff --git a/Windows/GEDebugger/SimpleGLWindow.h b/Windows/GEDebugger/SimpleGLWindow.h index caf90b8b6d..605fb0c37f 100644 --- a/Windows/GEDebugger/SimpleGLWindow.h +++ b/Windows/GEDebugger/SimpleGLWindow.h @@ -117,7 +117,7 @@ struct SimpleGLWindow { } // Called first with 0 that it's opening, then the selected item. - void SetRightClickMenu(ContextMenuID menu, std::function callback) { + void SetRightClickMenu(ContextMenuID menu, std::function callback) { rightClickCallback_ = callback; rightClickMenu_ = menu; } @@ -136,6 +136,7 @@ protected: bool Leave(); bool RightClick(int mouseX, int mouseY); bool ToggleZoom(); + POINT PosFromMouse(int mouseX, int mouseY); const u8 *Reformat(const u8 *data, Format fmt, u32 numPixels); HWND hWnd_; @@ -173,6 +174,6 @@ protected: std::function redrawCallback_; std::function hoverCallback_; - std::function rightClickCallback_; + std::function rightClickCallback_; ContextMenuID rightClickMenu_; }; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 304ffded6b..c04801767e 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -786,6 +786,8 @@ BEGIN MENUITEM "Export Image...", ID_GEDBG_EXPORT_IMAGE MENUITEM "Copy Opaque Image", ID_GEDBG_COPY_IMAGE MENUITEM "Copy Image With Alpha", ID_GEDBG_COPY_IMAGE_ALPHA + MENUITEM "Track Pixel", ID_GEDBG_TRACK_PIXEL + MENUITEM "Stop Tracking Pixel", ID_GEDBG_TRACK_PIXEL_STOP MENUITEM "Show Prim Preview", ID_GEDBG_ENABLE_PREVIEW END POPUP "matrixoptions" diff --git a/Windows/resource.h b/Windows/resource.h index 822eb06bf9..ab68ee494f 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -335,6 +335,8 @@ #define ID_GEDBG_SETCOND 40223 #define ID_GEDBG_COPY_IMAGE 40224 #define ID_GEDBG_COPY_IMAGE_ALPHA 40225 +#define ID_GEDBG_TRACK_PIXEL 40226 +#define ID_GEDBG_TRACK_PIXEL_STOP 40227 // Dummy option to let the buffered rendering hotkey cycle through all the options. @@ -348,7 +350,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40226 +#define _APS_NEXT_COMMAND_VALUE 40228 #define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif