From 21997784bfc38cfffe2270f4ccde65e427dc10d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 5 Dec 2024 10:05:23 +0100 Subject: [PATCH] Extract FormatStateRow() from the Win32 GE debugger to GPU/Debugger/Registers --- CMakeLists.txt | 2 + GPU/Debugger/State.cpp | 532 ++++++++++++++ GPU/Debugger/State.h | 54 ++ GPU/GPU.vcxproj | 2 + GPU/GPU.vcxproj.filters | 6 + GPU/GPUCommon.cpp | 27 +- UI/ImDebugger/ImDebugger.cpp | 5 + UI/ImDebugger/ImDebugger.h | 1 + UI/ImDebugger/ImGe.cpp | 24 + UI/ImDebugger/ImGe.h | 1 + UWP/GPU_UWP/GPU_UWP.vcxproj | 2 + UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 63 +- Windows/Debugger/Debugger_Lists.cpp | 28 +- Windows/Debugger/Debugger_Lists.h | 10 +- Windows/GEDebugger/TabDisplayLists.cpp | 4 +- Windows/GEDebugger/TabDisplayLists.h | 4 +- Windows/GEDebugger/TabState.cpp | 944 +++++-------------------- Windows/GEDebugger/TabState.h | 2 +- Windows/GEDebugger/TabVertices.cpp | 8 +- Windows/GEDebugger/TabVertices.h | 4 +- Windows/W32Util/Misc.cpp | 6 +- Windows/W32Util/Misc.h | 4 +- android/jni/Android.mk | 1 + 23 files changed, 927 insertions(+), 807 deletions(-) create mode 100644 GPU/Debugger/State.cpp create mode 100644 GPU/Debugger/State.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fa4c24c71..89e6347f1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1970,6 +1970,8 @@ set(GPU_SOURCES GPU/Debugger/Record.cpp GPU/Debugger/Record.h GPU/Debugger/RecordFormat.h + GPU/Debugger/State.cpp + GPU/Debugger/State.h GPU/Debugger/Stepping.cpp GPU/Debugger/Stepping.h GPU/ge_constants.h diff --git a/GPU/Debugger/State.cpp b/GPU/Debugger/State.cpp new file mode 100644 index 0000000000..d875536cf7 --- /dev/null +++ b/GPU/Debugger/State.cpp @@ -0,0 +1,532 @@ +#include +#include "Common/Common.h" + +#include "GPU/Debugger/State.h" +#include "GPU/GPU.h" +#include "GPU/Common/GPUDebugInterface.h" +#include "GPU/GeDisasm.h" + +void FormatStateRow(GPUDebugInterface *gpudebug, char *dest, size_t destSize, CmdFormatType fmt, u32 value, bool enabled, u32 otherValue, u32 otherValue2) { + switch (fmt) { + case CMD_FMT_HEX: + snprintf(dest, destSize, "%06x", value); + break; + + case CMD_FMT_NUM: + snprintf(dest, destSize, "%d", value); + break; + + case CMD_FMT_FLOAT24: + snprintf(dest, destSize, "%f", getFloat24(value)); + break; + + case CMD_FMT_PTRWIDTH: + value |= (otherValue & 0x00FF0000) << 8; + otherValue &= 0xFFFF; + snprintf(dest, destSize, "%08x, w=%d", value, otherValue); + break; + + case CMD_FMT_XY: + { + int x = value & 0x3FF; + int y = value >> 10; + snprintf(dest, destSize, "%d,%d", x, y); + } + break; + + case CMD_FMT_XYPLUS1: + { + int x = value & 0x3FF; + int y = value >> 10; + snprintf(dest, destSize, "%d,%d", x + 1, y + 1); + } + break; + + case CMD_FMT_XYXY: + { + int x1 = value & 0x3FF; + int y1 = value >> 10; + int x2 = otherValue & 0x3FF; + int y2 = otherValue >> 10; + snprintf(dest, destSize, "%d,%d - %d,%d", x1, y1, x2, y2); + } + break; + + case CMD_FMT_XYZ: + { + float x = getFloat24(value); + float y = getFloat24(otherValue); + float z = getFloat24(otherValue2); + snprintf(dest, destSize, "%f, %f, %f", x, y, z); + } + break; + + case CMD_FMT_TEXSIZE: + { + int w = 1 << (value & 0x1f); + int h = 1 << ((value >> 8) & 0x1f); + snprintf(dest, destSize, "%dx%d", w, h); + } + break; + + case CMD_FMT_F16_XY: + { + float x = (float)value / 16.0f; + float y = (float)otherValue / 16.0f; + snprintf(dest, destSize, "%fx%f", x, y); + } + break; + + case CMD_FMT_VERTEXTYPE: + { + char buffer[256]; + GeDescribeVertexType(value, buffer); + snprintf(dest, destSize, "%s", buffer); + } + break; + + case CMD_FMT_TEXFMT: + { + static const char *texformats[] = { + "5650", + "5551", + "4444", + "8888", + "CLUT4", + "CLUT8", + "CLUT16", + "CLUT32", + "DXT1", + "DXT3", + "DXT5", + }; + if (value < (u32)ARRAY_SIZE(texformats)) { + snprintf(dest, destSize, "%s", texformats[value]); + } else if ((value & 0xF) < (u32)ARRAY_SIZE(texformats)) { + snprintf(dest, destSize, "%s (extra bits %06x)", texformats[value & 0xF], value & ~0xF); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_CLUTFMT: + { + const char *clutformats[] = { + "BGR 5650", + "ABGR 1555", + "ABGR 4444", + "ABGR 8888", + }; + const u8 palette = (value >> 0) & 3; + const u8 shift = (value >> 2) & 0x3F; + const u8 mask = (value >> 8) & 0xFF; + const u8 offset = (value >> 16) & 0xFF; + if (offset < 0x20 && shift < 0x20) { + if (offset == 0 && shift == 0) { + snprintf(dest, destSize, "%s ind & %02x", clutformats[palette], mask); + } else { + snprintf(dest, destSize, "%s (ind >> %d) & %02x, offset +%d", clutformats[palette], shift, mask, offset); + } + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_COLORTEST: + { + static const char *colorTests[] = { "NEVER", "ALWAYS", " == ", " != " }; + const u32 mask = otherValue2; + const u32 ref = otherValue; + if (value < (u32)ARRAY_SIZE(colorTests)) { + snprintf(dest, destSize, "pass if (c & %06x) %s (%06x & %06x)", mask, colorTests[value], ref, mask); + } else { + snprintf(dest, destSize, "%06x, ref=%06x, maks=%06x", value, ref, mask); + } + } + break; + + case CMD_FMT_ALPHATEST: + case CMD_FMT_STENCILTEST: + { + static const char *alphaTestFuncs[] = { "NEVER", "ALWAYS", "==", "!=", "<", "<=", ">", ">=" }; + const u8 mask = (value >> 16) & 0xff; + const u8 ref = (value >> 8) & 0xff; + const u8 func = (value >> 0) & 0xff; + if (func < (u8)ARRAY_SIZE(alphaTestFuncs)) { + if (fmt == CMD_FMT_ALPHATEST) { + snprintf(dest, destSize, "pass if (a & %02x) %s (%02x & %02x)", mask, alphaTestFuncs[func], ref, mask); + } else if (fmt == CMD_FMT_STENCILTEST) { + // Stencil test is the other way around. + snprintf(dest, destSize, "pass if (%02x & %02x) %s (a & %02x)", ref, mask, alphaTestFuncs[func], mask); + } + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_ZTEST: + { + static const char *zTestFuncs[] = { "NEVER", "ALWAYS", "==", "!=", "<", "<=", ">", ">=" }; + if (value < (u32)ARRAY_SIZE(zTestFuncs)) { + snprintf(dest, destSize, "pass if src %s dst", zTestFuncs[value]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_OFFSETADDR: + snprintf(dest, destSize, "%08x", gpuDebug->GetRelativeAddress(0)); + break; + + case CMD_FMT_VADDR: + snprintf(dest, destSize, "%08x", gpuDebug->GetVertexAddress()); + break; + + case CMD_FMT_IADDR: + snprintf(dest, destSize, "%08x", gpuDebug->GetIndexAddress()); + break; + + case CMD_FMT_MATERIALUPDATE: + { + static const char *materialTypes[] = { + "none", + "ambient", + "diffuse", + "ambient, diffuse", + "specular", + "ambient, specular", + "diffuse, specular", + "ambient, diffuse, specular", + }; + if (value < (u32)ARRAY_SIZE(materialTypes)) { + snprintf(dest, destSize, "%s", materialTypes[value]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_SHADEMODEL: + if (value == 0) { + snprintf(dest, destSize, "flat"); + } else if (value == 1) { + snprintf(dest, destSize, "gouraud"); + } else { + snprintf(dest, destSize, "%06x", value); + } + break; + + case CMD_FMT_STENCILOP: + { + static const char *stencilOps[] = { "KEEP", "ZERO", "REPLACE", "INVERT", "INCREMENT", "DECREMENT" }; + const u8 sfail = (value >> 0) & 0xFF; + const u8 zfail = (value >> 8) & 0xFF; + const u8 pass = (value >> 16) & 0xFF; + const u8 totalValid = (u8)ARRAY_SIZE(stencilOps); + if (sfail < totalValid && zfail < totalValid && pass < totalValid) { + snprintf(dest, destSize, "fail=%s, pass/depthfail=%s, pass=%s", stencilOps[sfail], stencilOps[zfail], stencilOps[pass]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_BLENDMODE: + { + const char *blendModes[] = { + "add", + "subtract", + "reverse subtract", + "min", + "max", + "abs subtract", + }; + const char *blendFactorsA[] = { + "dst", + "1.0 - dst", + "src.a", + "1.0 - src.a", + "dst.a", + "1.0 - dst.a", + "2.0 * src.a", + "1.0 - 2.0 * src.a", + "2.0 * dst.a", + "1.0 - 2.0 * dst.a", + "fixed", + }; + const char *blendFactorsB[] = { + "src", + "1.0 - src", + "src.a", + "1.0 - src.a", + "dst.a", + "1.0 - dst.a", + "2.0 * src.a", + "1.0 - 2.0 * src.a", + "2.0 * dst.a", + "1.0 - 2.0 * dst.a", + "fixed", + }; + const u8 blendFactorA = (value >> 0) & 0xF; + const u8 blendFactorB = (value >> 4) & 0xF; + const u32 blendMode = (value >> 8); + + if (blendFactorA < (u8)ARRAY_SIZE(blendFactorsA) && blendFactorB < (u8)ARRAY_SIZE(blendFactorsB) && blendMode < (u32)ARRAY_SIZE(blendModes)) { + snprintf(dest, destSize, "%s: %s, %s", blendModes[blendMode], blendFactorsA[blendFactorA], blendFactorsB[blendFactorB]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_CLEARMODE: + if (value == 0) { + snprintf(dest, destSize, "%d", value); + } else if ((value & ~(GE_CLEARMODE_ALL | 1)) == 0) { + const char *clearmodes[] = { + "1, write disabled", + "1, write color", + "1, write alpha/stencil", + "1, write color, alpha/stencil", + "1, write depth", + "1, write color, depth", + "1, write alpha/stencil, depth", + "1, write color, alpha/stencil, depth", + }; + snprintf(dest, destSize, "%s", clearmodes[value >> 8]); + } else { + snprintf(dest, destSize, "%06x", value); + } + break; + + case CMD_FMT_TEXFUNC: + { + const char *texfuncs[] = { + "modulate", + "decal", + "blend", + "replace", + "add", + }; + const u8 func = (value >> 0) & 0xFF; + const u8 rgba = (value >> 8) & 0xFF; + const u8 colorDouble = (value >> 16) & 0xFF; + + if (rgba <= 1 && colorDouble <= 1 && func < (u8)ARRAY_SIZE(texfuncs)) { + snprintf(dest, destSize, "%s, %s%s", texfuncs[func], rgba ? "RGBA" : "RGB", colorDouble ? ", color doubling" : ""); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_TEXMODE: + { + const u8 swizzle = (value >> 0) & 0xFF; + const u8 clutLevels = (value >> 8) & 0xFF; + const u8 maxLevel = (value >> 16) & 0xFF; + + if (swizzle <= 1 && clutLevels <= 1 && maxLevel <= 7) { + snprintf(dest, destSize, "%s%d levels%s", swizzle ? "swizzled, " : "", maxLevel + 1, clutLevels ? ", CLUT per level" : ""); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_LOGICOP: + { + const char *logicOps[] = { + "clear", + "and", + "reverse and", + "copy", + "inverted and", + "noop", + "xor", + "or", + "negated or", + "equivalence", + "inverted", + "reverse or", + "inverted copy", + "inverted or", + "negated and", + "set", + }; + + if (value < ARRAY_SIZE(logicOps)) { + snprintf(dest, destSize, "%s", logicOps[value]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_TEXWRAP: + { + if ((value & ~0x0101) == 0) { + const bool clampS = (value & 0x0001) != 0; + const bool clampT = (value & 0x0100) != 0; + snprintf(dest, destSize, "%s s, %s t", clampS ? "clamp" : "wrap", clampT ? "clamp" : "wrap"); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_TEXLEVEL: + { + static const char *mipLevelModes[3] = { + "auto + bias", + "bias", + "slope + bias", + }; + const int mipLevel = value & 0xFFFF; + const int biasFixed = (s8)(value >> 16); + const float bias = (float)biasFixed / 16.0f; + + if (mipLevel == 0 || mipLevel == 1 || mipLevel == 2) { + snprintf(dest, destSize, "%s: %f", mipLevelModes[mipLevel], bias); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_TEXFILTER: + { + const char *textureFilters[] = { + "nearest", + "linear", + NULL, + NULL, + "nearest, mipmap nearest", + "linear, mipmap nearest", + "nearest, mipmap linear", + "linear, mipmap linear", + }; + if ((value & ~0x0107) == 0 && textureFilters[value & 7] != NULL) { + const int min = (value & 0x0007) >> 0; + const int mag = (value & 0x0100) >> 8; + snprintf(dest, destSize, "min: %s, mag: %s", textureFilters[min], textureFilters[mag]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_TEXMAPMODE: + { + static const char *const uvGenModes[] = { + "tex coords", + "tex matrix", + "tex env map", + "unknown (tex coords?)", + }; + static const char *const uvProjModes[] = { + "pos", + "uv", + "normalized normal", + "normal", + }; + if ((value & ~0x0303) == 0) { + const int uvGen = (value & 0x0003) >> 0; + const int uvProj = (value & 0x0300) >> 8; + snprintf(dest, destSize, "gen: %s, proj: %s", uvGenModes[uvGen], uvProjModes[uvProj]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_TEXSHADELS: + if ((value & ~0x0303) == 0) { + const int sLight = (value & 0x0003) >> 0; + const int tLight = (value & 0x0300) >> 8; + snprintf(dest, destSize, "s: %d, t: %d", sLight, tLight); + } else { + snprintf(dest, destSize, "%06x", value); + } + break; + + case CMD_FMT_LIGHTMODE: + if (value == 0) { + snprintf(dest, destSize, "mixed color"); + } else if (value == 1) { + snprintf(dest, destSize, "separate specular"); + } else { + snprintf(dest, destSize, "%06x", value); + } + break; + + case CMD_FMT_LIGHTTYPE: + { + static const char * const lightComputations[] = { + "diffuse", + "diffuse + spec", + "pow(diffuse)", + "unknown (diffuse?)", + }; + static const char * const lightTypes[] = { + "directional", + "point", + "spot", + "unknown (directional?)", + }; + if ((value & ~0x0303) == 0) { + const int comp = (value & 0x0003) >> 0; + const int type = (value & 0x0300) >> 8; + snprintf(dest, destSize, "type: %s, comp: %s", lightTypes[type], lightComputations[comp]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_CULL: + if (value == 0) { + snprintf(dest, destSize, "front (CW)"); + } else if (value == 1) { + snprintf(dest, destSize, "back (CCW)"); + } else { + snprintf(dest, destSize, "%06x", value); + } + break; + + case CMD_FMT_PATCHPRIMITIVE: + { + static const char * const patchPrims[] = { + "triangles", + "lines", + "points", + }; + if (value < (u32)ARRAY_SIZE(patchPrims)) { + snprintf(dest, destSize, "%s", patchPrims[value]); + } else { + snprintf(dest, destSize, "%06x", value); + } + } + break; + + case CMD_FMT_FLAG: + if ((value & ~1) == 0) { + snprintf(dest, destSize, "%d", value); + } else { + snprintf(dest, destSize, "%06x", value); + } + break; + + default: + snprintf(dest, destSize, "BAD FORMAT %06x", value); + } + + // TODO: Turn row grey or some such? + if (!enabled) { + strcat(dest, " (disabled)"); + } +} diff --git a/GPU/Debugger/State.h b/GPU/Debugger/State.h new file mode 100644 index 0000000000..eeb5dae989 --- /dev/null +++ b/GPU/Debugger/State.h @@ -0,0 +1,54 @@ +#pragma once + +#include + +#include + +#include "Common/CommonTypes.h" + +// Extracted from Windows/GE Debugger/TabState.cpp + +enum CmdFormatType { + CMD_FMT_HEX = 0, + CMD_FMT_NUM, + CMD_FMT_FLOAT24, + CMD_FMT_PTRWIDTH, + CMD_FMT_XY, + CMD_FMT_XYXY, + CMD_FMT_XYZ, + CMD_FMT_XYPLUS1, + CMD_FMT_TEXSIZE, + CMD_FMT_F16_XY, + CMD_FMT_VERTEXTYPE, + CMD_FMT_TEXFMT, + CMD_FMT_CLUTFMT, + CMD_FMT_COLORTEST, + CMD_FMT_ALPHATEST, + CMD_FMT_STENCILTEST, + CMD_FMT_ZTEST, + CMD_FMT_OFFSETADDR, + CMD_FMT_VADDR, + CMD_FMT_IADDR, + CMD_FMT_MATERIALUPDATE, + CMD_FMT_STENCILOP, + CMD_FMT_BLENDMODE, + CMD_FMT_FLAG, + CMD_FMT_CLEARMODE, + CMD_FMT_TEXFUNC, + CMD_FMT_TEXMODE, + CMD_FMT_LOGICOP, + CMD_FMT_TEXWRAP, + CMD_FMT_TEXLEVEL, + CMD_FMT_TEXFILTER, + CMD_FMT_TEXMAPMODE, + CMD_FMT_TEXSHADELS, + CMD_FMT_SHADEMODEL, + CMD_FMT_LIGHTMODE, + CMD_FMT_LIGHTTYPE, + CMD_FMT_CULL, + CMD_FMT_PATCHPRIMITIVE, +}; + +class GPUDebugInterface; + +void FormatStateRow(GPUDebugInterface *debug, char *dest, size_t destSize, CmdFormatType fmt, u32 value, bool enabled, u32 otherValue, u32 otherValue2); diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 20881e306c..5cb3ea9e62 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -386,6 +386,7 @@ + @@ -533,6 +534,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index dac0350e57..610ba94cbe 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -276,6 +276,9 @@ Common + + Debugger + @@ -548,6 +551,9 @@ Common + + Debugger + diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 387a748e88..2d2eae807c 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1995,23 +1995,42 @@ bool GPUCommon::DescribeCodePtr(const u8 *ptr, std::string &name) { } void GPUCommon::DrawImGuiDebugger() { - // Proof of concept - if (ImGui::Button("Run")) { + if (ImGui::Button("Run/Resume")) { Core_Resume(); } ImGui::SameLine(); - if (ImGui::Button("Next Tex")) { + ImGui::TextUnformatted("Break:"); + ImGui::SameLine(); + if (ImGui::Button("Frame")) { + GPUDebug::SetBreakNext(GPUDebug::BreakNext::FRAME); + } + ImGui::SameLine(); + if (ImGui::Button("Tex")) { GPUDebug::SetBreakNext(GPUDebug::BreakNext::TEX); } ImGui::SameLine(); - if (ImGui::Button("Next Prim")) { + if (ImGui::Button("NonTex")) { + GPUDebug::SetBreakNext(GPUDebug::BreakNext::NONTEX); + } + ImGui::SameLine(); + if (ImGui::Button("Prim")) { GPUDebug::SetBreakNext(GPUDebug::BreakNext::PRIM); } ImGui::SameLine(); + if (ImGui::Button("Draw")) { + GPUDebug::SetBreakNext(GPUDebug::BreakNext::DRAW); + } + ImGui::SameLine(); + if (ImGui::Button("Curve")) { + GPUDebug::SetBreakNext(GPUDebug::BreakNext::CURVE); + } + ImGui::SameLine(); if (ImGui::Button("Single step")) { GPUDebug::SetBreakNext(GPUDebug::BreakNext::OP); } + // Let's display the current CLUT. + // First, let's list any active display lists. ImGui::Text("Next list ID: %d", nextListID); for (auto index : dlQueue) { diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 98b7ed623f..f516c9162a 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -825,6 +825,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu } if (ImGui::BeginMenu("Graphics")) { ImGui::MenuItem("GE Debugger", nullptr, &cfg_.geDebuggerOpen); + ImGui::MenuItem("GE Registers", nullptr, &cfg_.geRegistersOpen); ImGui::MenuItem("Display Output", nullptr, &cfg_.displayOpen); ImGui::MenuItem("Textures", nullptr, &cfg_.texturesOpen); ImGui::MenuItem("Framebuffers", nullptr, &cfg_.framebuffersOpen); @@ -927,6 +928,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu if (cfg_.geDebuggerOpen) { DrawGeDebuggerWindow(cfg_); } + + if (cfg_.geRegistersOpen) { + DrawGeRegistersWindow(cfg_); + } } void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, CoreState coreState) { diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 08f4016be3..f8388a8bc5 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -80,6 +80,7 @@ struct ImConfig { bool audioChannelsOpen; bool debugStatsOpen; bool geDebuggerOpen; + bool geRegistersOpen; // HLE explorer settings // bool filterByUsed = true; diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index 4534dc650e..4c1cdc5b43 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -85,3 +85,27 @@ void DrawGeDebuggerWindow(ImConfig &cfg) { ImGui::End(); } + +// TODO: Separate window or merge into Ge debugger? +void DrawGeRegistersWindow(ImConfig &cfg) { + ImGui::SetNextWindowSize(ImVec2(300, 500), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Debug Stats", &cfg.geRegistersOpen)) { + ImGui::End(); + return; + } + + if (ImGui::BeginTabBar("GeRegs", ImGuiTabBarFlags_None)) { + if (ImGui::BeginTabItem("Control")) { + if (ImGui::BeginTable("fpr", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("bkpt", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("name", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch); + + ImGui::EndTable(); + } + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::End(); +} diff --git a/UI/ImDebugger/ImGe.h b/UI/ImDebugger/ImGe.h index f75d1acf12..bd9ffcbdfd 100644 --- a/UI/ImDebugger/ImGe.h +++ b/UI/ImDebugger/ImGe.h @@ -12,6 +12,7 @@ void DrawTexturesWindow(ImConfig &cfg, TextureCacheCommon *textureCache); void DrawDisplayWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager); void DrawDebugStatsWindow(ImConfig &cfg); void DrawGeDebuggerWindow(ImConfig &cfg); +void DrawGeRegistersWindow(ImConfig &cfg); class ImGeDebugger { public: diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 9c1cd5c3ab..7bb4b346bd 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -151,6 +151,7 @@ + @@ -219,6 +220,7 @@ + diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 9934806fcb..84b4c5d396 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -31,12 +31,6 @@ - - - - - - @@ -65,6 +59,27 @@ + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + @@ -95,13 +110,6 @@ - - - - - - - @@ -131,5 +139,34 @@ + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + Debugger + + + + + {49bcf7f6-518a-4ecd-af55-bda3a344efe7} + diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index e07aa38fc3..7329e30ada 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -158,7 +158,7 @@ void CtrlThreadList::showMenu(int itemIndex, const POINT &pt) } } -void CtrlThreadList::GetColumnText(wchar_t* dest, int row, int col) +void CtrlThreadList::GetColumnText(wchar_t* dest, size_t destSize, int row, int col) { if (row < 0 || row >= (int)threads.size()) { return; @@ -457,7 +457,7 @@ int CtrlBreakpointList::getBreakpointIndex(int itemIndex, bool& isMemory) return -1; } -void CtrlBreakpointList::GetColumnText(wchar_t* dest, int row, int col) +void CtrlBreakpointList::GetColumnText(wchar_t* dest, size_t destSize, int row, int col) { if (!PSP_IsInited()) { return; @@ -512,10 +512,8 @@ void CtrlBreakpointList::GetColumnText(wchar_t* dest, int row, int col) wsprintf(dest,L"0x%08X",mc.end-mc.start); } else { const std::string sym = g_symbolMap->GetLabelString(displayedBreakPoints_[index].addr); - if (!sym.empty()) - { - std::wstring s = ConvertUTF8ToWString(sym); - wcscpy(dest,s.c_str()); + if (!sym.empty()) { + ConvertUTF8ToWString(dest, destSize, sym); } else { wcscpy(dest,L"-"); } @@ -529,8 +527,7 @@ void CtrlBreakpointList::GetColumnText(wchar_t* dest, int row, int col) } else { char temp[256]; disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp, sizeof(temp)); - std::wstring s = ConvertUTF8ToWString(temp); - wcscpy(dest,s.c_str()); + ConvertUTF8ToWString(dest, destSize, temp); } } break; @@ -669,7 +666,7 @@ bool CtrlStackTraceView::WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, L return false; } -void CtrlStackTraceView::GetColumnText(wchar_t* dest, int row, int col) +void CtrlStackTraceView::GetColumnText(wchar_t* dest, size_t destSize, int row, int col) { // We should have emptied the list if g_symbolMap is nullptr, but apparently we don't, // so let's have a sanity check here. @@ -779,16 +776,15 @@ bool CtrlModuleList::WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESU return false; } -void CtrlModuleList::GetColumnText(wchar_t* dest, int row, int col) +void CtrlModuleList::GetColumnText(wchar_t* dest, size_t destSize, int row, int col) { if (row < 0 || row >= (int)modules.size()) { return; } - switch (col) - { + switch (col) { case ML_NAME: - wcscpy(dest,ConvertUTF8ToWString(modules[row].name).c_str()); + ConvertUTF8ToWString(dest, destSize, modules[row].name); break; case ML_ADDRESS: wsprintf(dest,L"%08X",modules[row].address); @@ -887,7 +883,7 @@ bool CtrlWatchList::WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESUL return false; } -void CtrlWatchList::GetColumnText(wchar_t *dest, int row, int col) { +void CtrlWatchList::GetColumnText(wchar_t *dest, size_t destSize, int row, int col) { const auto &watch = watches_[row]; switch (col) { case WL_NAME: @@ -913,12 +909,12 @@ void CtrlWatchList::GetColumnText(wchar_t *dest, int row, int col) { break; case WatchFormat::FLOAT: memcpy(&valuef, &value, sizeof(valuef)); - swprintf_s(dest, 255, L"%f", valuef); + swprintf_s(dest, destSize, L"%f", valuef); break; case WatchFormat::STR: if (Memory::IsValidAddress(value)) { uint32_t len = Memory::ValidSize(value, 255); - swprintf_s(dest, 255, L"%.*S", len, Memory::GetCharPointer(value)); + swprintf_s(dest, destSize, L"%.*S", len, Memory::GetCharPointer(value)); } else { wsprintf(dest, L"(0x%08X)", value); } diff --git a/Windows/Debugger/Debugger_Lists.h b/Windows/Debugger/Debugger_Lists.h index 589d1513dc..0a8c7f52ce 100644 --- a/Windows/Debugger/Debugger_Lists.h +++ b/Windows/Debugger/Debugger_Lists.h @@ -23,7 +23,7 @@ public: const char* getCurrentThreadName(); protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override; - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return (int) threads.size(); } void OnDoubleClick(int itemIndex, int column) override; void OnRightClick(int itemIndex, int column, const POINT &point) override; @@ -40,7 +40,7 @@ public: void reloadBreakpoints(); protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override; - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return getTotalBreakpointCount(); } void OnDoubleClick(int itemIndex, int column) override; void OnRightClick(int itemIndex, int column, const POINT &point) override; @@ -68,7 +68,7 @@ public: void loadStackTrace(); protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override; - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return (int)frames.size(); } void OnDoubleClick(int itemIndex, int column) override; private: @@ -84,7 +84,7 @@ public: void loadModules(); protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override; - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return (int)modules.size(); } void OnDoubleClick(int itemIndex, int column) override; private: @@ -99,7 +99,7 @@ public: protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override; - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return (int)watches_.size(); } void OnRightClick(int itemIndex, int column, const POINT &point) override; bool ListenRowPrePaint() override { return true; } diff --git a/Windows/GEDebugger/TabDisplayLists.cpp b/Windows/GEDebugger/TabDisplayLists.cpp index 0e97f6e928..5ef0237587 100644 --- a/Windows/GEDebugger/TabDisplayLists.cpp +++ b/Windows/GEDebugger/TabDisplayLists.cpp @@ -34,7 +34,7 @@ CtrlDisplayListStack::CtrlDisplayListStack(HWND hwnd): GenericListControl(hwnd,d Update(); } -void CtrlDisplayListStack::GetColumnText(wchar_t* dest, int row, int col) +void CtrlDisplayListStack::GetColumnText(wchar_t* dest, size_t destSize, int row, int col) { if (row < 0 || row >= (int)ARRAY_SIZE(list.stack)) { return; @@ -85,7 +85,7 @@ CtrlAllDisplayLists::CtrlAllDisplayLists(HWND hwnd): GenericListControl(hwnd,all Update(); } -void CtrlAllDisplayLists::GetColumnText(wchar_t* dest, int row, int col) +void CtrlAllDisplayLists::GetColumnText(wchar_t* dest, size_t destSize, int row, int col) { if (row < 0 || row >= (int)lists.size()) { return; diff --git a/Windows/GEDebugger/TabDisplayLists.h b/Windows/GEDebugger/TabDisplayLists.h index 4843024991..b4e7e4d36d 100644 --- a/Windows/GEDebugger/TabDisplayLists.h +++ b/Windows/GEDebugger/TabDisplayLists.h @@ -18,7 +18,7 @@ public: } protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override { return false; } - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return list.stackptr; } void OnDoubleClick(int itemIndex, int column) override; private: @@ -35,7 +35,7 @@ public: } protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override; - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return (int) lists.size(); } void OnDoubleClick(int itemIndex, int column) override; private: diff --git a/Windows/GEDebugger/TabState.cpp b/Windows/GEDebugger/TabState.cpp index 335cf2302e..984142b296 100644 --- a/Windows/GEDebugger/TabState.cpp +++ b/Windows/GEDebugger/TabState.cpp @@ -20,6 +20,7 @@ #include #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" +#include "Common/System/Request.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Text/Parsers.h" #include "Common/Log.h" @@ -34,6 +35,7 @@ #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Debugger/Breakpoints.h" #include "GPU/Debugger/Stepping.h" +#include "GPU/Debugger/State.h" using namespace GPUBreakpoints; @@ -57,226 +59,185 @@ enum StateValuesCols { STATEVALUES_COL_VALUE, }; -enum CmdFormatType { - CMD_FMT_HEX = 0, - CMD_FMT_NUM, - CMD_FMT_FLOAT24, - CMD_FMT_PTRWIDTH, - CMD_FMT_XY, - CMD_FMT_XYXY, - CMD_FMT_XYZ, - CMD_FMT_XYPLUS1, - CMD_FMT_TEXSIZE, - CMD_FMT_F16_XY, - CMD_FMT_VERTEXTYPE, - CMD_FMT_TEXFMT, - CMD_FMT_CLUTFMT, - CMD_FMT_COLORTEST, - CMD_FMT_ALPHATEST, - CMD_FMT_STENCILTEST, - CMD_FMT_ZTEST, - CMD_FMT_OFFSETADDR, - CMD_FMT_VADDR, - CMD_FMT_IADDR, - CMD_FMT_MATERIALUPDATE, - CMD_FMT_STENCILOP, - CMD_FMT_BLENDMODE, - CMD_FMT_FLAG, - CMD_FMT_CLEARMODE, - CMD_FMT_TEXFUNC, - CMD_FMT_TEXMODE, - CMD_FMT_LOGICOP, - CMD_FMT_TEXWRAP, - CMD_FMT_TEXLEVEL, - CMD_FMT_TEXFILTER, - CMD_FMT_TEXMAPMODE, - CMD_FMT_TEXSHADELS, - CMD_FMT_SHADEMODEL, - CMD_FMT_LIGHTMODE, - CMD_FMT_LIGHTTYPE, - CMD_FMT_CULL, - CMD_FMT_PATCHPRIMITIVE, -}; - struct TabStateRow { - const TCHAR *title; - u8 cmd; + std::string_view title; + uint8_t cmd; CmdFormatType fmt; - u8 enableCmd; - u8 otherCmd; - u8 otherCmd2; + uint8_t enableCmd; + uint8_t otherCmd; + uint8_t otherCmd2; }; -static const TabStateRow stateFlagsRows[] = { - { L"Lighting enable", GE_CMD_LIGHTINGENABLE, CMD_FMT_FLAG }, - { L"Light 0 enable", GE_CMD_LIGHTENABLE0, CMD_FMT_FLAG }, - { L"Light 1 enable", GE_CMD_LIGHTENABLE1, CMD_FMT_FLAG }, - { L"Light 2 enable", GE_CMD_LIGHTENABLE2, CMD_FMT_FLAG }, - { L"Light 3 enable", GE_CMD_LIGHTENABLE3, CMD_FMT_FLAG }, - { L"Depth clamp enable", GE_CMD_DEPTHCLAMPENABLE, CMD_FMT_FLAG }, - { L"Cullface enable", GE_CMD_CULLFACEENABLE, CMD_FMT_FLAG }, - { L"Texture map enable", GE_CMD_TEXTUREMAPENABLE, CMD_FMT_FLAG }, - { L"Fog enable", GE_CMD_FOGENABLE, CMD_FMT_FLAG }, - { L"Dither enable", GE_CMD_DITHERENABLE, CMD_FMT_FLAG }, - { L"Alpha blend enable", GE_CMD_ALPHABLENDENABLE, CMD_FMT_FLAG }, - { L"Alpha test enable", GE_CMD_ALPHATESTENABLE, CMD_FMT_FLAG }, - { L"Depth test enable", GE_CMD_ZTESTENABLE, CMD_FMT_FLAG }, - { L"Stencil test enable", GE_CMD_STENCILTESTENABLE, CMD_FMT_FLAG }, - { L"Antialias enable", GE_CMD_ANTIALIASENABLE, CMD_FMT_FLAG }, - { L"Patch cull enable", GE_CMD_PATCHCULLENABLE, CMD_FMT_FLAG }, - { L"Color test enable", GE_CMD_COLORTESTENABLE, CMD_FMT_FLAG }, - { L"Logic op enable", GE_CMD_LOGICOPENABLE, CMD_FMT_FLAG }, - { L"Depth write disable", GE_CMD_ZWRITEDISABLE, CMD_FMT_FLAG }, +static const TabStateRow g_stateFlagsRows[] = { + { "Lighting enable", GE_CMD_LIGHTINGENABLE, CMD_FMT_FLAG }, + { "Light 0 enable", GE_CMD_LIGHTENABLE0, CMD_FMT_FLAG }, + { "Light 1 enable", GE_CMD_LIGHTENABLE1, CMD_FMT_FLAG }, + { "Light 2 enable", GE_CMD_LIGHTENABLE2, CMD_FMT_FLAG }, + { "Light 3 enable", GE_CMD_LIGHTENABLE3, CMD_FMT_FLAG }, + { "Depth clamp enable", GE_CMD_DEPTHCLAMPENABLE, CMD_FMT_FLAG }, + { "Cullface enable", GE_CMD_CULLFACEENABLE, CMD_FMT_FLAG }, + { "Texture map enable", GE_CMD_TEXTUREMAPENABLE, CMD_FMT_FLAG }, + { "Fog enable", GE_CMD_FOGENABLE, CMD_FMT_FLAG }, + { "Dither enable", GE_CMD_DITHERENABLE, CMD_FMT_FLAG }, + { "Alpha blend enable", GE_CMD_ALPHABLENDENABLE, CMD_FMT_FLAG }, + { "Alpha test enable", GE_CMD_ALPHATESTENABLE, CMD_FMT_FLAG }, + { "Depth test enable", GE_CMD_ZTESTENABLE, CMD_FMT_FLAG }, + { "Stencil test enable", GE_CMD_STENCILTESTENABLE, CMD_FMT_FLAG }, + { "Antialias enable", GE_CMD_ANTIALIASENABLE, CMD_FMT_FLAG }, + { "Patch cull enable", GE_CMD_PATCHCULLENABLE, CMD_FMT_FLAG }, + { "Color test enable", GE_CMD_COLORTESTENABLE, CMD_FMT_FLAG }, + { "Logic op enable", GE_CMD_LOGICOPENABLE, CMD_FMT_FLAG }, + { "Depth write disable", GE_CMD_ZWRITEDISABLE, CMD_FMT_FLAG }, }; -static const TabStateRow stateLightingRows[] = { - { L"Ambient color", GE_CMD_AMBIENTCOLOR, CMD_FMT_HEX }, - { L"Ambient alpha", GE_CMD_AMBIENTALPHA, CMD_FMT_HEX }, - { L"Material update", GE_CMD_MATERIALUPDATE, CMD_FMT_MATERIALUPDATE }, - { L"Material emissive", GE_CMD_MATERIALEMISSIVE, CMD_FMT_HEX }, - { L"Material ambient", GE_CMD_MATERIALAMBIENT, CMD_FMT_HEX }, - { L"Material diffuse", GE_CMD_MATERIALDIFFUSE, CMD_FMT_HEX }, - { L"Material alpha", GE_CMD_MATERIALALPHA, CMD_FMT_HEX }, - { L"Material specular", GE_CMD_MATERIALSPECULAR, CMD_FMT_HEX }, - { L"Mat. specular coef", GE_CMD_MATERIALSPECULARCOEF, CMD_FMT_FLOAT24 }, - { L"Reverse normals", GE_CMD_REVERSENORMAL, CMD_FMT_FLAG }, - { L"Shade model", GE_CMD_SHADEMODE, CMD_FMT_SHADEMODEL }, - { L"Light mode", GE_CMD_LIGHTMODE, CMD_FMT_LIGHTMODE, GE_CMD_LIGHTINGENABLE }, - { L"Light type 0", GE_CMD_LIGHTTYPE0, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE0 }, - { L"Light type 1", GE_CMD_LIGHTTYPE1, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE1 }, - { L"Light type 2", GE_CMD_LIGHTTYPE2, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE2 }, - { L"Light type 3", GE_CMD_LIGHTTYPE3, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE3 }, - { L"Light pos 0", GE_CMD_LX0, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE0, GE_CMD_LY0, GE_CMD_LZ0 }, - { L"Light pos 1", GE_CMD_LX1, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE1, GE_CMD_LY1, GE_CMD_LZ1 }, - { L"Light pos 2", GE_CMD_LX2, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE2, GE_CMD_LY2, GE_CMD_LZ2 }, - { L"Light pos 3", GE_CMD_LX3, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE3, GE_CMD_LY3, GE_CMD_LZ3 }, - { L"Light dir 0", GE_CMD_LDX0, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE0, GE_CMD_LDY0, GE_CMD_LDZ0 }, - { L"Light dir 1", GE_CMD_LDX1, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE1, GE_CMD_LDY1, GE_CMD_LDZ1 }, - { L"Light dir 2", GE_CMD_LDX2, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE2, GE_CMD_LDY2, GE_CMD_LDZ2 }, - { L"Light dir 3", GE_CMD_LDX3, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE3, GE_CMD_LDY3, GE_CMD_LDZ3 }, - { L"Light att 0", GE_CMD_LKA0, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE0, GE_CMD_LKB0, GE_CMD_LKC0 }, - { L"Light att 1", GE_CMD_LKA1, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE1, GE_CMD_LKB1, GE_CMD_LKC1 }, - { L"Light att 2", GE_CMD_LKA2, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE2, GE_CMD_LKB2, GE_CMD_LKC2 }, - { L"Light att 3", GE_CMD_LKA3, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE3, GE_CMD_LKB3, GE_CMD_LKC3 }, - { L"Lightspot coef 0", GE_CMD_LKS0, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE0 }, - { L"Lightspot coef 1", GE_CMD_LKS1, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE1 }, - { L"Lightspot coef 2", GE_CMD_LKS2, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE2 }, - { L"Lightspot coef 3", GE_CMD_LKS3, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE3 }, - { L"Light angle 0", GE_CMD_LKO0, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE0 }, - { L"Light angle 1", GE_CMD_LKO1, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE1 }, - { L"Light angle 2", GE_CMD_LKO2, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE2 }, - { L"Light angle 3", GE_CMD_LKO3, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE3 }, - { L"Light ambient 0", GE_CMD_LAC0, CMD_FMT_HEX, GE_CMD_LIGHTENABLE0 }, - { L"Light diffuse 0", GE_CMD_LDC0, CMD_FMT_HEX, GE_CMD_LIGHTENABLE0 }, - { L"Light specular 0", GE_CMD_LSC0, CMD_FMT_HEX, GE_CMD_LIGHTENABLE0 }, - { L"Light ambient 1", GE_CMD_LAC1, CMD_FMT_HEX, GE_CMD_LIGHTENABLE1 }, - { L"Light diffuse 1", GE_CMD_LDC1, CMD_FMT_HEX, GE_CMD_LIGHTENABLE1 }, - { L"Light specular 1", GE_CMD_LSC1, CMD_FMT_HEX, GE_CMD_LIGHTENABLE1 }, - { L"Light ambient 2", GE_CMD_LAC2, CMD_FMT_HEX, GE_CMD_LIGHTENABLE2 }, - { L"Light diffuse 2", GE_CMD_LDC2, CMD_FMT_HEX, GE_CMD_LIGHTENABLE2 }, - { L"Light specular 2", GE_CMD_LSC2, CMD_FMT_HEX, GE_CMD_LIGHTENABLE2 }, - { L"Light ambient 3", GE_CMD_LAC3, CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 }, - { L"Light diffuse 3", GE_CMD_LDC3, CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 }, - { L"Light specular 3", GE_CMD_LSC3, CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 }, +static const TabStateRow g_stateLightingRows[] = { + { "Ambient color", GE_CMD_AMBIENTCOLOR, CMD_FMT_HEX }, + { "Ambient alpha", GE_CMD_AMBIENTALPHA, CMD_FMT_HEX }, + { "Material update", GE_CMD_MATERIALUPDATE, CMD_FMT_MATERIALUPDATE }, + { "Material emissive", GE_CMD_MATERIALEMISSIVE, CMD_FMT_HEX }, + { "Material ambient", GE_CMD_MATERIALAMBIENT, CMD_FMT_HEX }, + { "Material diffuse", GE_CMD_MATERIALDIFFUSE, CMD_FMT_HEX }, + { "Material alpha", GE_CMD_MATERIALALPHA, CMD_FMT_HEX }, + { "Material specular", GE_CMD_MATERIALSPECULAR, CMD_FMT_HEX }, + { "Mat. specular coef", GE_CMD_MATERIALSPECULARCOEF, CMD_FMT_FLOAT24 }, + { "Reverse normals", GE_CMD_REVERSENORMAL, CMD_FMT_FLAG }, + { "Shade model", GE_CMD_SHADEMODE, CMD_FMT_SHADEMODEL }, + { "Light mode", GE_CMD_LIGHTMODE, CMD_FMT_LIGHTMODE, GE_CMD_LIGHTINGENABLE }, + { "Light type 0", GE_CMD_LIGHTTYPE0, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE0 }, + { "Light type 1", GE_CMD_LIGHTTYPE1, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE1 }, + { "Light type 2", GE_CMD_LIGHTTYPE2, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE2 }, + { "Light type 3", GE_CMD_LIGHTTYPE3, CMD_FMT_LIGHTTYPE, GE_CMD_LIGHTENABLE3 }, + { "Light pos 0", GE_CMD_LX0, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE0, GE_CMD_LY0, GE_CMD_LZ0 }, + { "Light pos 1", GE_CMD_LX1, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE1, GE_CMD_LY1, GE_CMD_LZ1 }, + { "Light pos 2", GE_CMD_LX2, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE2, GE_CMD_LY2, GE_CMD_LZ2 }, + { "Light pos 3", GE_CMD_LX3, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE3, GE_CMD_LY3, GE_CMD_LZ3 }, + { "Light dir 0", GE_CMD_LDX0, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE0, GE_CMD_LDY0, GE_CMD_LDZ0 }, + { "Light dir 1", GE_CMD_LDX1, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE1, GE_CMD_LDY1, GE_CMD_LDZ1 }, + { "Light dir 2", GE_CMD_LDX2, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE2, GE_CMD_LDY2, GE_CMD_LDZ2 }, + { "Light dir 3", GE_CMD_LDX3, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE3, GE_CMD_LDY3, GE_CMD_LDZ3 }, + { "Light att 0", GE_CMD_LKA0, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE0, GE_CMD_LKB0, GE_CMD_LKC0 }, + { "Light att 1", GE_CMD_LKA1, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE1, GE_CMD_LKB1, GE_CMD_LKC1 }, + { "Light att 2", GE_CMD_LKA2, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE2, GE_CMD_LKB2, GE_CMD_LKC2 }, + { "Light att 3", GE_CMD_LKA3, CMD_FMT_XYZ, GE_CMD_LIGHTENABLE3, GE_CMD_LKB3, GE_CMD_LKC3 }, + { "Lightspot coef 0", GE_CMD_LKS0, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE0 }, + { "Lightspot coef 1", GE_CMD_LKS1, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE1 }, + { "Lightspot coef 2", GE_CMD_LKS2, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE2 }, + { "Lightspot coef 3", GE_CMD_LKS3, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE3 }, + { "Light angle 0", GE_CMD_LKO0, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE0 }, + { "Light angle 1", GE_CMD_LKO1, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE1 }, + { "Light angle 2", GE_CMD_LKO2, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE2 }, + { "Light angle 3", GE_CMD_LKO3, CMD_FMT_FLOAT24, GE_CMD_LIGHTENABLE3 }, + { "Light ambient 0", GE_CMD_LAC0, CMD_FMT_HEX, GE_CMD_LIGHTENABLE0 }, + { "Light diffuse 0", GE_CMD_LDC0, CMD_FMT_HEX, GE_CMD_LIGHTENABLE0 }, + { "Light specular 0", GE_CMD_LSC0, CMD_FMT_HEX, GE_CMD_LIGHTENABLE0 }, + { "Light ambient 1", GE_CMD_LAC1, CMD_FMT_HEX, GE_CMD_LIGHTENABLE1 }, + { "Light diffuse 1", GE_CMD_LDC1, CMD_FMT_HEX, GE_CMD_LIGHTENABLE1 }, + { "Light specular 1", GE_CMD_LSC1, CMD_FMT_HEX, GE_CMD_LIGHTENABLE1 }, + { "Light ambient 2", GE_CMD_LAC2, CMD_FMT_HEX, GE_CMD_LIGHTENABLE2 }, + { "Light diffuse 2", GE_CMD_LDC2, CMD_FMT_HEX, GE_CMD_LIGHTENABLE2 }, + { "Light specular 2", GE_CMD_LSC2, CMD_FMT_HEX, GE_CMD_LIGHTENABLE2 }, + { "Light ambient 3", GE_CMD_LAC3, CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 }, + { "Light diffuse 3", GE_CMD_LDC3, CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 }, + { "Light specular 3", GE_CMD_LSC3, CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 }, }; -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 }, +static const TabStateRow g_stateTextureRows[] = { + { "Texture L0 addr", GE_CMD_TEXADDR0, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH0 }, + { "Texture L0 size", GE_CMD_TEXSIZE0, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Tex format", GE_CMD_TEXFORMAT, CMD_FMT_TEXFMT, GE_CMD_TEXTUREMAPENABLE }, + { "Tex CLUT", GE_CMD_CLUTADDR, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_CLUTADDRUPPER }, + { "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 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"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 }, - { L"Texture L4 addr", GE_CMD_TEXADDR4, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH4 }, - { 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 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 }, - { L"Texture L4 size", GE_CMD_TEXSIZE4, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, - { L"Texture L5 size", GE_CMD_TEXSIZE5, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, - { L"Texture L6 size", GE_CMD_TEXSIZE6, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, - { L"Texture L7 size", GE_CMD_TEXSIZE7, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Tex U scale", GE_CMD_TEXSCALEU, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, + { "Tex V scale", GE_CMD_TEXSCALEV, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, + { "Tex U offset", GE_CMD_TEXOFFSETU, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, + { "Tex V offset", GE_CMD_TEXOFFSETV, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, + { "Tex mapping mode", GE_CMD_TEXMAPMODE, CMD_FMT_TEXMAPMODE, GE_CMD_TEXTUREMAPENABLE }, + { "Tex shade srcs", GE_CMD_TEXSHADELS, CMD_FMT_TEXSHADELS, GE_CMD_TEXTUREMAPENABLE }, + { "Tex func", GE_CMD_TEXFUNC, CMD_FMT_TEXFUNC, GE_CMD_TEXTUREMAPENABLE }, + { "Tex env color", GE_CMD_TEXENVCOLOR, CMD_FMT_HEX, GE_CMD_TEXTUREMAPENABLE }, + { "Tex mode", GE_CMD_TEXMODE, CMD_FMT_TEXMODE, GE_CMD_TEXTUREMAPENABLE }, + { "Tex filtering", GE_CMD_TEXFILTER, CMD_FMT_TEXFILTER, GE_CMD_TEXTUREMAPENABLE }, + { "Tex wrapping", GE_CMD_TEXWRAP, CMD_FMT_TEXWRAP, GE_CMD_TEXTUREMAPENABLE }, + { "Tex level/bias", GE_CMD_TEXLEVEL, CMD_FMT_TEXLEVEL, GE_CMD_TEXTUREMAPENABLE }, + { "Tex lod slope", GE_CMD_TEXLODSLOPE, CMD_FMT_FLOAT24, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L1 addr", GE_CMD_TEXADDR1, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH1 }, + { "Texture L2 addr", GE_CMD_TEXADDR2, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH2 }, + { "Texture L3 addr", GE_CMD_TEXADDR3, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH3 }, + { "Texture L4 addr", GE_CMD_TEXADDR4, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH4 }, + { "Texture L5 addr", GE_CMD_TEXADDR5, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH5 }, + { "Texture L6 addr", GE_CMD_TEXADDR6, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH6 }, + { "Texture L7 addr", GE_CMD_TEXADDR7, CMD_FMT_PTRWIDTH, GE_CMD_TEXTUREMAPENABLE, GE_CMD_TEXBUFWIDTH7 }, + { "Texture L1 size", GE_CMD_TEXSIZE1, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L2 size", GE_CMD_TEXSIZE2, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L3 size", GE_CMD_TEXSIZE3, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L4 size", GE_CMD_TEXSIZE4, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L5 size", GE_CMD_TEXSIZE5, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L6 size", GE_CMD_TEXSIZE6, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, + { "Texture L7 size", GE_CMD_TEXSIZE7, CMD_FMT_TEXSIZE, GE_CMD_TEXTUREMAPENABLE }, }; -static const TabStateRow stateSettingsRows[] = { - { 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_XYPLUS1 }, - { 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"Min Z", GE_CMD_MINZ, CMD_FMT_HEX }, - { L"Max Z", GE_CMD_MAXZ, CMD_FMT_HEX }, - { 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"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 }, - { L"Logic Op", GE_CMD_LOGICOP, CMD_FMT_LOGICOP, GE_CMD_LOGICOPENABLE }, - { 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"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 }, - { L"Morph Weight 3", GE_CMD_MORPHWEIGHT3, CMD_FMT_FLOAT24 }, - { L"Morph Weight 4", GE_CMD_MORPHWEIGHT4, CMD_FMT_FLOAT24 }, - { L"Morph Weight 5", GE_CMD_MORPHWEIGHT5, CMD_FMT_FLOAT24 }, - { L"Morph Weight 6", GE_CMD_MORPHWEIGHT6, CMD_FMT_FLOAT24 }, - { L"Morph Weight 7", GE_CMD_MORPHWEIGHT7, CMD_FMT_FLOAT24 }, +static const TabStateRow g_stateSettingsRows[] = { + { "Framebuffer", GE_CMD_FRAMEBUFPTR, CMD_FMT_PTRWIDTH, 0, GE_CMD_FRAMEBUFWIDTH }, + { "Framebuffer format", GE_CMD_FRAMEBUFPIXFORMAT, CMD_FMT_TEXFMT }, + { "Depthbuffer", GE_CMD_ZBUFPTR, CMD_FMT_PTRWIDTH, 0, GE_CMD_ZBUFWIDTH }, + { "Viewport Scale", GE_CMD_VIEWPORTXSCALE, CMD_FMT_XYZ, 0, GE_CMD_VIEWPORTYSCALE, GE_CMD_VIEWPORTZSCALE }, + { "Viewport Offset", GE_CMD_VIEWPORTXCENTER, CMD_FMT_XYZ, 0, GE_CMD_VIEWPORTYCENTER, GE_CMD_VIEWPORTZCENTER }, + { "Scissor", GE_CMD_SCISSOR1, CMD_FMT_XYXY, 0, GE_CMD_SCISSOR2 }, + { "Region", GE_CMD_REGION1, CMD_FMT_XYXY, 0, GE_CMD_REGION2 }, + { "Color test", GE_CMD_COLORTEST, CMD_FMT_COLORTEST, GE_CMD_COLORTESTENABLE, GE_CMD_COLORREF, GE_CMD_COLORTESTMASK }, + { "Alpha test", GE_CMD_ALPHATEST, CMD_FMT_ALPHATEST, GE_CMD_ALPHATESTENABLE }, + { "Clear mode", GE_CMD_CLEARMODE, CMD_FMT_CLEARMODE }, + { "Stencil test", GE_CMD_STENCILTEST, CMD_FMT_STENCILTEST, GE_CMD_STENCILTESTENABLE }, + { "Stencil test op", GE_CMD_STENCILOP, CMD_FMT_STENCILOP, GE_CMD_STENCILTESTENABLE }, + { "Depth test", GE_CMD_ZTEST, CMD_FMT_ZTEST, GE_CMD_ZTESTENABLE }, + { "RGB mask", GE_CMD_MASKRGB, CMD_FMT_HEX }, + { "Stencil/alpha mask", GE_CMD_MASKALPHA, CMD_FMT_HEX }, + { "Transfer src", GE_CMD_TRANSFERSRC, CMD_FMT_PTRWIDTH, 0, GE_CMD_TRANSFERSRCW }, + { "Transfer src pos", GE_CMD_TRANSFERSRCPOS, CMD_FMT_XY }, + { "Transfer dst", GE_CMD_TRANSFERDST, CMD_FMT_PTRWIDTH, 0, GE_CMD_TRANSFERDSTW }, + { "Transfer dst pos", GE_CMD_TRANSFERDSTPOS, CMD_FMT_XY }, + { "Transfer size", GE_CMD_TRANSFERSIZE, CMD_FMT_XYPLUS1 }, + { "Vertex type", GE_CMD_VERTEXTYPE, CMD_FMT_VERTEXTYPE }, + { "Offset addr", GE_CMD_OFFSETADDR, CMD_FMT_OFFSETADDR }, + { "Vertex addr", GE_CMD_VADDR, CMD_FMT_VADDR }, + { "Index addr", GE_CMD_IADDR, CMD_FMT_IADDR }, + { "Min Z", GE_CMD_MINZ, CMD_FMT_HEX }, + { "Max Z", GE_CMD_MAXZ, CMD_FMT_HEX }, + { "Offset", GE_CMD_OFFSETX, CMD_FMT_F16_XY, 0, GE_CMD_OFFSETY }, + { "Cull mode", GE_CMD_CULL, CMD_FMT_CULL, GE_CMD_CULLFACEENABLE }, + { "Alpha blend mode", GE_CMD_BLENDMODE, CMD_FMT_BLENDMODE, GE_CMD_ALPHABLENDENABLE }, + { "Blend color A", GE_CMD_BLENDFIXEDA, CMD_FMT_HEX, GE_CMD_ALPHABLENDENABLE }, + { "Blend color B", GE_CMD_BLENDFIXEDB, CMD_FMT_HEX, GE_CMD_ALPHABLENDENABLE }, + { "Logic Op", GE_CMD_LOGICOP, CMD_FMT_LOGICOP, GE_CMD_LOGICOPENABLE }, + { "Fog 1", GE_CMD_FOG1, CMD_FMT_FLOAT24, GE_CMD_FOGENABLE }, + { "Fog 2", GE_CMD_FOG2, CMD_FMT_FLOAT24, GE_CMD_FOGENABLE }, + { "Fog color", GE_CMD_FOGCOLOR, CMD_FMT_HEX, GE_CMD_FOGENABLE }, + { "Morph Weight 0", GE_CMD_MORPHWEIGHT0, CMD_FMT_FLOAT24 }, + { "Morph Weight 1", GE_CMD_MORPHWEIGHT1, CMD_FMT_FLOAT24 }, + { "Morph Weight 2", GE_CMD_MORPHWEIGHT2, CMD_FMT_FLOAT24 }, + { "Morph Weight 3", GE_CMD_MORPHWEIGHT3, CMD_FMT_FLOAT24 }, + { "Morph Weight 4", GE_CMD_MORPHWEIGHT4, CMD_FMT_FLOAT24 }, + { "Morph Weight 5", GE_CMD_MORPHWEIGHT5, CMD_FMT_FLOAT24 }, + { "Morph Weight 6", GE_CMD_MORPHWEIGHT6, CMD_FMT_FLOAT24 }, + { "Morph Weight 7", GE_CMD_MORPHWEIGHT7, CMD_FMT_FLOAT24 }, // TODO: Format? - { L"Patch division", GE_CMD_PATCHDIVISION, CMD_FMT_HEX }, - { L"Patch primitive", GE_CMD_PATCHPRIMITIVE, CMD_FMT_PATCHPRIMITIVE }, + { "Patch division", GE_CMD_PATCHDIVISION, CMD_FMT_HEX }, + { "Patch primitive", GE_CMD_PATCHPRIMITIVE, CMD_FMT_PATCHPRIMITIVE }, // TODO: Format? - { L"Patch facing", GE_CMD_PATCHFACING, CMD_FMT_HEX, GE_CMD_PATCHCULLENABLE }, - { L"Dither 0", GE_CMD_DITH0, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, - { 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"Imm vertex XY", GE_CMD_VSCX, CMD_FMT_F16_XY, 0, GE_CMD_VSCY }, - { L"Imm vertex Z", GE_CMD_VSCZ, CMD_FMT_HEX }, - { L"Imm vertex tex STQ", GE_CMD_VTCS, CMD_FMT_XYZ, 0, GE_CMD_VTCT, GE_CMD_VTCQ }, - { L"Imm vertex color0", GE_CMD_VCV, CMD_FMT_HEX }, - { L"Imm vertex color1", GE_CMD_VSCV, CMD_FMT_HEX }, - { L"Imm vertex fog", GE_CMD_VFC, CMD_FMT_HEX }, + { "Patch facing", GE_CMD_PATCHFACING, CMD_FMT_HEX, GE_CMD_PATCHCULLENABLE }, + { "Dither 0", GE_CMD_DITH0, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, + { "Dither 1", GE_CMD_DITH1, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, + { "Dither 2", GE_CMD_DITH2, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, + { "Dither 3", GE_CMD_DITH3, CMD_FMT_HEX, GE_CMD_DITHERENABLE }, + { "Imm vertex XY", GE_CMD_VSCX, CMD_FMT_F16_XY, 0, GE_CMD_VSCY }, + { "Imm vertex Z", GE_CMD_VSCZ, CMD_FMT_HEX }, + { "Imm vertex tex STQ", GE_CMD_VTCS, CMD_FMT_XYZ, 0, GE_CMD_VTCT, GE_CMD_VTCQ }, + { "Imm vertex color0", GE_CMD_VCV, CMD_FMT_HEX }, + { "Imm vertex color1", GE_CMD_VSCV, CMD_FMT_HEX }, + { "Imm vertex fog", GE_CMD_VFC, CMD_FMT_HEX }, // TODO: Format? - { L"Imm vertex prim", GE_CMD_VAP, CMD_FMT_HEX }, + { "Imm vertex prim", GE_CMD_VAP, CMD_FMT_HEX }, }; // TODO: Commands not present in the above lists (some because they don't have meaningful values...): @@ -320,7 +281,10 @@ static bool ToggleBreakpoint(const TabStateRow &info) { return true; } -bool PromptStateValue(const TabStateRow &info, HWND hparent, const wchar_t *title, u32 &value) { +bool PromptStateValue(const TabStateRow &info, HWND hparent, const char *title, u32 &value) { + wchar_t wtitle[1024]; + ConvertUTF8ToWString(wtitle, ARRAY_SIZE(wtitle), title); + if (info.fmt == CMD_FMT_FLOAT24 || info.fmt == CMD_FMT_XYZ) { union { u32 u; @@ -328,7 +292,7 @@ bool PromptStateValue(const TabStateRow &info, HWND hparent, const wchar_t *titl } temp = { value << 8 }; std::string strvalue = StringFromFormat("%f", temp.f); - bool res = InputBox_GetString(GetModuleHandle(NULL), hparent, title, strvalue, strvalue); + bool res = InputBox_GetString(GetModuleHandle(NULL), hparent, wtitle, strvalue, strvalue); if (!res) return false; @@ -341,7 +305,7 @@ bool PromptStateValue(const TabStateRow &info, HWND hparent, const wchar_t *titl } return false; } - return InputBox_GetHex(GetModuleHandle(NULL), hparent, title, value, value); + return InputBox_GetHex(GetModuleHandle(NULL), hparent, wtitle, value, value); } CtrlStateValues::CtrlStateValues(const TabStateRow *rows, int rowCount, HWND hwnd) @@ -351,534 +315,7 @@ CtrlStateValues::CtrlStateValues(const TabStateRow *rows, int rowCount, HWND hwn Update(); } -void FormatStateRow(wchar_t *dest, const TabStateRow &info, u32 value, bool enabled, u32 otherValue, u32 otherValue2) { - switch (info.fmt) { - case CMD_FMT_HEX: - swprintf(dest, 255, L"%06x", value); - break; - - case CMD_FMT_NUM: - swprintf(dest, 255, L"%d", value); - break; - - case CMD_FMT_FLOAT24: - swprintf(dest, 255, L"%f", getFloat24(value)); - break; - - case CMD_FMT_PTRWIDTH: - value |= (otherValue & 0x00FF0000) << 8; - otherValue &= 0xFFFF; - swprintf(dest, 255, L"%08x, w=%d", value, otherValue); - break; - - case CMD_FMT_XY: - { - int x = value & 0x3FF; - int y = value >> 10; - swprintf(dest, 255, L"%d,%d", x, y); - } - break; - - case CMD_FMT_XYPLUS1: - { - int x = value & 0x3FF; - int y = value >> 10; - swprintf(dest, 255, L"%d,%d", x + 1, y + 1); - } - break; - - case CMD_FMT_XYXY: - { - int x1 = value & 0x3FF; - int y1 = value >> 10; - int x2 = otherValue & 0x3FF; - int y2 = otherValue >> 10; - swprintf(dest, 255, L"%d,%d - %d,%d", x1, y1, x2, y2); - } - break; - - case CMD_FMT_XYZ: - { - float x = getFloat24(value); - float y = getFloat24(otherValue); - float z = getFloat24(otherValue2); - swprintf(dest, 255, L"%f, %f, %f", x, y, z); - } - break; - - case CMD_FMT_TEXSIZE: - { - int w = 1 << (value & 0x1f); - int h = 1 << ((value >> 8) & 0x1f); - swprintf(dest, 255, L"%dx%d", w, h); - } - break; - - case CMD_FMT_F16_XY: - { - float x = (float)value / 16.0f; - float y = (float)otherValue / 16.0f; - swprintf(dest, 255, L"%fx%f", x, y); - } - break; - - case CMD_FMT_VERTEXTYPE: - { - char buffer[256]; - GeDescribeVertexType(value, buffer); - swprintf(dest, 255, L"%S", buffer); - } - break; - - case CMD_FMT_TEXFMT: - { - static const char *texformats[] = { - "5650", - "5551", - "4444", - "8888", - "CLUT4", - "CLUT8", - "CLUT16", - "CLUT32", - "DXT1", - "DXT3", - "DXT5", - }; - if (value < (u32)ARRAY_SIZE(texformats)) { - swprintf(dest, 255, L"%S", texformats[value]); - } - else if ((value & 0xF) < (u32)ARRAY_SIZE(texformats)) { - swprintf(dest, 255, L"%S (extra bits %06x)", texformats[value & 0xF], value & ~0xF); - } - else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_CLUTFMT: - { - const char *clutformats[] = { - "BGR 5650", - "ABGR 1555", - "ABGR 4444", - "ABGR 8888", - }; - const u8 palette = (value >> 0) & 3; - const u8 shift = (value >> 2) & 0x3F; - const u8 mask = (value >> 8) & 0xFF; - const u8 offset = (value >> 16) & 0xFF; - if (offset < 0x20 && shift < 0x20) { - if (offset == 0 && shift == 0) { - swprintf(dest, 255, L"%S ind & %02x", clutformats[palette], mask); - } else { - swprintf(dest, 255, L"%S (ind >> %d) & %02x, offset +%d", clutformats[palette], shift, mask, offset); - } - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_COLORTEST: - { - static const char *colorTests[] = {"NEVER", "ALWAYS", " == ", " != "}; - const u32 mask = otherValue2; - const u32 ref = otherValue; - if (value < (u32)ARRAY_SIZE(colorTests)) { - swprintf(dest, 255, L"pass if (c & %06x) %S (%06x & %06x)", mask, colorTests[value], ref, mask); - } else { - swprintf(dest, 255, L"%06x, ref=%06x, maks=%06x", value, ref, mask); - } - } - break; - - case CMD_FMT_ALPHATEST: - case CMD_FMT_STENCILTEST: - { - static const char *alphaTestFuncs[] = { "NEVER", "ALWAYS", "==", "!=", "<", "<=", ">", ">=" }; - const u8 mask = (value >> 16) & 0xff; - const u8 ref = (value >> 8) & 0xff; - const u8 func = (value >> 0) & 0xff; - if (func < (u8)ARRAY_SIZE(alphaTestFuncs)) { - if (info.fmt == CMD_FMT_ALPHATEST) { - swprintf(dest, 255, L"pass if (a & %02x) %S (%02x & %02x)", mask, alphaTestFuncs[func], ref, mask); - } else if (info.fmt == CMD_FMT_STENCILTEST) { - // Stencil test is the other way around. - swprintf(dest, 255, L"pass if (%02x & %02x) %S (a & %02x)", ref, mask, alphaTestFuncs[func], mask); - } - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_ZTEST: - { - static const char *zTestFuncs[] = { "NEVER", "ALWAYS", "==", "!=", "<", "<=", ">", ">=" }; - if (value < (u32)ARRAY_SIZE(zTestFuncs)) { - swprintf(dest, 255, L"pass if src %S dst", zTestFuncs[value]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_OFFSETADDR: - swprintf(dest, 255, L"%08x", gpuDebug->GetRelativeAddress(0)); - break; - - case CMD_FMT_VADDR: - swprintf(dest, 255, L"%08x", gpuDebug->GetVertexAddress()); - break; - - case CMD_FMT_IADDR: - swprintf(dest, 255, L"%08x", gpuDebug->GetIndexAddress()); - break; - - case CMD_FMT_MATERIALUPDATE: - { - static const char *materialTypes[] = { - "none", - "ambient", - "diffuse", - "ambient, diffuse", - "specular", - "ambient, specular", - "diffuse, specular", - "ambient, diffuse, specular", - }; - if (value < (u32)ARRAY_SIZE(materialTypes)) { - swprintf(dest, 255, L"%S", materialTypes[value]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_SHADEMODEL: - if (value == 0) { - swprintf(dest, 255, L"flat"); - } else if (value == 1) { - swprintf(dest, 255, L"gouraud"); - } else { - swprintf(dest, 255, L"%06x", value); - } - break; - - case CMD_FMT_STENCILOP: - { - static const char *stencilOps[] = { "KEEP", "ZERO", "REPLACE", "INVERT", "INCREMENT", "DECREMENT" }; - const u8 sfail = (value >> 0) & 0xFF; - const u8 zfail = (value >> 8) & 0xFF; - const u8 pass = (value >> 16) & 0xFF; - const u8 totalValid = (u8)ARRAY_SIZE(stencilOps); - if (sfail < totalValid && zfail < totalValid && pass < totalValid) { - swprintf(dest, 255, L"fail=%S, pass/depthfail=%S, pass=%S", stencilOps[sfail], stencilOps[zfail], stencilOps[pass]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_BLENDMODE: - { - const char *blendModes[] = { - "add", - "subtract", - "reverse subtract", - "min", - "max", - "abs subtract", - }; - const char *blendFactorsA[] = { - "dst", - "1.0 - dst", - "src.a", - "1.0 - src.a", - "dst.a", - "1.0 - dst.a", - "2.0 * src.a", - "1.0 - 2.0 * src.a", - "2.0 * dst.a", - "1.0 - 2.0 * dst.a", - "fixed", - }; - const char *blendFactorsB[] = { - "src", - "1.0 - src", - "src.a", - "1.0 - src.a", - "dst.a", - "1.0 - dst.a", - "2.0 * src.a", - "1.0 - 2.0 * src.a", - "2.0 * dst.a", - "1.0 - 2.0 * dst.a", - "fixed", - }; - const u8 blendFactorA = (value >> 0) & 0xF; - const u8 blendFactorB = (value >> 4) & 0xF; - const u32 blendMode = (value >> 8); - - if (blendFactorA < (u8)ARRAY_SIZE(blendFactorsA) && blendFactorB < (u8)ARRAY_SIZE(blendFactorsB) && blendMode < (u32)ARRAY_SIZE(blendModes)) { - swprintf(dest, 255, L"%S: %S, %S", blendModes[blendMode], blendFactorsA[blendFactorA], blendFactorsB[blendFactorB]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_CLEARMODE: - if (value == 0) { - swprintf(dest, 255, L"%d", value); - } else if ((value & ~(GE_CLEARMODE_ALL | 1)) == 0) { - const char *clearmodes[] = { - "1, write disabled", - "1, write color", - "1, write alpha/stencil", - "1, write color, alpha/stencil", - "1, write depth", - "1, write color, depth", - "1, write alpha/stencil, depth", - "1, write color, alpha/stencil, depth", - }; - swprintf(dest, 255, L"%S", clearmodes[value >> 8]); - } else { - swprintf(dest, 255, L"%06x", value); - } - break; - - case CMD_FMT_TEXFUNC: - { - const char *texfuncs[] = { - "modulate", - "decal", - "blend", - "replace", - "add", - }; - const u8 func = (value >> 0) & 0xFF; - const u8 rgba = (value >> 8) & 0xFF; - const u8 colorDouble = (value >> 16) & 0xFF; - - if (rgba <= 1 && colorDouble <= 1 && func < (u8)ARRAY_SIZE(texfuncs)) { - swprintf(dest, 255, L"%S, %S%S", texfuncs[func], rgba ? "RGBA" : "RGB", colorDouble ? ", color doubling" : ""); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_TEXMODE: - { - const u8 swizzle = (value >> 0) & 0xFF; - const u8 clutLevels = (value >> 8) & 0xFF; - const u8 maxLevel = (value >> 16) & 0xFF; - - if (swizzle <= 1 && clutLevels <= 1 && maxLevel <= 7) { - swprintf(dest, 255, L"%S%d levels%S", swizzle ? "swizzled, " : "", maxLevel + 1, clutLevels ? ", CLUT per level" : ""); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_LOGICOP: - { - const char *logicOps[] = { - "clear", - "and", - "reverse and", - "copy", - "inverted and", - "noop", - "xor", - "or", - "negated or", - "equivalence", - "inverted", - "reverse or", - "inverted copy", - "inverted or", - "negated and", - "set", - }; - - if (value < ARRAY_SIZE(logicOps)) { - swprintf(dest, 255, L"%S", logicOps[value]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_TEXWRAP: - { - if ((value & ~0x0101) == 0) { - const bool clampS = (value & 0x0001) != 0; - const bool clampT = (value & 0x0100) != 0; - swprintf(dest, 255, L"%S s, %S t", clampS ? "clamp" : "wrap", clampT ? "clamp" : "wrap"); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_TEXLEVEL: - { - static constexpr std::array mipLevelModes = { - "auto + bias", - "bias", - "slope + bias", - }; - const int mipLevel = value & 0xFFFF; - const int biasFixed = (s8)(value >> 16); - const float bias = (float)biasFixed / 16.0f; - - if (mipLevel == 0 || mipLevel == 1 || mipLevel == 2) { - swprintf(dest, 255, L"%S: %f", mipLevelModes[mipLevel], bias); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_TEXFILTER: - { - const char *textureFilters[] = { - "nearest", - "linear", - NULL, - NULL, - "nearest, mipmap nearest", - "linear, mipmap nearest", - "nearest, mipmap linear", - "linear, mipmap linear", - }; - if ((value & ~0x0107) == 0 && textureFilters[value & 7] != NULL) { - const int min = (value & 0x0007) >> 0; - const int mag = (value & 0x0100) >> 8; - swprintf(dest, 255, L"min: %S, mag: %S", textureFilters[min], textureFilters[mag]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_TEXMAPMODE: - { - static constexpr std::array uvGenModes = { - "tex coords", - "tex matrix", - "tex env map", - "unknown (tex coords?)", - }; - static constexpr std::array uvProjModes = { - "pos", - "uv", - "normalized normal", - "normal", - }; - if ((value & ~0x0303) == 0) { - const int uvGen = (value & 0x0003) >> 0; - const int uvProj = (value & 0x0300) >> 8; - swprintf(dest, 255, L"gen: %S, proj: %S", uvGenModes[uvGen], uvProjModes[uvProj]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_TEXSHADELS: - if ((value & ~0x0303) == 0) { - const int sLight = (value & 0x0003) >> 0; - const int tLight = (value & 0x0300) >> 8; - swprintf(dest, 255, L"s: %d, t: %d", sLight, tLight); - } else { - swprintf(dest, 255, L"%06x", value); - } - break; - - case CMD_FMT_LIGHTMODE: - if (value == 0) { - swprintf(dest, 255, L"mixed color"); - } else if (value == 1) { - swprintf(dest, 255, L"separate specular"); - } else { - swprintf(dest, 255, L"%06x", value); - } - break; - - case CMD_FMT_LIGHTTYPE: - { - static constexpr std::array lightComputations = { - "diffuse", - "diffuse + spec", - "pow(diffuse)", - "unknown (diffuse?)", - }; - static constexpr std::array lightTypes = { - "directional", - "point", - "spot", - "unknown (directional?)", - }; - if ((value & ~0x0303) == 0) { - const int comp = (value & 0x0003) >> 0; - const int type = (value & 0x0300) >> 8; - swprintf(dest, 255, L"type: %S, comp: %S", lightTypes[type], lightComputations[comp]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_CULL: - if (value == 0) { - swprintf(dest, 255, L"front (CW)"); - } else if (value == 1) { - swprintf(dest, 255, L"back (CCW)"); - } else { - swprintf(dest, 255, L"%06x", value); - } - break; - - case CMD_FMT_PATCHPRIMITIVE: - { - const char *patchPrims[] = { - "triangles", - "lines", - "points", - }; - if (value < (u32)ARRAY_SIZE(patchPrims)) { - swprintf(dest, 255, L"%S", patchPrims[value]); - } else { - swprintf(dest, 255, L"%06x", value); - } - } - break; - - case CMD_FMT_FLAG: - if ((value & ~1) == 0) { - swprintf(dest, 255, L"%d", value); - } else { - swprintf(dest, 255, L"%06x", value); - } - break; - - default: - swprintf(dest, 255, L"BAD FORMAT %06x", value); - } - - // TODO: Turn row grey or some such? - if (!enabled) { - wcscat(dest, L" (disabled)"); - } -} - -void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) { +void CtrlStateValues::GetColumnText(wchar_t *dest, size_t destSize, int row, int col) { if (row < 0 || row >= rowCount_) { return; } @@ -889,12 +326,12 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) { break; case STATEVALUES_COL_NAME: - wcscpy(dest, rows_[row].title); + ConvertUTF8ToWString(dest, destSize, rows_[row].title); break; case STATEVALUES_COL_VALUE: { - if (gpuDebug == NULL) { + if (!gpuDebug) { wcscpy(dest, L"N/A"); break; } @@ -905,8 +342,9 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) { const u32 value = state.cmdmem[info.cmd] & 0xFFFFFF; const u32 otherValue = state.cmdmem[info.otherCmd] & 0xFFFFFF; const u32 otherValue2 = state.cmdmem[info.otherCmd2] & 0xFFFFFF; - - FormatStateRow(dest, info, value, enabled, otherValue, otherValue2); + char temp[256]; + FormatStateRow(gpuDebug, temp, sizeof(temp), info.fmt, value, enabled, otherValue, otherValue2); + ConvertUTF8ToWString(dest, destSize, temp); break; } } @@ -941,25 +379,25 @@ void CtrlStateValues::OnDoubleClick(int row, int column) { default: { - wchar_t title[1024]; + char title[1024]; const auto state = gpuDebug->GetGState(); u32 newValue = state.cmdmem[info.cmd] & 0x00FFFFFF; - swprintf(title, 1023, L"New value for %s", info.title); + snprintf(title, sizeof(title), "New value for %.*s", (int)info.title.size(), info.title.data()); if (PromptStateValue(info, GetHandle(), title, newValue)) { newValue |= state.cmdmem[info.cmd] & 0xFF000000; SetCmdValue(newValue); if (info.otherCmd) { newValue = state.cmdmem[info.otherCmd] & 0x00FFFFFF; - swprintf(title, 1023, L"New value for %s (secondary)", info.title); + snprintf(title, sizeof(title), "New value for %.*s (secondary)", (int)info.title.size(), info.title.data()); if (PromptStateValue(info, GetHandle(), title, newValue)) { newValue |= state.cmdmem[info.otherCmd] & 0xFF000000; SetCmdValue(newValue); if (info.otherCmd2) { newValue = state.cmdmem[info.otherCmd2] & 0x00FFFFFF; - swprintf(title, 1023, L"New value for %s (tertiary)", info.title); + snprintf(title, sizeof(title), "New value for %.*s (tertiary)", (int)info.title.size(), info.title.data()); if (PromptStateValue(info, GetHandle(), title, newValue)) { newValue |= state.cmdmem[info.otherCmd2] & 0xFF000000; SetCmdValue(newValue); @@ -1020,7 +458,7 @@ void CtrlStateValues::OnRightClick(int row, int column, const POINT &point) { case ID_DISASM_COPYINSTRUCTIONHEX: { char temp[16]; snprintf(temp, sizeof(temp), "%08x", gstate.cmdmem[info.cmd] & 0x00FFFFFF); - W32Util::CopyTextToClipboard(GetHandle(), temp); + System_CopyStringToClipboard(temp); break; } @@ -1030,9 +468,9 @@ void CtrlStateValues::OnRightClick(int row, int column, const POINT &point) { const u32 otherValue = state.cmdmem[info.otherCmd] & 0xFFFFFF; const u32 otherValue2 = state.cmdmem[info.otherCmd2] & 0xFFFFFF; - wchar_t dest[512]; - FormatStateRow(dest, info, value, enabled, otherValue, otherValue2); - W32Util::CopyTextToClipboard(GetHandle(), dest); + char dest[512]; + FormatStateRow(gpuDebug, dest, sizeof(dest), info.fmt, value, enabled, otherValue, otherValue2); + System_CopyStringToClipboard(dest); break; } @@ -1149,19 +587,19 @@ BOOL TabStateValues::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { } TabStateFlags::TabStateFlags(HINSTANCE _hInstance, HWND _hParent) - : TabStateValues(stateFlagsRows, ARRAY_SIZE(stateFlagsRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { + : TabStateValues(g_stateFlagsRows, ARRAY_SIZE(g_stateFlagsRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { } TabStateLighting::TabStateLighting(HINSTANCE _hInstance, HWND _hParent) - : TabStateValues(stateLightingRows, ARRAY_SIZE(stateLightingRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { + : TabStateValues(g_stateLightingRows, ARRAY_SIZE(g_stateLightingRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { } TabStateSettings::TabStateSettings(HINSTANCE _hInstance, HWND _hParent) - : TabStateValues(stateSettingsRows, ARRAY_SIZE(stateSettingsRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { + : TabStateValues(g_stateSettingsRows, ARRAY_SIZE(g_stateSettingsRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { } TabStateTexture::TabStateTexture(HINSTANCE _hInstance, HWND _hParent) - : TabStateValues(stateTextureRows, ARRAY_SIZE(stateTextureRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { + : TabStateValues(g_stateTextureRows, ARRAY_SIZE(g_stateTextureRows), (LPCSTR)IDD_GEDBG_TAB_VALUES, _hInstance, _hParent) { } TabStateWatch::TabStateWatch(HINSTANCE _hInstance, HWND _hParent) diff --git a/Windows/GEDebugger/TabState.h b/Windows/GEDebugger/TabState.h index f525b02723..a813b1ff6c 100644 --- a/Windows/GEDebugger/TabState.h +++ b/Windows/GEDebugger/TabState.h @@ -36,7 +36,7 @@ protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) override { return false; } - void GetColumnText(wchar_t* dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override { return rowCount_; } void OnDoubleClick(int row, int column) override; void OnRightClick(int row, int column, const POINT& point) override; diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index 4304084a4d..8aa6f0c2aa 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -138,7 +138,7 @@ CtrlVertexList::~CtrlVertexList() { delete decoder; } -void CtrlVertexList::GetColumnText(wchar_t *dest, int row, int col) { +void CtrlVertexList::GetColumnText(wchar_t *dest, size_t destSize, int row, int col) { if (row < 0 || row >= rowCount_ ) { wcscpy(dest, L"Invalid"); return; @@ -146,7 +146,7 @@ void CtrlVertexList::GetColumnText(wchar_t *dest, int row, int col) { if (!indices.empty()) { if (row >= (int)indices.size()) { - swprintf(dest, 255, L"Invalid indice %d", row); + swprintf(dest, destSize, L"Invalid indice %d", row); return; } row = indices[row]; @@ -156,7 +156,7 @@ void CtrlVertexList::GetColumnText(wchar_t *dest, int row, int col) { FormatVertColRaw(dest, row, col); } else { if (row >= (int)vertices.size()) { - swprintf(dest, 255, L"Invalid vertex %d", row); + swprintf(dest, destSize, L"Invalid vertex %d", row); return; } @@ -461,7 +461,7 @@ bool CtrlMatrixList::GetValue(const GPUgstate &state, int row, int col, float &v return true; } -void CtrlMatrixList::GetColumnText(wchar_t *dest, int row, int col) { +void CtrlMatrixList::GetColumnText(wchar_t *dest, size_t destSize, int row, int col) { if (col == MATRIXLIST_COL_BREAKPOINT) { wcscpy(dest, L" "); return; diff --git a/Windows/GEDebugger/TabVertices.h b/Windows/GEDebugger/TabVertices.h index 4d7a04d660..9c12458c62 100644 --- a/Windows/GEDebugger/TabVertices.h +++ b/Windows/GEDebugger/TabVertices.h @@ -36,7 +36,7 @@ public: protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override { return false; } - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override; private: @@ -78,7 +78,7 @@ protected: bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT &returnValue) override { return false; } - void GetColumnText(wchar_t *dest, int row, int col) override; + void GetColumnText(wchar_t *dest, size_t destSize, int row, int col) override; int GetRowCount() override; void OnDoubleClick(int row, int column) override; void OnRightClick(int row, int column, const POINT &point) override; diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index 5aed03198a..d1d3da7330 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -352,7 +352,7 @@ int GenericListControl::HandleNotify(LPARAM lParam) { NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam; stringBuffer[0] = 0; - GetColumnText(stringBuffer,dispInfo->item.iItem,dispInfo->item.iSubItem); + GetColumnText(stringBuffer, ARRAY_SIZE(stringBuffer), dispInfo->item.iItem,dispInfo->item.iSubItem); if (stringBuffer[0] == 0) wcscat(stringBuffer,L"Invalid"); @@ -411,7 +411,7 @@ int GenericListControl::OnIncrementalSearch(int startRow, const wchar_t *str, bo for (int i = 0; i < size; ++i) { int r = (startRow + i) % size; stringBuffer[0] = 0; - GetColumnText(stringBuffer, r, c); + GetColumnText(stringBuffer, ARRAY_SIZE(stringBuffer), r, c); int difference = partial ? _wcsnicmp(str, stringBuffer, searchlen) : _wcsicmp(str, stringBuffer); if (difference == 0) return r; @@ -591,7 +591,7 @@ void GenericListControl::CopyRows(int start, int size) for (int c = 0; c < columnCount; ++c) { stringBuffer[0] = 0; - GetColumnText(stringBuffer, r, c); + GetColumnText(stringBuffer, ARRAY_SIZE(stringBuffer), r, c); data.append(stringBuffer); if (c < columnCount - 1) data.append(L"\t"); diff --git a/Windows/W32Util/Misc.h b/Windows/W32Util/Misc.h index cd20db75ea..e2c31ef813 100644 --- a/Windows/W32Util/Misc.h +++ b/Windows/W32Util/Misc.h @@ -77,7 +77,7 @@ protected: void SetItemState(int item, uint8_t state); virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) = 0; - virtual void GetColumnText(wchar_t* dest, int row, int col) = 0; + virtual void GetColumnText(wchar_t* dest, size_t destSize, int row, int col) = 0; virtual int GetRowCount() = 0; virtual void OnDoubleClick(int itemIndex, int column) { }; virtual void OnRightClick(int itemIndex, int column, const POINT& point) { }; @@ -102,8 +102,8 @@ private: WNDPROC oldProc; void *images_ = nullptr; const GenericListViewColumn* columns; + wchar_t stringBuffer[256]; // needs to survive slightly longer than the GetColumnText scope, so needs to be here. int columnCount; - wchar_t stringBuffer[256]; bool valid; bool sendInvalidRows; // Used for hacky workaround to fix a rare hang (see issue #5184) diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 95692d060d..786b267169 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -551,6 +551,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/Debugger/GECommandTable.cpp \ $(SRC)/GPU/Debugger/Playback.cpp \ $(SRC)/GPU/Debugger/Record.cpp \ + $(SRC)/GPU/Debugger/State.cpp \ $(SRC)/GPU/Debugger/Stepping.cpp \ $(SRC)/GPU/GLES/FramebufferManagerGLES.cpp \ $(SRC)/GPU/GLES/StencilBufferGLES.cpp \