diff --git a/GPU/Common/GPUDebugInterface.h b/GPU/Common/GPUDebugInterface.h index 97531a952c..68e03debd2 100644 --- a/GPU/Common/GPUDebugInterface.h +++ b/GPU/Common/GPUDebugInterface.h @@ -171,6 +171,9 @@ public: virtual u32 GetVertexAddress() = 0; virtual u32 GetIndexAddress() = 0; virtual GPUgstate GetGState() = 0; + // Needs to be called from the GPU thread. + // Calling from a separate thread (e.g. UI) may fail. + virtual void SetCmdValue(u32 op) = 0; // Needs to be called from the GPU thread, so on the same thread as a notification is fine. // Calling from a separate thread (e.g. UI) may fail. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 43fbf11ea6..39930b4b38 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1096,3 +1096,12 @@ u32 GPUCommon::GetIndexAddress() { GPUgstate GPUCommon::GetGState() { return gstate; } + +void GPUCommon::SetCmdValue(u32 op) { + u32 cmd = op >> 24; + u32 diff = op ^ gstate.cmdmem[cmd]; + + PreExecuteOp(op, diff); + gstate.cmdmem[cmd] = op; + ExecuteOp(op, diff); +} diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index aa5e28f06d..a8355828d3 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -152,6 +152,7 @@ public: virtual u32 GetVertexAddress(); virtual u32 GetIndexAddress(); virtual GPUgstate GetGState(); + virtual void SetCmdValue(u32 op); virtual DisplayList* getList(int listid) { diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index f1f4b14d05..72d269f6a8 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -41,6 +41,7 @@ enum PauseAction { PAUSE_GETDEPTHBUF, PAUSE_GETSTENCILBUF, PAUSE_GETTEX, + PAUSE_SETCMDVALUE, }; static bool attached = false; @@ -65,6 +66,7 @@ static GPUDebugBuffer bufferFrame; static GPUDebugBuffer bufferDepth; static GPUDebugBuffer bufferStencil; static GPUDebugBuffer bufferTex; +static u32 pauseSetCmdValue; enum PrimaryDisplayType { PRIMARY_FRAMEBUF, @@ -143,6 +145,13 @@ static void RunPauseAction() { case PAUSE_GETTEX: bufferResult = gpuDebug->GetCurrentTexture(bufferTex); break; + + case PAUSE_SETCMDVALUE: + gpuDebug->SetCmdValue(pauseSetCmdValue); + break; + + default: + ERROR_LOG(HLE, "Unsupported pause action, forgot to add it to the switch."); } actionWait.notify_one(); @@ -468,6 +477,13 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { SendMessage(m_hDlg,WM_COMMAND,IDC_GEDBG_RESUME,0); } break; + + case WM_GEDBG_SETCMDWPARAM: + { + pauseSetCmdValue = (u32)wParam; + SetPauseAction(PAUSE_SETCMDVALUE); + } + break; } return FALSE; diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index 297af36142..a5eff0736e 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -29,7 +29,8 @@ enum { WM_GEDBG_BREAK_DRAW, WM_GEDBG_STEPDISPLAYLIST, WM_GEDBG_TOGGLEPCBREAKPOINT, - WM_GEDBG_RUNTOWPARAM + WM_GEDBG_RUNTOWPARAM, + WM_GEDBG_SETCMDWPARAM, }; class CtrlDisplayListView; diff --git a/Windows/GEDebugger/TabState.cpp b/Windows/GEDebugger/TabState.cpp index d3594f39f8..fe17038aaf 100644 --- a/Windows/GEDebugger/TabState.cpp +++ b/Windows/GEDebugger/TabState.cpp @@ -17,6 +17,7 @@ #include "base/basictypes.h" #include "Windows/resource.h" +#include "Windows/GEDebugger/GEDebugger.h" #include "Windows/GEDebugger/TabState.h" #include "GPU/GPUState.h" #include "GPU/GeDisasm.h" @@ -527,7 +528,36 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) { break; } } - +} + +void CtrlStateValues::OnDoubleClick(int row, int column) { + if (gpuDebug == NULL) { + return; + } + + const auto info = rows_[row]; + switch (info.fmt) { + case CMD_FMT_FLAG: + { + const auto state = gpuDebug->GetGState(); + u32 newValue = state.cmdmem[info.cmd] ^ 1; + SetCmdValue(newValue); + } + break; + } +} + +void CtrlStateValues::OnRightClick(int row, int column, const POINT& point) { + if (gpuDebug == NULL) { + return; + } + + // TODO: Copy, etc. +} + +void CtrlStateValues::SetCmdValue(u32 op) { + SendMessage(GetParent(GetParent(GetHandle())), WM_GEDBG_SETCMDWPARAM, op, NULL); + Update(); } TabStateValues::TabStateValues(const TabStateRow *rows, int rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent) diff --git a/Windows/GEDebugger/TabState.h b/Windows/GEDebugger/TabState.h index e86b693199..c31ef8bfe3 100644 --- a/Windows/GEDebugger/TabState.h +++ b/Windows/GEDebugger/TabState.h @@ -30,8 +30,12 @@ protected: virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) { return false; }; virtual void GetColumnText(wchar_t* dest, int row, int col); virtual int GetRowCount() { return rowCount_; } + virtual void OnDoubleClick(int row, int column); + virtual void OnRightClick(int row, int column, const POINT& point); private: + void SetCmdValue(u32 op); + const TabStateRow *rows_; int rowCount_; };