From 9c3e00aa08f58a2191e1bd8838c93db14cd80d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 11 Aug 2022 22:45:40 +0200 Subject: [PATCH 01/15] Add a second set of tabs to the Windows GE debugger. Also reorder stuff. --- Windows/GEDebugger/GEDebugger.cpp | 45 ++++++++++++++++++++++----- Windows/GEDebugger/GEDebugger.h | 8 +++-- Windows/GEDebugger/TabState.cpp | 51 ++++++++++++++++--------------- Windows/ppsspp.rc | 3 +- Windows/resource.h | 4 ++- 5 files changed, 75 insertions(+), 36 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 2a7c32713f..16aa373b68 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -146,8 +146,10 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&frameRect,2); MoveWindow(frameWnd,frameRect.left,frameRect.top,512,272,TRUE); - tabs = new TabControl(GetDlgItem(m_hDlg,IDC_GEDBG_MAINTAB)); - HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView",L"Display List"); + tabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_MAINTAB)); + tabsRight_ = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_RIGHTTAB)); + + HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView", L"Display List"); displayList = CtrlDisplayListView::getFrom(wnd); fbTabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_FBTABS)); @@ -162,7 +164,7 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) tabs->AddTabDialog(flags, L"Flags"); lighting = new TabStateLighting(_hInstance, m_hDlg); - tabs->AddTabDialog(lighting, L"Lighting"); + tabs->AddTabDialog(lighting, L"Light"); textureState = new TabStateTexture(_hInstance, m_hDlg); tabs->AddTabDialog(textureState, L"Texture"); @@ -171,7 +173,7 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) tabs->AddTabDialog(settings, L"Settings"); vertices = new TabVertices(_hInstance, m_hDlg); - tabs->AddTabDialog(vertices, L"Vertices"); + tabs->AddTabDialog(vertices, L"Verts"); matrices = new TabMatrices(_hInstance, m_hDlg); tabs->AddTabDialog(matrices, L"Matrices"); @@ -184,6 +186,18 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) tabs->ShowTab(0, true); + + lightingRight_ = new TabStateLighting(_hInstance, m_hDlg); + tabsRight_->AddTabDialog(lightingRight_, L"Light"); + + textureStateRight_ = new TabStateTexture(_hInstance, m_hDlg); + tabsRight_->AddTabDialog(textureStateRight_, L"Texture"); + + settingsRight_ = new TabStateSettings(_hInstance, m_hDlg); + tabsRight_->AddTabDialog(settingsRight_, L"Settings"); + + tabsRight_->ShowTab(0, true); + // set window position int x = g_Config.iGEWindowX == -1 ? windowRect.left : g_Config.iGEWindowX; int y = g_Config.iGEWindowY == -1 ? windowRect.top : g_Config.iGEWindowY; @@ -200,13 +214,17 @@ CGEDebugger::~CGEDebugger() { CleanupPrimPreview(); delete flags; delete lighting; + delete lightingRight_; delete textureState; + delete textureStateRight_; delete settings; + delete settingsRight_; delete vertices; delete matrices; delete lists; delete watch; delete tabs; + delete tabsRight_; delete fbTabs; } @@ -364,8 +382,11 @@ void CGEDebugger::UpdatePreviews() { flags->Update(); lighting->Update(); + lightingRight_->Update(); textureState->Update(); + textureStateRight_->Update(); settings->Update(); + settingsRight_->Update(); vertices->Update(); matrices->Update(); lists->Update(); @@ -696,16 +717,23 @@ void CGEDebugger::UpdateTextureLevel(int level) { } void CGEDebugger::UpdateSize(WORD width, WORD height) { - // only resize the tab for now + // only resize the tabs for now HWND tabControl = GetDlgItem(m_hDlg, IDC_GEDBG_MAINTAB); + HWND tabControlRight = GetDlgItem(m_hDlg, IDC_GEDBG_RIGHTTAB); RECT tabRect; GetWindowRect(tabControl,&tabRect); MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&tabRect,2); - tabRect.right = tabRect.left + (width-tabRect.left*2); // assume same gap on both sides + tabRect.right = tabRect.left + (width / 2-tabRect.left*2); // assume same gap on both sides tabRect.bottom = tabRect.top + (height-tabRect.top-tabRect.left); // assume same gap on bottom too - MoveWindow(tabControl,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE); + + RECT tabRectRight = tabRect; + tabRectRight.left += tabRect.right; + tabRectRight.right += tabRect.right; + + MoveWindow(tabControl, tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, TRUE); + MoveWindow(tabControlRight, tabRectRight.left, tabRectRight.top, tabRectRight.right - tabRectRight.left, tabRectRight.bottom - tabRectRight.top, TRUE); } void CGEDebugger::SavePosition() { @@ -777,6 +805,9 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { lists->Update(); } break; + case IDC_GEDBG_RIGHTTAB: + tabsRight_->HandleNotify(lParam); + break; case IDC_GEDBG_FBTABS: fbTabs->HandleNotify(lParam); if (GPUDebug::IsActive() && gpuDebug != nullptr) { diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index ebf9a2c0d7..7dabf9c63c 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -81,8 +81,8 @@ private: void PrimaryPreviewHover(int x, int y); void SecondPreviewHover(int x, int y); void PreviewExport(const GPUDebugBuffer *buffer); - void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); - void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); + static void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); + static void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); void UpdateMenus(); u32 TexturePreviewFlags(const GPUgstate &state); @@ -93,12 +93,16 @@ private: TabStateLighting *lighting = nullptr; TabStateTexture *textureState = nullptr; TabStateSettings *settings = nullptr; + TabStateLighting *lightingRight_ = nullptr; + TabStateTexture *textureStateRight_ = nullptr; + TabStateSettings *settingsRight_ = nullptr; TabVertices *vertices = nullptr; TabMatrices *matrices = nullptr; SimpleGLWindow *primaryWindow = nullptr; SimpleGLWindow *secondWindow = nullptr; TabStateWatch *watch = nullptr; TabControl *tabs = nullptr; + TabControl *tabsRight_ = nullptr; TabControl *fbTabs = nullptr; int textureLevel_ = 0; bool showClut_ = false; diff --git a/Windows/GEDebugger/TabState.cpp b/Windows/GEDebugger/TabState.cpp index 486e6030b4..9d6735aabd 100644 --- a/Windows/GEDebugger/TabState.cpp +++ b/Windows/GEDebugger/TabState.cpp @@ -177,23 +177,25 @@ static const TabStateRow stateLightingRows[] = { }; static const TabStateRow stateTextureRows[] = { + { L"Texture L0 addr", GE_CMD_TEXADDR0, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH0 }, + { L"Texture L0 size", GE_CMD_TEXSIZE0, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { L"Tex format", GE_CMD_TEXFORMAT, CMD_FMT_TEXFMT, GE_CMD_TEXTUREMAPENABLE }, + { L"Tex CLUT", GE_CMD_CLUTADDR, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_CLUTADDRUPPER }, + { L"Tex CLUT format", GE_CMD_CLUTFORMAT, CMD_FMT_CLUTFMT, GE_CMD_TEXTUREMAPENABLE }, + { L"Tex U scale", GE_CMD_TEXSCALEU, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, { L"Tex V scale", GE_CMD_TEXSCALEV, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, { L"Tex U offset", GE_CMD_TEXOFFSETU, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, { L"Tex V offset", GE_CMD_TEXOFFSETV, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, { L"Tex mapping mode", GE_CMD_TEXMAPMODE, CMD_FMT_TEXMAPMODE, GE_CMD_TEXTUREMAPENABLE }, { L"Tex shade srcs", GE_CMD_TEXSHADELS, CMD_FMT_TEXSHADELS, GE_CMD_TEXTUREMAPENABLE }, + { L"Tex func", GE_CMD_TEXFUNC, CMD_FMT_TEXFUNC, GE_CMD_TEXTUREMAPENABLE }, + { L"Tex env color", GE_CMD_TEXENVCOLOR, CMD_FMT_HEX, GE_CMD_TEXTUREMAPENABLE }, { L"Tex mode", GE_CMD_TEXMODE, CMD_FMT_TEXMODE, GE_CMD_TEXTUREMAPENABLE }, - { L"Tex format", GE_CMD_TEXFORMAT, CMD_FMT_TEXFMT, GE_CMD_TEXTUREMAPENABLE }, { L"Tex filtering", GE_CMD_TEXFILTER, CMD_FMT_TEXFILTER, GE_CMD_TEXTUREMAPENABLE }, { L"Tex wrapping", GE_CMD_TEXWRAP, CMD_FMT_TEXWRAP, GE_CMD_TEXTUREMAPENABLE }, { L"Tex level/bias", GE_CMD_TEXLEVEL, CMD_FMT_TEXLEVEL, GE_CMD_TEXTUREMAPENABLE }, { L"Tex lod slope", GE_CMD_TEXLODSLOPE, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, - { L"Tex func", GE_CMD_TEXFUNC, CMD_FMT_TEXFUNC, GE_CMD_TEXTUREMAPENABLE }, - { L"Tex env color", GE_CMD_TEXENVCOLOR, CMD_FMT_HEX, GE_CMD_TEXTUREMAPENABLE }, - { L"CLUT", GE_CMD_CLUTADDR, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_CLUTADDRUPPER }, - { L"CLUT format", GE_CMD_CLUTFORMAT, CMD_FMT_CLUTFMT, GE_CMD_TEXTUREMAPENABLE }, - { L"Texture L0 addr", GE_CMD_TEXADDR0, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH0 }, { L"Texture L1 addr", GE_CMD_TEXADDR1, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH1 }, { L"Texture L2 addr", GE_CMD_TEXADDR2, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH2 }, { L"Texture L3 addr", GE_CMD_TEXADDR3, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH3 }, @@ -201,7 +203,6 @@ static const TabStateRow stateTextureRows[] = { { L"Texture L5 addr", GE_CMD_TEXADDR5, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH5 }, { L"Texture L6 addr", GE_CMD_TEXADDR6, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH6 }, { L"Texture L7 addr", GE_CMD_TEXADDR7, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH7 }, - { L"Texture L0 size", GE_CMD_TEXSIZE0, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, { L"Texture L1 size", GE_CMD_TEXSIZE1, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, { L"Texture L2 size", GE_CMD_TEXSIZE2, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, { L"Texture L3 size", GE_CMD_TEXSIZE3, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, @@ -212,27 +213,34 @@ static const TabStateRow stateTextureRows[] = { }; static const TabStateRow stateSettingsRows[] = { - { L"Clear mode", GE_CMD_CLEARMODE, CMD_FMT_CLEARMODE }, { L"Framebuffer", GE_CMD_FRAMEBUFPTR, CMD_FMT_PTRWIDTH, 0, GE_CMD_FRAMEBUFWIDTH }, { L"Framebuffer format", GE_CMD_FRAMEBUFPIXFORMAT, CMD_FMT_TEXFMT }, { L"Depthbuffer", GE_CMD_ZBUFPTR, CMD_FMT_PTRWIDTH, 0, GE_CMD_ZBUFWIDTH }, + { L"Viewport Scale", GE_CMD_VIEWPORTXSCALE, CMD_FMT_XYZ, 0, GE_CMD_VIEWPORTYSCALE, GE_CMD_VIEWPORTZSCALE }, + { L"Viewport Offset", GE_CMD_VIEWPORTXCENTER, CMD_FMT_XYZ, 0, GE_CMD_VIEWPORTYCENTER, GE_CMD_VIEWPORTZCENTER }, + { L"Scissor", GE_CMD_SCISSOR1, CMD_FMT_XYXY, 0, GE_CMD_SCISSOR2 }, + { L"Region", GE_CMD_REGION1, CMD_FMT_XYXY, 0, GE_CMD_REGION2 }, + { L"Color test", GE_CMD_COLORTEST, CMD_FMT_COLORTEST, GE_CMD_COLORTESTENABLE, GE_CMD_COLORREF, GE_CMD_COLORTESTMASK }, + { L"Alpha test", GE_CMD_ALPHATEST, CMD_FMT_ALPHATEST, GE_CMD_ALPHATESTENABLE }, + { L"Clear mode", GE_CMD_CLEARMODE, CMD_FMT_CLEARMODE }, + { L"Stencil test", GE_CMD_STENCILTEST, CMD_FMT_STENCILTEST, GE_CMD_STENCILTESTENABLE }, + { L"Stencil test op", GE_CMD_STENCILOP, CMD_FMT_STENCILOP, GE_CMD_STENCILTESTENABLE }, + { L"Depth test", GE_CMD_ZTEST, CMD_FMT_ZTEST, GE_CMD_ZTESTENABLE }, + { L"RGB mask", GE_CMD_MASKRGB, CMD_FMT_HEX }, + { L"Stencil/alpha mask", GE_CMD_MASKALPHA, CMD_FMT_HEX }, + { L"Transfer src", GE_CMD_TRANSFERSRC, CMD_FMT_PTRWIDTH, 0, GE_CMD_TRANSFERSRCW }, + { L"Transfer src pos", GE_CMD_TRANSFERSRCPOS, CMD_FMT_XY }, + { L"Transfer dst", GE_CMD_TRANSFERDST, CMD_FMT_PTRWIDTH, 0, GE_CMD_TRANSFERDSTW }, + { L"Transfer dst pos", GE_CMD_TRANSFERDSTPOS, CMD_FMT_XY }, + { L"Transfer size", GE_CMD_TRANSFERSIZE, CMD_FMT_XY }, { L"Vertex type", GE_CMD_VERTEXTYPE, CMD_FMT_VERTEXTYPE }, { L"Offset addr", GE_CMD_OFFSETADDR, CMD_FMT_OFFSETADDR }, { L"Vertex addr", GE_CMD_VADDR, CMD_FMT_VADDR }, { L"Index addr", GE_CMD_IADDR, CMD_FMT_IADDR }, - { L"Region", GE_CMD_REGION1, CMD_FMT_XYXY, 0, GE_CMD_REGION2 }, - { L"Scissor", GE_CMD_SCISSOR1, CMD_FMT_XYXY, 0, GE_CMD_SCISSOR2 }, { L"Min Z", GE_CMD_MINZ, CMD_FMT_HEX }, { L"Max Z", GE_CMD_MAXZ, CMD_FMT_HEX }, - { L"Viewport Scale", GE_CMD_VIEWPORTXSCALE, CMD_FMT_XYZ, 0, GE_CMD_VIEWPORTYSCALE, GE_CMD_VIEWPORTZSCALE }, - { L"Viewport Offset", GE_CMD_VIEWPORTXCENTER, CMD_FMT_XYZ, 0, GE_CMD_VIEWPORTYCENTER, GE_CMD_VIEWPORTZCENTER }, { L"Offset", GE_CMD_OFFSETX, CMD_FMT_F16_XY, 0, GE_CMD_OFFSETY }, { L"Cull mode", GE_CMD_CULL, CMD_FMT_CULL, GE_CMD_CULLFACEENABLE }, - { L"Color test", GE_CMD_COLORTEST, CMD_FMT_COLORTEST, GE_CMD_COLORTESTENABLE, GE_CMD_COLORREF, GE_CMD_COLORTESTMASK }, - { L"Alpha test", GE_CMD_ALPHATEST, CMD_FMT_ALPHATEST, GE_CMD_ALPHATESTENABLE }, - { L"Stencil test", GE_CMD_STENCILTEST, CMD_FMT_STENCILTEST, GE_CMD_STENCILTESTENABLE }, - { L"Stencil test op", GE_CMD_STENCILOP, CMD_FMT_STENCILOP, GE_CMD_STENCILTESTENABLE }, - { L"Depth test", GE_CMD_ZTEST, CMD_FMT_ZTEST, GE_CMD_ZTESTENABLE }, { L"Alpha blend mode", GE_CMD_BLENDMODE, CMD_FMT_BLENDMODE, GE_CMD_ALPHABLENDENABLE }, { L"Blend color A", GE_CMD_BLENDFIXEDA, CMD_FMT_HEX, GE_CMD_ALPHABLENDENABLE }, { L"Blend color B", GE_CMD_BLENDFIXEDB, CMD_FMT_HEX, GE_CMD_ALPHABLENDENABLE }, @@ -240,8 +248,6 @@ static const TabStateRow stateSettingsRows[] = { { L"Fog 1", GE_CMD_FOG1, CMD_FMT_FLOAT24, GE_CMD_FOGENABLE }, { L"Fog 2", GE_CMD_FOG2, CMD_FMT_FLOAT24, GE_CMD_FOGENABLE }, { L"Fog color", GE_CMD_FOGCOLOR, CMD_FMT_HEX, GE_CMD_FOGENABLE }, - { L"RGB mask", GE_CMD_MASKRGB, CMD_FMT_HEX }, - { L"Stencil/alpha mask", GE_CMD_MASKALPHA, CMD_FMT_HEX }, { L"Morph Weight 0", GE_CMD_MORPHWEIGHT0, CMD_FMT_FLOAT24 }, { L"Morph Weight 1", GE_CMD_MORPHWEIGHT1, CMD_FMT_FLOAT24 }, { L"Morph Weight 2", GE_CMD_MORPHWEIGHT2, CMD_FMT_FLOAT24 }, @@ -259,11 +265,6 @@ static const TabStateRow stateSettingsRows[] = { { L"Dither 1", GE_CMD_DITH1, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, { L"Dither 2", GE_CMD_DITH2, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, { L"Dither 3", GE_CMD_DITH3, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, - { L"Transfer src", GE_CMD_TRANSFERSRC, CMD_FMT_PTRWIDTH, 0, GE_CMD_TRANSFERSRCW }, - { L"Transfer src pos", GE_CMD_TRANSFERSRCPOS, CMD_FMT_XY }, - { L"Transfer dst", GE_CMD_TRANSFERDST, CMD_FMT_PTRWIDTH, 0, GE_CMD_TRANSFERDSTW }, - { L"Transfer dst pos", GE_CMD_TRANSFERDSTPOS, CMD_FMT_XY }, - { L"Transfer size", GE_CMD_TRANSFERSIZE, CMD_FMT_XY }, }; // TODO: Commands not present in the above lists (some because they don't have meaningful values...): @@ -1013,7 +1014,7 @@ void CtrlStateValues::OnRightClick(int row, int column, const POINT &point) { } bool CtrlStateValues::OnRowPrePaint(int row, LPNMLVCUSTOMDRAW msg) { - if (RowValuesChanged(row)) { + if (gpuDebug && RowValuesChanged(row)) { msg->clrText = RGB(255, 0, 0); return true; } diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index b306c1a7f5..cbfb3727b4 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -212,7 +212,8 @@ BEGIN PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,444,2,44,14 CONTROL "",IDC_GEDBG_TEX,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,10,20,128,128 CONTROL "",IDC_GEDBG_FRAME,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,148,20,256,136 - CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,10,216,480,180 + CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,10,216,280,180 + CONTROL "",IDC_GEDBG_RIGHTTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,210,216,280,180 EDITTEXT IDC_GEDBG_FRAMEBUFADDR,148,192,200,12,ES_READONLY | NOT WS_BORDER EDITTEXT IDC_GEDBG_TEXADDR,10,152,128,12,ES_READONLY | NOT WS_BORDER CONTROL "Force opaque",IDC_GEDBG_FORCEOPAQUE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,164,60,12 diff --git a/Windows/resource.h b/Windows/resource.h index 29879fdc57..2b30032234 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -264,7 +264,6 @@ #define ID_OPTIONS_BUFLINEARFILTER 40152 #define ID_OPTIONS_BUFNEARESTFILTER 40153 #define ID_OPTIONS_DIRECT3D9 40154 -#define ID_OPTIONS_DIRECT3D11 40169 #define ID_OPTIONS_OPENGL 40155 #define ID_EMULATION_ROTATION_H 40156 #define ID_EMULATION_ROTATION_V 40157 @@ -326,6 +325,9 @@ #define IDC_GEDBG_FLUSHAUTO 40213 #define IDI_BREAKPOINT_SMALL 40214 #define IDC_GEDBG_SETPRIMFILTER 40215 +#define IDC_GEDBG_RIGHTTAB 40216 +#define ID_OPTIONS_DIRECT3D11 40217 + // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 From 8cb7d9cd9f3ab406e7c6bfab31e9b219860467ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 12 Aug 2022 21:33:02 +0200 Subject: [PATCH 02/15] Pause the debugger on TRANSFERSTART (treat that as a prim) --- GPU/Debugger/Debugger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 04fb647f1d..28dc194b74 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -111,7 +111,7 @@ bool NotifyCommand(u32 pc) { } bool process = true; - if (cmd == GE_CMD_PRIM || cmd == GE_CMD_BEZIER || cmd == GE_CMD_SPLINE) { + if (cmd == GE_CMD_PRIM || cmd == GE_CMD_BEZIER || cmd == GE_CMD_SPLINE || cmd == GE_CMD_TRANSFERSTART) { primsThisFrame++; if (!restrictPrimRanges.empty()) { From 5993864d8f628eb587027f2872bba74692c4b7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Aug 2022 11:15:07 +0200 Subject: [PATCH 03/15] Add plain Create method to CtrlDisplayListView --- Windows/GEDebugger/CtrlDisplayListView.cpp | 12 ++++++++++++ Windows/GEDebugger/CtrlDisplayListView.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 296851c630..4a0e9095a3 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -3,6 +3,7 @@ #include "Common/System/Display.h" #include "Windows/GEDebugger/CtrlDisplayListView.h" #include "Windows/GEDebugger/GEDebugger.h" +#include "Windows/MainWindow.h" #include "Windows/InputBox.h" #include "Windows/W32Util/ContextMenu.h" #include "Windows/main.h" @@ -70,6 +71,17 @@ CtrlDisplayListView *CtrlDisplayListView::getFrom(HWND hwnd) return (CtrlDisplayListView*) GetWindowLongPtr(hwnd, GWLP_USERDATA); } +CtrlDisplayListView *CtrlDisplayListView::Create(HWND parentWnd) { + DWORD style = WS_CHILD; + RECT tabRect{ 0, 0, 100, 100 }; + + HWND hWnd = CreateWindowEx(0, windowClass, L"", style, + tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, + parentWnd, 0, MainWindow::GetHInstance(), 0); + + return new CtrlDisplayListView(hWnd); +} + LRESULT CALLBACK CtrlDisplayListView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CtrlDisplayListView *win = CtrlDisplayListView::getFrom(hwnd); diff --git a/Windows/GEDebugger/CtrlDisplayListView.h b/Windows/GEDebugger/CtrlDisplayListView.h index fe605f799e..4112b91f93 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.h +++ b/Windows/GEDebugger/CtrlDisplayListView.h @@ -36,6 +36,8 @@ public: static void registerClass(); static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static CtrlDisplayListView * getFrom(HWND wnd); + + CtrlDisplayListView *Create(HWND parentWnd); HWND GetHWND() { return wnd; From 60b2b1db5f193ecbcf8107f4b52a6b02ec16ff86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Aug 2022 11:26:51 +0200 Subject: [PATCH 04/15] Move the display list view to its own column on the right --- Windows/GEDebugger/CtrlDisplayListView.cpp | 4 ++-- Windows/GEDebugger/CtrlDisplayListView.h | 2 +- Windows/GEDebugger/GEDebugger.cpp | 14 +++++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 4a0e9095a3..188884a292 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -72,10 +72,10 @@ CtrlDisplayListView *CtrlDisplayListView::getFrom(HWND hwnd) } CtrlDisplayListView *CtrlDisplayListView::Create(HWND parentWnd) { - DWORD style = WS_CHILD; + DWORD style = WS_CHILD | WS_VISIBLE | WS_BORDER; RECT tabRect{ 0, 0, 100, 100 }; - HWND hWnd = CreateWindowEx(0, windowClass, L"", style, + HWND hWnd = CreateWindowEx(0, windowClass, L"Display List", style, tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, parentWnd, 0, MainWindow::GetHInstance(), 0); diff --git a/Windows/GEDebugger/CtrlDisplayListView.h b/Windows/GEDebugger/CtrlDisplayListView.h index 4112b91f93..73d96b2c12 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.h +++ b/Windows/GEDebugger/CtrlDisplayListView.h @@ -37,7 +37,7 @@ public: static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static CtrlDisplayListView * getFrom(HWND wnd); - CtrlDisplayListView *Create(HWND parentWnd); + static CtrlDisplayListView *Create(HWND parentWnd); HWND GetHWND() { return wnd; diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 16aa373b68..18ccc1823f 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -141,7 +141,6 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) // up both the size and the aspect ratio RECT frameRect; HWND frameWnd = GetDlgItem(m_hDlg,IDC_GEDBG_FRAME); - GetWindowRect(frameWnd,&frameRect); MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&frameRect,2); MoveWindow(frameWnd,frameRect.left,frameRect.top,512,272,TRUE); @@ -149,8 +148,8 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) tabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_MAINTAB)); tabsRight_ = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_RIGHTTAB)); - HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView", L"Display List"); - displayList = CtrlDisplayListView::getFrom(wnd); + // HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView", L"Display List"); + displayList = CtrlDisplayListView::Create(m_hDlg); fbTabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_FBTABS)); fbTabs->SetMinTabWidth(50); @@ -731,9 +730,18 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { RECT tabRectRight = tabRect; tabRectRight.left += tabRect.right; tabRectRight.right += tabRect.right; + + RECT frameRect; + HWND frameWnd = GetDlgItem(m_hDlg, IDC_GEDBG_FRAME); + GetWindowRect(frameWnd, &frameRect); + RECT listRect = { frameRect.right + 10, 40, tabRectRight.right, tabRect.top }; + MoveWindow(tabControl, tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, TRUE); MoveWindow(tabControlRight, tabRectRight.left, tabRectRight.top, tabRectRight.right - tabRectRight.left, tabRectRight.bottom - tabRectRight.top, TRUE); + if (displayList) { + MoveWindow(displayList->GetHWND(), listRect.left, listRect.top, listRect.right - listRect.left, listRect.bottom - listRect.top, TRUE); + } } void CGEDebugger::SavePosition() { From 2a0f23665f95b081d36e286d33026f574ceb02ec Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 09:12:57 -0700 Subject: [PATCH 05/15] GE Debugger: Track tabs per panel. --- Windows/GEDebugger/GEDebugger.cpp | 195 +++++++++++++++++++----------- Windows/GEDebugger/GEDebugger.h | 46 +++++-- Windows/GEDebugger/TabState.h | 2 +- Windows/W32Util/DialogManager.h | 4 +- Windows/W32Util/TabControl.cpp | 15 +++ Windows/W32Util/TabControl.h | 5 + Windows/ppsspp.rc | 3 +- Windows/resource.h | 3 +- 8 files changed, 182 insertions(+), 91 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 18ccc1823f..bec47dee0a 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -59,6 +59,53 @@ enum PrimaryDisplayType { PRIMARY_STENCILBUF, }; +static void *AddDisplayListTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, HINSTANCE inst, HWND parent) { + HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView", tab->name); + return CtrlDisplayListView::getFrom(wnd); +} + +static void RemoveDisplayListTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr) { + CtrlDisplayListView *view = (CtrlDisplayListView *)ptr; + DestroyWindow(view->GetHWND()); +} + +static void UpdateDisplayListTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr) { + CtrlDisplayListView *view = (CtrlDisplayListView *)ptr; + DisplayList list; + if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) { + view->setDisplayList(list); + } +} + +template +static void *AddStateTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, HINSTANCE inst, HWND parent) { + T *w = new T(inst, parent); + tabs->AddTabDialog(w, tab->name); + return w; +} + +static void RemoveStateTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr) { + Dialog *view = (Dialog *)ptr; + delete view; +} + +static void UpdateStateTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr) { + Dialog *view = (Dialog *)ptr; + view->Update(); +} + +static const std::vector defaultTabs = { + { L"Display List", GETabPosition::LEFT, GETabType::LIST_DISASM, {}, &AddDisplayListTab, &RemoveDisplayListTab, &UpdateDisplayListTab }, + { L"Flags", GETabPosition::LEFT, GETabType::STATE, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Light", GETabPosition::LEFT, GETabType::STATE, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Texture", GETabPosition::LEFT, GETabType::STATE, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Settings", GETabPosition::LEFT, GETabType::STATE, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Verts", GETabPosition::LEFT, GETabType::STATE, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Matrices", GETabPosition::LEFT, GETabType::STATE, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Lists", GETabPosition::LEFT, GETabType::LISTS, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, + { L"Watch", GETabPosition::LEFT, GETabType::WATCH, {}, &AddStateTab, &RemoveStateTab, &UpdateStateTab }, +}; + StepCountDlg::StepCountDlg(HINSTANCE _hInstance, HWND _hParent) : Dialog((LPCSTR)IDD_GEDBG_STEPCOUNT, _hInstance, _hParent) { DialogManager::AddDlg(this); @@ -147,9 +194,7 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) tabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_MAINTAB)); tabsRight_ = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_RIGHTTAB)); - - // HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView", L"Display List"); - displayList = CtrlDisplayListView::Create(m_hDlg); + tabsTR_ = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_TOPRIGHTTAB)); fbTabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_FBTABS)); fbTabs->SetMinTabWidth(50); @@ -159,43 +204,17 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) fbTabs->AddTab(NULL, L"Stencil"); fbTabs->ShowTab(0, true); - flags = new TabStateFlags(_hInstance, m_hDlg); - tabs->AddTabDialog(flags, L"Flags"); + tabStates_ = defaultTabs; + for (GEDebuggerTab &tabState : tabStates_) { + AddTab(&tabState, tabState.pos); + } - lighting = new TabStateLighting(_hInstance, m_hDlg); - tabs->AddTabDialog(lighting, L"Light"); - - textureState = new TabStateTexture(_hInstance, m_hDlg); - tabs->AddTabDialog(textureState, L"Texture"); - - settings = new TabStateSettings(_hInstance, m_hDlg); - tabs->AddTabDialog(settings, L"Settings"); - - vertices = new TabVertices(_hInstance, m_hDlg); - tabs->AddTabDialog(vertices, L"Verts"); - - matrices = new TabMatrices(_hInstance, m_hDlg); - tabs->AddTabDialog(matrices, L"Matrices"); - - lists = new TabDisplayLists(_hInstance, m_hDlg); - tabs->AddTabDialog(lists, L"Lists"); - - watch = new TabStateWatch(_hInstance, m_hDlg); - tabs->AddTabDialog(watch, L"Watch"); - - tabs->ShowTab(0, true); - - - lightingRight_ = new TabStateLighting(_hInstance, m_hDlg); - tabsRight_->AddTabDialog(lightingRight_, L"Light"); - - textureStateRight_ = new TabStateTexture(_hInstance, m_hDlg); - tabsRight_->AddTabDialog(textureStateRight_, L"Texture"); - - settingsRight_ = new TabStateSettings(_hInstance, m_hDlg); - tabsRight_->AddTabDialog(settingsRight_, L"Settings"); - - tabsRight_->ShowTab(0, true); + if (tabs->Count() > 0) + tabs->ShowTab(0, true); + if (tabsRight_->Count() > 0) + tabsRight_->ShowTab(0, true); + if (tabsTR_->Count() > 0) + tabsTR_->ShowTab(0, true); // set window position int x = g_Config.iGEWindowX == -1 ? windowRect.left : g_Config.iGEWindowX; @@ -211,19 +230,14 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) CGEDebugger::~CGEDebugger() { CleanupPrimPreview(); - delete flags; - delete lighting; - delete lightingRight_; - delete textureState; - delete textureStateRight_; - delete settings; - delete settingsRight_; - delete vertices; - delete matrices; - delete lists; - delete watch; + + for (GEDebuggerTab &tabState : tabStates_) { + RemoveTab(&tabState, GETabPosition::ALL); + } + delete tabs; delete tabsRight_; + delete tabsTR_; delete fbTabs; } @@ -370,29 +384,56 @@ void CGEDebugger::UpdatePreviews() { UpdatePrimPreview(primOp, 3); } - DisplayList list; - if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) { - displayList->setDisplayList(list); - } - wchar_t primCounter[1024]{}; swprintf(primCounter, ARRAY_SIZE(primCounter), L"%d/%d", PrimsThisFrame(), PrimsLastFrame()); SetDlgItemText(m_hDlg, IDC_GEDBG_PRIMCOUNTER, primCounter); - flags->Update(); - lighting->Update(); - lightingRight_->Update(); - textureState->Update(); - textureStateRight_->Update(); - settings->Update(); - settingsRight_->Update(); - vertices->Update(); - matrices->Update(); - lists->Update(); - watch->Update(); + for (GEDebuggerTab &tabState : tabStates_) { + UpdateTab(&tabState); + } + updating_ = false; } +void CGEDebugger::UpdateTab(GEDebuggerTab *tab) { + auto doUpdate = [&](GETabPosition pos, TabControl *t, int index) { + if (tab->pos & pos) + tab->update(tab, t, pos, tab->state[index].ptr); + }; + + doUpdate(GETabPosition::LEFT, tabs, 0); + doUpdate(GETabPosition::RIGHT, tabsRight_, 1); + doUpdate(GETabPosition::TOPRIGHT, tabsTR_, 2); +} + +void CGEDebugger::AddTab(GEDebuggerTab *tab, GETabPosition mask) { + auto doAdd = [&](GETabPosition pos, TabControl *t, int index) { + // On init, we still have nullptr, but already have pos, so we use that. + if ((mask & pos) && tab->state[index].ptr == nullptr) { + tab->state[index].ptr = tab->add(tab, t, pos, m_hInstance, m_hDlg); + tab->pos |= pos; + } + }; + + doAdd(GETabPosition::LEFT, tabs, 0); + doAdd(GETabPosition::RIGHT, tabsRight_, 1); + doAdd(GETabPosition::TOPRIGHT, tabsTR_, 2); +} + +void CGEDebugger::RemoveTab(GEDebuggerTab *tab, GETabPosition mask) { + auto doRemove = [&](GETabPosition pos, TabControl *t, int index) { + if ((tab->pos & pos) && (mask & pos)) { + _assert_(tab->state[index].ptr != nullptr); + tab->remove(tab, t, pos, tab->state[index].ptr); + tab->pos = GETabPosition((int)tab->pos & ~(int)pos); + } + }; + + doRemove(GETabPosition::LEFT, tabs, 0); + doRemove(GETabPosition::RIGHT, tabsRight_, 1); + doRemove(GETabPosition::TOPRIGHT, tabsTR_, 2); +} + u32 CGEDebugger::TexturePreviewFlags(const GPUgstate &state) { if (state.isTextureAlphaUsed() && !forceOpaque_) { return SimpleGLWindow::ALPHA_BLEND | SimpleGLWindow::RESIZE_BEST_CENTER; @@ -719,6 +760,7 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { // only resize the tabs for now HWND tabControl = GetDlgItem(m_hDlg, IDC_GEDBG_MAINTAB); HWND tabControlRight = GetDlgItem(m_hDlg, IDC_GEDBG_RIGHTTAB); + HWND tabControlTR = GetDlgItem(m_hDlg, IDC_GEDBG_TOPRIGHTTAB); RECT tabRect; GetWindowRect(tabControl,&tabRect); @@ -734,14 +776,13 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { RECT frameRect; HWND frameWnd = GetDlgItem(m_hDlg, IDC_GEDBG_FRAME); GetWindowRect(frameWnd, &frameRect); + MapWindowPoints(HWND_DESKTOP, m_hDlg, (LPPOINT)&frameRect, 2); - RECT listRect = { frameRect.right + 10, 40, tabRectRight.right, tabRect.top }; + RECT trRect = { frameRect.right + 10, frameRect.top, tabRectRight.right, tabRectRight.top }; MoveWindow(tabControl, tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, TRUE); MoveWindow(tabControlRight, tabRectRight.left, tabRectRight.top, tabRectRight.right - tabRectRight.left, tabRectRight.bottom - tabRectRight.top, TRUE); - if (displayList) { - MoveWindow(displayList->GetHWND(), listRect.left, listRect.top, listRect.right - listRect.left, listRect.bottom - listRect.top, TRUE); - } + MoveWindow(tabControlTR, trRect.left, trRect.top, trRect.right - trRect.left, trRect.bottom - trRect.top, TRUE); } void CGEDebugger::SavePosition() { @@ -810,12 +851,18 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case IDC_GEDBG_MAINTAB: tabs->HandleNotify(lParam); if (gpuDebug != nullptr) { - lists->Update(); + for (GEDebuggerTab &tabState : tabStates_) { + if (tabState.type == GETabType::LISTS) + UpdateTab(&tabState); + } } break; case IDC_GEDBG_RIGHTTAB: tabsRight_->HandleNotify(lParam); break; + case IDC_GEDBG_TOPRIGHTTAB: + tabsTR_->HandleNotify(lParam); + break; case IDC_GEDBG_FBTABS: fbTabs->HandleNotify(lParam); if (GPUDebug::IsActive() && gpuDebug != nullptr) { @@ -996,8 +1043,10 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { case WM_GEDBG_UPDATE_WATCH: // Just a notification to update. - if (watch) - watch->Update(); + for (GEDebuggerTab &tabState : tabStates_) { + if (tabState.type == GETabType::WATCH) + UpdateTab(&tabState); + } break; } diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index 7dabf9c63c..0e716f1adc 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -44,6 +44,35 @@ class TabMatrices; class TabStateWatch; struct GPUgstate; +enum class GETabPosition { + LEFT = 1, + RIGHT = 2, + TOPRIGHT = 4, + ALL = 7, +}; +ENUM_CLASS_BITOPS(GETabPosition); + +enum class GETabType { + LIST_DISASM, + LISTS, + STATE, + WATCH, +}; + +struct GEDebuggerTab { + const wchar_t *name; + GETabPosition pos; + GETabType type; + union { + Dialog *dlg; + CtrlDisplayListView *displayList; + void *ptr; + } state[3]; + void *(*add)(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, HINSTANCE inst, HWND parent); + void (*remove)(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr); + void (*update)(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr); +}; + class StepCountDlg : public Dialog { public: StepCountDlg(HINSTANCE _hInstance, HWND _hParent); @@ -84,25 +113,18 @@ private: static void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); static void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, char desc[256]); void UpdateMenus(); + void UpdateTab(GEDebuggerTab *tab); + void AddTab(GEDebuggerTab *tab, GETabPosition mask); + void RemoveTab(GEDebuggerTab *tab, GETabPosition mask); u32 TexturePreviewFlags(const GPUgstate &state); - CtrlDisplayListView *displayList = nullptr; - TabDisplayLists *lists = nullptr; - TabStateFlags *flags = nullptr; - TabStateLighting *lighting = nullptr; - TabStateTexture *textureState = nullptr; - TabStateSettings *settings = nullptr; - TabStateLighting *lightingRight_ = nullptr; - TabStateTexture *textureStateRight_ = nullptr; - TabStateSettings *settingsRight_ = nullptr; - TabVertices *vertices = nullptr; - TabMatrices *matrices = nullptr; SimpleGLWindow *primaryWindow = nullptr; SimpleGLWindow *secondWindow = nullptr; - TabStateWatch *watch = nullptr; + std::vector tabStates_; TabControl *tabs = nullptr; TabControl *tabsRight_ = nullptr; + TabControl *tabsTR_ = nullptr; TabControl *fbTabs = nullptr; int textureLevel_ = 0; bool showClut_ = false; diff --git a/Windows/GEDebugger/TabState.h b/Windows/GEDebugger/TabState.h index c60c849028..dbc1558fa0 100644 --- a/Windows/GEDebugger/TabState.h +++ b/Windows/GEDebugger/TabState.h @@ -57,7 +57,7 @@ public: TabStateValues(const TabStateRow *rows, int rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent); ~TabStateValues(); - virtual void Update() { + void Update() override { values->Update(); } diff --git a/Windows/W32Util/DialogManager.h b/Windows/W32Util/DialogManager.h index fc943b3ddd..55497223ac 100644 --- a/Windows/W32Util/DialogManager.h +++ b/Windows/W32Util/DialogManager.h @@ -18,6 +18,7 @@ protected: virtual void Create(); void Destroy(); + HINSTANCE m_hInstance; HWND m_hParent; HWND m_hDlg; LPCSTR m_hResource; @@ -26,9 +27,6 @@ protected: virtual BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam) = 0; static INT_PTR CALLBACK DlgProcStatic(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); - -private: - HINSTANCE m_hInstance; }; diff --git a/Windows/W32Util/TabControl.cpp b/Windows/W32Util/TabControl.cpp index 2d315213df..8721a9637c 100644 --- a/Windows/W32Util/TabControl.cpp +++ b/Windows/W32Util/TabControl.cpp @@ -93,6 +93,21 @@ void TabControl::AddTab(HWND handle, const wchar_t* title) ShowTab(index); } +HWND TabControl::RemoveTab(int index) { + int prevIndex = CurrentTabIndex(); + if (currentTab >= index) + --currentTab; + + HWND prevHandle = tabs[index].pageHandle; + TabCtrl_DeleteItem(hwnd, index); + tabs.erase(tabs.begin() + index); + + if (prevIndex == index) + ShowTab(currentTab, true); + + return prevHandle; +} + int TabControl::AppendPageToControl(const wchar_t *title) { TCITEM tcItem; diff --git a/Windows/W32Util/TabControl.h b/Windows/W32Util/TabControl.h index 7eb2360dcf..c8212af004 100644 --- a/Windows/W32Util/TabControl.h +++ b/Windows/W32Util/TabControl.h @@ -14,6 +14,7 @@ public: HWND AddTabWindow(const wchar_t* className, const wchar_t* title, DWORD style = 0); void AddTabDialog(Dialog* dialog, const wchar_t* title); void AddTab(HWND hwnd, const wchar_t* title); + HWND RemoveTab(int index); void ShowTab(int index, bool setControlIndex = true); void ShowTab(HWND pageHandle); void NextTab(bool cycle); @@ -30,6 +31,10 @@ public: bool GetShowTabTitles() { return showTabTitles; } void SetMinTabWidth(int w); + int Count() { + return (int)tabs.size(); + } + private: static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); void OnResize(); diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index cbfb3727b4..80a6295986 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -196,7 +196,7 @@ BEGIN CONTROL "",IDC_DEBUG_BOTTOMTABS,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,1,338,513,93 END -IDD_GEDEBUGGER DIALOGEX 0, 0, 500, 400 +IDD_GEDEBUGGER DIALOGEX 0, 0, 490, 400 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW CAPTION "GE" @@ -212,6 +212,7 @@ BEGIN PUSHBUTTON "&Resume",IDC_GEDBG_RESUME,444,2,44,14 CONTROL "",IDC_GEDBG_TEX,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,10,20,128,128 CONTROL "",IDC_GEDBG_FRAME,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,148,20,256,136 + CONTROL "",IDC_GEDBG_TOPRIGHTTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,500,20,280,136 CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,10,216,280,180 CONTROL "",IDC_GEDBG_RIGHTTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,210,216,280,180 EDITTEXT IDC_GEDBG_FRAMEBUFADDR,148,192,200,12,ES_READONLY | NOT WS_BORDER diff --git a/Windows/resource.h b/Windows/resource.h index 2b30032234..7cbe5bf9df 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -327,6 +327,7 @@ #define IDC_GEDBG_SETPRIMFILTER 40215 #define IDC_GEDBG_RIGHTTAB 40216 #define ID_OPTIONS_DIRECT3D11 40217 +#define IDC_GEDBG_TOPRIGHTTAB 40218 // Dummy option to let the buffered rendering hotkey cycle through all the options. @@ -340,7 +341,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40216 +#define _APS_NEXT_COMMAND_VALUE 40219 #define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif From 5958943e236753d5e1116e09bc17f65bc77c21fa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 09:32:35 -0700 Subject: [PATCH 06/15] GE Debugger: Show/hide tabs if empty. --- Windows/GEDebugger/GEDebugger.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index bec47dee0a..a1ae45d671 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -766,12 +766,22 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { GetWindowRect(tabControl,&tabRect); MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&tabRect,2); - tabRect.right = tabRect.left + (width / 2-tabRect.left*2); // assume same gap on both sides - tabRect.bottom = tabRect.top + (height-tabRect.top-tabRect.left); // assume same gap on bottom too + // Assume the same gap (tabRect.left) on all sides. + if (tabsTR_ && tabsTR_->Count() == 0) { + tabRect.right = tabRect.left + (width - tabRect.left * 2); + } else { + tabRect.right = tabRect.left + (width / 2 - tabRect.left * 2); + } + tabRect.bottom = tabRect.top + (height - tabRect.top - tabRect.left); RECT tabRectRight = tabRect; - tabRectRight.left += tabRect.right; - tabRectRight.right += tabRect.right; + if (tabs && tabsTR_ && tabs->Count() == 0 && tabsTR_->Count() != 0) { + tabRect.right = tabRect.left; + tabRect.bottom = tabRect.top; + } else { + tabRectRight.left += tabRect.right; + tabRectRight.right += tabRect.right; + } RECT frameRect; HWND frameWnd = GetDlgItem(m_hDlg, IDC_GEDBG_FRAME); @@ -779,6 +789,10 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { MapWindowPoints(HWND_DESKTOP, m_hDlg, (LPPOINT)&frameRect, 2); RECT trRect = { frameRect.right + 10, frameRect.top, tabRectRight.right, tabRectRight.top }; + if (tabsTR_ && tabsTR_->Count() == 0) { + trRect.right = trRect.left; + trRect.bottom = trRect.top; + } MoveWindow(tabControl, tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, TRUE); MoveWindow(tabControlRight, tabRectRight.left, tabRectRight.top, tabRectRight.right - tabRectRight.left, tabRectRight.bottom - tabRectRight.top, TRUE); From 49679c6a50944dab11dc5c0f137fcbb8423b6d41 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 10:16:16 -0700 Subject: [PATCH 07/15] GE Debugger: Add context menu to control tabs. Crurent non-functional, but shows up for the correct tab. --- Windows/GEDebugger/GEDebugger.cpp | 116 ++++++++++++++++++++++++++---- Windows/GEDebugger/GEDebugger.h | 13 ++-- Windows/W32Util/ContextMenu.h | 1 + Windows/W32Util/TabControl.cpp | 8 +++ Windows/W32Util/TabControl.h | 1 + Windows/ppsspp.rc | 6 ++ Windows/resource.h | 5 +- 7 files changed, 132 insertions(+), 18 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index a1ae45d671..9c30abb1d1 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -59,6 +59,13 @@ enum PrimaryDisplayType { PRIMARY_STENCILBUF, }; +enum class GEPanelIndex { + LEFT, + RIGHT, + TOPRIGHT, + COUNT, +}; + static void *AddDisplayListTab(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, HINSTANCE inst, HWND parent) { HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView", tab->name); return CtrlDisplayListView::getFrom(wnd); @@ -396,42 +403,64 @@ void CGEDebugger::UpdatePreviews() { } void CGEDebugger::UpdateTab(GEDebuggerTab *tab) { - auto doUpdate = [&](GETabPosition pos, TabControl *t, int index) { + auto doUpdate = [&](GETabPosition pos, TabControl *t, GEPanelIndex index) { if (tab->pos & pos) - tab->update(tab, t, pos, tab->state[index].ptr); + tab->update(tab, t, pos, tab->state[(int)index].ptr); }; - doUpdate(GETabPosition::LEFT, tabs, 0); - doUpdate(GETabPosition::RIGHT, tabsRight_, 1); - doUpdate(GETabPosition::TOPRIGHT, tabsTR_, 2); + doUpdate(GETabPosition::LEFT, tabs, GEPanelIndex::LEFT); + doUpdate(GETabPosition::RIGHT, tabsRight_, GEPanelIndex::RIGHT); + doUpdate(GETabPosition::TOPRIGHT, tabsTR_, GEPanelIndex::TOPRIGHT); } void CGEDebugger::AddTab(GEDebuggerTab *tab, GETabPosition mask) { - auto doAdd = [&](GETabPosition pos, TabControl *t, int index) { + auto doAdd = [&](GETabPosition pos, TabControl *t, GEPanelIndex pindex) { + int index = (int)pindex; // On init, we still have nullptr, but already have pos, so we use that. if ((mask & pos) && tab->state[index].ptr == nullptr) { + tab->state[index].index = t->Count(); tab->state[index].ptr = tab->add(tab, t, pos, m_hInstance, m_hDlg); tab->pos |= pos; } }; - doAdd(GETabPosition::LEFT, tabs, 0); - doAdd(GETabPosition::RIGHT, tabsRight_, 1); - doAdd(GETabPosition::TOPRIGHT, tabsTR_, 2); + doAdd(GETabPosition::LEFT, tabs, GEPanelIndex::LEFT); + doAdd(GETabPosition::RIGHT, tabsRight_, GEPanelIndex::RIGHT); + doAdd(GETabPosition::TOPRIGHT, tabsTR_, GEPanelIndex::TOPRIGHT); } void CGEDebugger::RemoveTab(GEDebuggerTab *tab, GETabPosition mask) { - auto doRemove = [&](GETabPosition pos, TabControl *t, int index) { + auto doRemove = [&](GETabPosition pos, TabControl *t, GEPanelIndex pindex) { + int index = (int)pindex; if ((tab->pos & pos) && (mask & pos)) { _assert_(tab->state[index].ptr != nullptr); tab->remove(tab, t, pos, tab->state[index].ptr); tab->pos = GETabPosition((int)tab->pos & ~(int)pos); + tab->state[index].index = -1; } }; - doRemove(GETabPosition::LEFT, tabs, 0); - doRemove(GETabPosition::RIGHT, tabsRight_, 1); - doRemove(GETabPosition::TOPRIGHT, tabsTR_, 2); + doRemove(GETabPosition::LEFT, tabs, GEPanelIndex::LEFT); + doRemove(GETabPosition::RIGHT, tabsRight_, GEPanelIndex::RIGHT); + doRemove(GETabPosition::TOPRIGHT, tabsTR_, GEPanelIndex::TOPRIGHT); +} + +int CGEDebugger::HasTabIndex(GEDebuggerTab *tab, GETabPosition pos) { + int stateIndex = 0; + switch (pos) { + case GETabPosition::LEFT: stateIndex = (int)GEPanelIndex::LEFT; break; + case GETabPosition::RIGHT: stateIndex = (int)GEPanelIndex::RIGHT; break; + case GETabPosition::TOPRIGHT: stateIndex = (int)GEPanelIndex::TOPRIGHT; break; + default: _assert_msg_(false, "Invalid GE tab position"); break; + } + + if (tab->pos & pos) { + auto &state = tab->state[stateIndex]; + if (state.ptr == nullptr) + return -1; + return state.index; + } + return -1; } u32 CGEDebugger::TexturePreviewFlags(const GPUgstate &state) { @@ -870,12 +899,15 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { UpdateTab(&tabState); } } + CheckTabMessage(tabs, GETabPosition::LEFT, lParam); break; case IDC_GEDBG_RIGHTTAB: tabsRight_->HandleNotify(lParam); + CheckTabMessage(tabsRight_, GETabPosition::RIGHT, lParam); break; case IDC_GEDBG_TOPRIGHTTAB: tabsTR_->HandleNotify(lParam); + CheckTabMessage(tabsTR_, GETabPosition::TOPRIGHT, lParam); break; case IDC_GEDBG_FBTABS: fbTabs->HandleNotify(lParam); @@ -1067,6 +1099,64 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { return FALSE; } +void CGEDebugger::CheckTabMessage(TabControl *t, GETabPosition pos, LPARAM lParam) { + NMHDR *msg = (LPNMHDR)lParam; + if (msg->code != NM_RCLICK) + return; + + POINT cursorPos; + GetCursorPos(&cursorPos); + int tabIndex = t->HitTest(cursorPos); + if (tabIndex == -1) + return; + + // Find the tabState that was clicked on. + GEDebuggerTab *tab = nullptr; + for (GEDebuggerTab &tabState : tabStates_) { + int foundIndex = HasTabIndex(&tabState, pos); + if (foundIndex == tabIndex) { + tab = &tabState; + break; + } + } + // Shouldn't normally happen... maybe we added some other type of tab. + if (!tab) + return; + + int currentPanels = 0; + for (int i = 0; i < (int)GEPanelIndex::COUNT; ++i) { + if (tab && tab->state[i].index != -1 && tab->state[i].ptr) + currentPanels++; + } + + HMENU subMenu = GetContextMenu(ContextMenuID::GEDBG_TABS); + static const int itemIDs[] = { ID_GEDBG_SHOWONLEFT, ID_GEDBG_SHOWONRIGHT, ID_GEDBG_SHOWONTOPRIGHT }; + for (int i = 0; i < (int)GEPanelIndex::COUNT; ++i) { + bool active = tab && tab->state[i].index != -1 && tab->state[i].ptr; + bool disabled = active && currentPanels == 1; + CheckMenuItem(subMenu, itemIDs[i], active ? MF_CHECKED : MF_UNCHECKED); + EnableMenuItem(subMenu, itemIDs[i], disabled ? MF_GRAYED : MF_ENABLED); + } + + switch (TriggerContextMenu(ContextMenuID::GEDBG_TABS, m_hDlg, ContextPoint::FromCursor())) { + case ID_GEDBG_SHOWONLEFT: + // TODO + break; + + case ID_GEDBG_SHOWONRIGHT: + // TODO + break; + + case ID_GEDBG_SHOWONTOPRIGHT: + // TODO + break; + + default: + // Cancel, that's fine. + break; + } +} + void CGEDebugger::UpdateMenus() { CheckMenuItem(GetMenu(m_hDlg), IDC_GEDBG_FLUSHAUTO, MF_BYCOMMAND | (autoFlush_ ? MF_CHECKED : MF_UNCHECKED)); } diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index 0e716f1adc..c7d70dc3ee 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -63,10 +63,13 @@ struct GEDebuggerTab { const wchar_t *name; GETabPosition pos; GETabType type; - union { - Dialog *dlg; - CtrlDisplayListView *displayList; - void *ptr; + struct { + union { + Dialog *dlg; + CtrlDisplayListView *displayList; + void *ptr; + }; + int index = -1; } state[3]; void *(*add)(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, HINSTANCE inst, HWND parent); void (*remove)(GEDebuggerTab *tab, TabControl *tabs, GETabPosition pos, void *ptr); @@ -116,6 +119,8 @@ private: void UpdateTab(GEDebuggerTab *tab); void AddTab(GEDebuggerTab *tab, GETabPosition mask); void RemoveTab(GEDebuggerTab *tab, GETabPosition mask); + int HasTabIndex(GEDebuggerTab *tab, GETabPosition pos); + void CheckTabMessage(TabControl *t, GETabPosition pos, LPARAM lParam); u32 TexturePreviewFlags(const GPUgstate &state); diff --git a/Windows/W32Util/ContextMenu.h b/Windows/W32Util/ContextMenu.h index f8fbe46488..9e52e2aa47 100644 --- a/Windows/W32Util/ContextMenu.h +++ b/Windows/W32Util/ContextMenu.h @@ -31,6 +31,7 @@ enum class ContextMenuID { GEDBG_STATE = 7, GEDBG_PREVIEW = 8, GEDBG_MATRIX = 9, + GEDBG_TABS = 10, }; struct ContextPoint { diff --git a/Windows/W32Util/TabControl.cpp b/Windows/W32Util/TabControl.cpp index 8721a9637c..75c819ec04 100644 --- a/Windows/W32Util/TabControl.cpp +++ b/Windows/W32Util/TabControl.cpp @@ -272,6 +272,14 @@ void TabControl::HandleNotify(LPARAM lParam) } } +int TabControl::HitTest(const POINT &screenPos) { + TCHITTESTINFO hitTest{}; + hitTest.pt = screenPos; + ScreenToClient(hwnd, &hitTest.pt); + + return TabCtrl_HitTest(hwnd, &hitTest); +} + void TabControl::OnResize() { RECT tabRect; diff --git a/Windows/W32Util/TabControl.h b/Windows/W32Util/TabControl.h index c8212af004..3d4b26f93e 100644 --- a/Windows/W32Util/TabControl.h +++ b/Windows/W32Util/TabControl.h @@ -11,6 +11,7 @@ class TabControl public: TabControl(HWND handle, bool noDisplayArea = false); void HandleNotify(LPARAM lParam); + int HitTest(const POINT &screenPos); HWND AddTabWindow(const wchar_t* className, const wchar_t* title, DWORD style = 0); void AddTabDialog(Dialog* dialog, const wchar_t* title); void AddTab(HWND hwnd, const wchar_t* title); diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 80a6295986..e2f38fd8e6 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -792,6 +792,12 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Toggle Breakpoint", ID_DISASM_TOGGLEBREAKPOINT END + POPUP "getaboptions" + BEGIN + MENUITEM "Show in &Left Pane" ID_GEDBG_SHOWONLEFT + MENUITEM "Show in &Right Pane" ID_GEDBG_SHOWONRIGHT + MENUITEM "Show in &Top Right Pane" ID_GEDBG_SHOWONTOPRIGHT + END END #endif // English (United States) resources diff --git a/Windows/resource.h b/Windows/resource.h index 7cbe5bf9df..eacb42760b 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -328,6 +328,9 @@ #define IDC_GEDBG_RIGHTTAB 40216 #define ID_OPTIONS_DIRECT3D11 40217 #define IDC_GEDBG_TOPRIGHTTAB 40218 +#define ID_GEDBG_SHOWONLEFT 40219 +#define ID_GEDBG_SHOWONRIGHT 40220 +#define ID_GEDBG_SHOWONTOPRIGHT 40221 // Dummy option to let the buffered rendering hotkey cycle through all the options. @@ -341,7 +344,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40219 +#define _APS_NEXT_COMMAND_VALUE 40222 #define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif From 6272f3e1d6f5f247aff3cd5830a501882cc24d1e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 10:57:31 -0700 Subject: [PATCH 08/15] GE Debugger: Actually allow swapping tabs. --- Windows/GEDebugger/CtrlDisplayListView.cpp | 11 ------- Windows/GEDebugger/CtrlDisplayListView.h | 2 -- Windows/GEDebugger/GEDebugger.cpp | 37 +++++++++++++++++----- Windows/W32Util/Misc.cpp | 3 ++ Windows/W32Util/TabControl.cpp | 14 +++++--- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 188884a292..c9dd0c9d65 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -71,17 +71,6 @@ CtrlDisplayListView *CtrlDisplayListView::getFrom(HWND hwnd) return (CtrlDisplayListView*) GetWindowLongPtr(hwnd, GWLP_USERDATA); } -CtrlDisplayListView *CtrlDisplayListView::Create(HWND parentWnd) { - DWORD style = WS_CHILD | WS_VISIBLE | WS_BORDER; - RECT tabRect{ 0, 0, 100, 100 }; - - HWND hWnd = CreateWindowEx(0, windowClass, L"Display List", style, - tabRect.left, tabRect.top, tabRect.right - tabRect.left, tabRect.bottom - tabRect.top, - parentWnd, 0, MainWindow::GetHInstance(), 0); - - return new CtrlDisplayListView(hWnd); -} - LRESULT CALLBACK CtrlDisplayListView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CtrlDisplayListView *win = CtrlDisplayListView::getFrom(hwnd); diff --git a/Windows/GEDebugger/CtrlDisplayListView.h b/Windows/GEDebugger/CtrlDisplayListView.h index 73d96b2c12..fe605f799e 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.h +++ b/Windows/GEDebugger/CtrlDisplayListView.h @@ -36,8 +36,6 @@ public: static void registerClass(); static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static CtrlDisplayListView * getFrom(HWND wnd); - - static CtrlDisplayListView *Create(HWND parentWnd); HWND GetHWND() { return wnd; diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 9c30abb1d1..52c41edf0f 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -421,6 +421,7 @@ void CGEDebugger::AddTab(GEDebuggerTab *tab, GETabPosition mask) { tab->state[index].index = t->Count(); tab->state[index].ptr = tab->add(tab, t, pos, m_hInstance, m_hDlg); tab->pos |= pos; + t->ShowTab(tab->state[index].index, true); } }; @@ -433,10 +434,18 @@ void CGEDebugger::RemoveTab(GEDebuggerTab *tab, GETabPosition mask) { auto doRemove = [&](GETabPosition pos, TabControl *t, GEPanelIndex pindex) { int index = (int)pindex; if ((tab->pos & pos) && (mask & pos)) { - _assert_(tab->state[index].ptr != nullptr); - tab->remove(tab, t, pos, tab->state[index].ptr); + auto &state = tab->state[index]; + _assert_(state.ptr != nullptr); + t->RemoveTab(state.index); + for (auto &tabState : tabStates_) { + if (tabState.state[index].index > state.index) + --tabState.state[index].index; + } + + tab->remove(tab, t, pos, state.ptr); tab->pos = GETabPosition((int)tab->pos & ~(int)pos); - tab->state[index].index = -1; + state.ptr = nullptr; + state.index = -1; } }; @@ -1125,30 +1134,42 @@ void CGEDebugger::CheckTabMessage(TabControl *t, GETabPosition pos, LPARAM lPara int currentPanels = 0; for (int i = 0; i < (int)GEPanelIndex::COUNT; ++i) { - if (tab && tab->state[i].index != -1 && tab->state[i].ptr) + if (tab->state[i].index != -1 && tab->state[i].ptr) currentPanels++; } HMENU subMenu = GetContextMenu(ContextMenuID::GEDBG_TABS); static const int itemIDs[] = { ID_GEDBG_SHOWONLEFT, ID_GEDBG_SHOWONRIGHT, ID_GEDBG_SHOWONTOPRIGHT }; for (int i = 0; i < (int)GEPanelIndex::COUNT; ++i) { - bool active = tab && tab->state[i].index != -1 && tab->state[i].ptr; + bool active = tab->state[i].index != -1 && tab->state[i].ptr; bool disabled = active && currentPanels == 1; CheckMenuItem(subMenu, itemIDs[i], active ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem(subMenu, itemIDs[i], disabled ? MF_GRAYED : MF_ENABLED); } + auto toggleState = [&](GEPanelIndex i, GETabPosition pos) { + auto &state = tab->state[(int)i]; + if (state.index != -1 && state.ptr) + RemoveTab(tab, pos); + else + AddTab(tab, pos); + + RECT rc; + GetClientRect(m_hDlg, &rc); + UpdateSize(rc.right - rc.left, rc.bottom - rc.top); + }; + switch (TriggerContextMenu(ContextMenuID::GEDBG_TABS, m_hDlg, ContextPoint::FromCursor())) { case ID_GEDBG_SHOWONLEFT: - // TODO + toggleState(GEPanelIndex::LEFT, GETabPosition::LEFT); break; case ID_GEDBG_SHOWONRIGHT: - // TODO + toggleState(GEPanelIndex::RIGHT, GETabPosition::RIGHT); break; case ID_GEDBG_SHOWONTOPRIGHT: - // TODO + toggleState(GEPanelIndex::TOPRIGHT, GETabPosition::TOPRIGHT); break; default: diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index 37bdfd475e..657a0193d2 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -204,6 +204,7 @@ GenericListControl::GenericListControl(HWND hwnd, const GenericListViewDef& def) } GenericListControl::~GenericListControl() { + SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)nullptr); // Don't destroy the image list, it's done automatically by the list view. } @@ -376,6 +377,8 @@ void GenericListControl::ResizeColumns() LRESULT CALLBACK GenericListControl::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { GenericListControl* list = (GenericListControl*) GetWindowLongPtr(hwnd,GWLP_USERDATA); + if (!list) + return FALSE; LRESULT returnValue; if (list->valid && list->WindowMessage(msg,wParam,lParam,returnValue) == true) diff --git a/Windows/W32Util/TabControl.cpp b/Windows/W32Util/TabControl.cpp index 75c819ec04..d4556725b6 100644 --- a/Windows/W32Util/TabControl.cpp +++ b/Windows/W32Util/TabControl.cpp @@ -99,11 +99,17 @@ HWND TabControl::RemoveTab(int index) { --currentTab; HWND prevHandle = tabs[index].pageHandle; - TabCtrl_DeleteItem(hwnd, index); - tabs.erase(tabs.begin() + index); + if (tabs.size() == 1) { + TabCtrl_DeleteAllItems(hwnd); + tabs.clear(); + currentTab = 0; + } else { + TabCtrl_DeleteItem(hwnd, index); + tabs.erase(tabs.begin() + index); - if (prevIndex == index) - ShowTab(currentTab, true); + if (prevIndex == index) + ShowTab(currentTab, true); + } return prevHandle; } From 8390867019d7ba1ac979dbae82981d4b6911d9ef Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 11:07:53 -0700 Subject: [PATCH 09/15] GE Debugger: Correct tab updating for right panel. --- Windows/GEDebugger/GEDebugger.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 52c41edf0f..b28ee32ccb 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -422,6 +422,8 @@ void CGEDebugger::AddTab(GEDebuggerTab *tab, GETabPosition mask) { tab->state[index].ptr = tab->add(tab, t, pos, m_hInstance, m_hDlg); tab->pos |= pos; t->ShowTab(tab->state[index].index, true); + if (gpuDebug) + tab->update(tab, t, pos, tab->state[index].ptr); } }; @@ -805,7 +807,7 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&tabRect,2); // Assume the same gap (tabRect.left) on all sides. - if (tabsTR_ && tabsTR_->Count() == 0) { + if (tabsRight_ && tabsRight_->Count() == 0) { tabRect.right = tabRect.left + (width - tabRect.left * 2); } else { tabRect.right = tabRect.left + (width / 2 - tabRect.left * 2); @@ -813,12 +815,12 @@ void CGEDebugger::UpdateSize(WORD width, WORD height) { tabRect.bottom = tabRect.top + (height - tabRect.top - tabRect.left); RECT tabRectRight = tabRect; - if (tabs && tabsTR_ && tabs->Count() == 0 && tabsTR_->Count() != 0) { + if (tabs && tabsRight_ && tabs->Count() == 0 && tabsRight_->Count() != 0) { tabRect.right = tabRect.left; tabRect.bottom = tabRect.top; } else { tabRectRight.left += tabRect.right; - tabRectRight.right += tabRect.right; + tabRectRight.right += tabRect.right + tabRect.left; } RECT frameRect; From 2a4443b85e917b24791c306001fece6a139f79bb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 11:26:37 -0700 Subject: [PATCH 10/15] GE Debugger: Cleanup duplicate dlist redraws. It's still not redrawing properly on resize, but it tries to... --- Windows/GEDebugger/CtrlDisplayListView.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index c9dd0c9d65..6b521c4996 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -150,8 +150,7 @@ void CtrlDisplayListView::redraw() GetClientRect(wnd, &rect); visibleRows = rect.bottom/rowHeight; - InvalidateRect(wnd, NULL, FALSE); - UpdateWindow(wnd); + RedrawWindow(wnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_ALLCHILDREN); } From 6fad5463d034402653f009b6498c939b7df5b0f9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 11:42:04 -0700 Subject: [PATCH 11/15] GE Debugger: Save tab configuration. --- Core/Config.cpp | 3 +++ Core/Config.h | 3 +++ Windows/GEDebugger/GEDebugger.cpp | 42 +++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 91264ca5b4..4c5d312bf2 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1167,6 +1167,9 @@ static ConfigSetting debuggerSettings[] = { ConfigSetting("GEWindowY", &g_Config.iGEWindowY, -1), ConfigSetting("GEWindowW", &g_Config.iGEWindowW, -1), ConfigSetting("GEWindowH", &g_Config.iGEWindowH, -1), + ConfigSetting("GEWindowTabsBL", &g_Config.uGETabsLeft, (uint32_t)0), + ConfigSetting("GEWindowTabsBR", &g_Config.uGETabsRight, (uint32_t)0), + ConfigSetting("GEWindowTabsTR", &g_Config.uGETabsTopRight, (uint32_t)0), ConfigSetting("ConsoleWindowX", &g_Config.iConsoleWindowX, -1), ConfigSetting("ConsoleWindowY", &g_Config.iConsoleWindowY, -1), ConfigSetting("FontWidth", &g_Config.iFontWidth, 8), diff --git a/Core/Config.h b/Core/Config.h index e682234ba3..7a35ff0d09 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -462,6 +462,9 @@ public: int iGEWindowY; int iGEWindowW; int iGEWindowH; + uint32_t uGETabsLeft; + uint32_t uGETabsRight; + uint32_t uGETabsTopRight; int iConsoleWindowX; int iConsoleWindowY; int iFontWidth; diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index b28ee32ccb..1546019124 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -212,6 +212,27 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) fbTabs->ShowTab(0, true); tabStates_ = defaultTabs; + // Restore settings, if any set. + _assert_msg_(defaultTabs.size() <= 32, "Cannot have more than 32 tabs"); + if ((g_Config.uGETabsLeft | g_Config.uGETabsRight | g_Config.uGETabsTopRight) != 0) { + for (int i = 0; i < (int)tabStates_.size(); ++i) { + int mask = 1 << i; + tabStates_[i].pos = (GETabPosition)0; + if (g_Config.uGETabsLeft & mask) + tabStates_[i].pos |= GETabPosition::LEFT; + if (g_Config.uGETabsRight & mask) + tabStates_[i].pos |= GETabPosition::RIGHT; + if (g_Config.uGETabsTopRight & mask) + tabStates_[i].pos |= GETabPosition::TOPRIGHT; + // If this is a new tab, add it to left. + if (tabStates_[i].pos == (GETabPosition)0) { + tabStates_[i].pos |= GETabPosition::LEFT; + g_Config.uGETabsLeft |= 1 << i; + } + } + } else { + g_Config.uGETabsLeft = (1 << tabStates_.size()) - 1; + } for (GEDebuggerTab &tabState : tabStates_) { AddTab(&tabState, tabState.pos); } @@ -1123,10 +1144,13 @@ void CGEDebugger::CheckTabMessage(TabControl *t, GETabPosition pos, LPARAM lPara // Find the tabState that was clicked on. GEDebuggerTab *tab = nullptr; - for (GEDebuggerTab &tabState : tabStates_) { + int tabStateIndex = 0; + for (int i = 0; i < (int)tabStates_.size(); ++i) { + GEDebuggerTab &tabState = tabStates_[i]; int foundIndex = HasTabIndex(&tabState, pos); if (foundIndex == tabIndex) { tab = &tabState; + tabStateIndex = i; break; } } @@ -1149,12 +1173,16 @@ void CGEDebugger::CheckTabMessage(TabControl *t, GETabPosition pos, LPARAM lPara EnableMenuItem(subMenu, itemIDs[i], disabled ? MF_GRAYED : MF_ENABLED); } - auto toggleState = [&](GEPanelIndex i, GETabPosition pos) { + auto toggleState = [&](GEPanelIndex i, GETabPosition pos, uint32_t &configured) { auto &state = tab->state[(int)i]; - if (state.index != -1 && state.ptr) + bool removing = state.index != -1 && state.ptr; + if (removing) { RemoveTab(tab, pos); - else + configured &= ~(1 << tabStateIndex); + } else { AddTab(tab, pos); + configured |= 1 << tabStateIndex; + } RECT rc; GetClientRect(m_hDlg, &rc); @@ -1163,15 +1191,15 @@ void CGEDebugger::CheckTabMessage(TabControl *t, GETabPosition pos, LPARAM lPara switch (TriggerContextMenu(ContextMenuID::GEDBG_TABS, m_hDlg, ContextPoint::FromCursor())) { case ID_GEDBG_SHOWONLEFT: - toggleState(GEPanelIndex::LEFT, GETabPosition::LEFT); + toggleState(GEPanelIndex::LEFT, GETabPosition::LEFT, g_Config.uGETabsLeft); break; case ID_GEDBG_SHOWONRIGHT: - toggleState(GEPanelIndex::RIGHT, GETabPosition::RIGHT); + toggleState(GEPanelIndex::RIGHT, GETabPosition::RIGHT, g_Config.uGETabsRight); break; case ID_GEDBG_SHOWONTOPRIGHT: - toggleState(GEPanelIndex::TOPRIGHT, GETabPosition::TOPRIGHT); + toggleState(GEPanelIndex::TOPRIGHT, GETabPosition::TOPRIGHT, g_Config.uGETabsTopRight); break; default: From 0b22c9840450193a215498f7d9a9bd092bb3a248 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 13:19:52 -0700 Subject: [PATCH 12/15] GPU: Skip fb create upload when clearing. This doesn't verify it's a full screen clear, but on a new framebuffer that's very very common. --- GPU/Common/FramebufferManagerCommon.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 68920e2a12..036c67c22b 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -469,7 +469,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfbs_.push_back(vfb); currentRenderVfb_ = vfb; - if (useBufferedRendering_ && !g_Config.bDisableSlowFramebufEffects) { + // Assume that if we're clearing right when switching to a new framebuffer, we don't need to upload. + if (useBufferedRendering_ && !g_Config.bDisableSlowFramebufEffects && params.isDrawing) { gpu->PerformMemoryUpload(params.fb_address, byteSize); // Alpha was already done by PerformMemoryUpload. PerformStencilUpload(params.fb_address, byteSize, StencilUpload::STENCIL_IS_ZERO | StencilUpload::IGNORE_ALPHA); From 132686513d546816cef6e62005241f84cce2dc22 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 16:14:23 -0700 Subject: [PATCH 13/15] GE Debugger: Correct base accounting in playback. On a jump, was forgetting the base value which caused corruption. --- GPU/Debugger/Playback.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 8fa93e7d7c..aa34ce3ccf 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -367,6 +367,7 @@ bool DumpExecute::SubmitCmds(const void *p, u32 sz) { Memory::Write_U32((GE_CMD_JUMP << 24) | (execListBuf & 0x00FFFFFF), execListPos + 4); execListPos = execListBuf; + lastBase_ = execListBuf & 0xFF000000; // Don't continue until we've stalled. SyncStall(); @@ -450,9 +451,9 @@ void DumpExecute::Vertices(u32 ptr, u32 sz) { return; } - if (lastBase_ != (psp & 0x0FF000000)) { + if (lastBase_ != (psp & 0xFF000000)) { execListQueue.push_back((GE_CMD_BASE << 24) | ((psp >> 8) & 0x00FF0000)); - lastBase_ = psp & 0x0FF000000; + lastBase_ = psp & 0xFF000000; } execListQueue.push_back((GE_CMD_VADDR << 24) | (psp & 0x00FFFFFF)); } @@ -464,9 +465,9 @@ void DumpExecute::Indices(u32 ptr, u32 sz) { return; } - if (lastBase_ != (psp & 0x0FF000000)) { + if (lastBase_ != (psp & 0xFF000000)) { execListQueue.push_back((GE_CMD_BASE << 24) | ((psp >> 8) & 0x00FF0000)); - lastBase_ = psp & 0x0FF000000; + lastBase_ = psp & 0xFF000000; } execListQueue.push_back((GE_CMD_IADDR << 24) | (psp & 0x00FFFFFF)); } From daaf448d2231f643b02ffe504bcfae29bacac0b9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Aug 2022 16:17:04 -0700 Subject: [PATCH 14/15] GE Debugger: Fix crash on 0 count prim. --- GPU/Common/DrawEngineCommon.cpp | 2 +- GPU/Software/TransformUnit.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 0755988029..34e0f7ff90 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -266,7 +266,7 @@ bool DrawEngineCommon::GetCurrentSimpleVertices(int count, std::vector 0 && (gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { const u8 *inds = Memory::GetPointer(gstate_c.indexAddr); const u16_le *inds16 = (const u16_le *)inds; From 77e41f80736873338a1ae0d5c035a82741b74e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 16 Aug 2022 00:34:38 +0200 Subject: [PATCH 15/15] Revert "Pause the debugger on TRANSFERSTART (treat that as a prim)" This reverts commit 8cb7d9cd9f3ab406e7c6bfab31e9b219860467ed. --- GPU/Debugger/Debugger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 28dc194b74..04fb647f1d 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -111,7 +111,7 @@ bool NotifyCommand(u32 pc) { } bool process = true; - if (cmd == GE_CMD_PRIM || cmd == GE_CMD_BEZIER || cmd == GE_CMD_SPLINE || cmd == GE_CMD_TRANSFERSTART) { + if (cmd == GE_CMD_PRIM || cmd == GE_CMD_BEZIER || cmd == GE_CMD_SPLINE) { primsThisFrame++; if (!restrictPrimRanges.empty()) {