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/Common/GPUDebugInterface.h b/GPU/Common/GPUDebugInterface.h index 39423d63ba..ad0c2057c8 100644 --- a/GPU/Common/GPUDebugInterface.h +++ b/GPU/Common/GPUDebugInterface.h @@ -200,6 +200,7 @@ class GPUDebugInterface { public: virtual ~GPUDebugInterface() {} virtual bool GetCurrentDisplayList(DisplayList &list) = 0; + virtual bool GetCurrentCommand(u32 *cmd) = 0; virtual std::vector ActiveDisplayLists() = 0; virtual void ResetListPC(int listID, u32 pc) = 0; virtual void ResetListStall(int listID, u32 stall) = 0; diff --git a/GPU/Debugger/State.cpp b/GPU/Debugger/State.cpp new file mode 100644 index 0000000000..7bb1ef2d28 --- /dev/null +++ b/GPU/Debugger/State.cpp @@ -0,0 +1,834 @@ +#include +#include "Common/Common.h" +#include "Common/StringUtils.h" +#include "GPU/Debugger/State.h" +#include "GPU/GPU.h" +#include "GPU/Common/GPUDebugInterface.h" +#include "GPU/GeDisasm.h" +#include "GPU/Common/VertexDecoderCommon.h" +#include "Core/System.h" + +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 }, +}; +const size_t g_stateFlagsRowsSize = ARRAY_SIZE(g_stateFlagsRows); + +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 }, +}; +const size_t g_stateLightingRowsSize = ARRAY_SIZE(g_stateLightingRows); + +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 }, + + { "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 }, +}; +const size_t g_stateTextureRowsSize = ARRAY_SIZE(g_stateTextureRows); + +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? + { "Patch division", GE_CMD_PATCHDIVISION, CMD_FMT_HEX }, + { "Patch primitive", GE_CMD_PATCHPRIMITIVE, CMD_FMT_PATCHPRIMITIVE }, + // TODO: Format? + { "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? + { "Imm vertex prim", GE_CMD_VAP, CMD_FMT_HEX }, +}; +const size_t g_stateSettingsRowsSize = ARRAY_SIZE(g_stateSettingsRows); + +// TODO: Commands not present in the above lists (some because they don't have meaningful values...): +// GE_CMD_PRIM, GE_CMD_BEZIER, GE_CMD_SPLINE, GE_CMD_BOUNDINGBOX, +// GE_CMD_JUMP, GE_CMD_BJUMP, GE_CMD_CALL, GE_CMD_RET, GE_CMD_END, GE_CMD_SIGNAL, GE_CMD_FINISH, +// GE_CMD_BONEMATRIXNUMBER, GE_CMD_BONEMATRIXDATA, GE_CMD_WORLDMATRIXNUMBER, GE_CMD_WORLDMATRIXDATA, +// GE_CMD_VIEWMATRIXNUMBER, GE_CMD_VIEWMATRIXDATA, GE_CMD_PROJMATRIXNUMBER, GE_CMD_PROJMATRIXDATA, +// GE_CMD_TGENMATRIXNUMBER, GE_CMD_TGENMATRIXDATA, +// GE_CMD_LOADCLUT, GE_CMD_TEXFLUSH, GE_CMD_TEXSYNC, +// GE_CMD_TRANSFERSTART, +// GE_CMD_UNKNOWN_* + +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)"); + } +} + +void FormatVertCol(char *dest, size_t destSize, const GPUDebugVertex &vert, int col) { + switch (col) { + case VERTEXLIST_COL_X: snprintf(dest, destSize, "%f", vert.x); break; + case VERTEXLIST_COL_Y: snprintf(dest, destSize, "%f", vert.y); break; + case VERTEXLIST_COL_Z: snprintf(dest, destSize, "%f", vert.z); break; + case VERTEXLIST_COL_U: snprintf(dest, destSize, "%f", vert.u); break; + case VERTEXLIST_COL_V: snprintf(dest, destSize, "%f", vert.v); break; + case VERTEXLIST_COL_COLOR: + snprintf(dest, destSize, "%02x%02x%02x%02x", vert.c[0], vert.c[1], vert.c[2], vert.c[3]); + break; + case VERTEXLIST_COL_NX: snprintf(dest, destSize, "%f", vert.nx); break; + case VERTEXLIST_COL_NY: snprintf(dest, destSize, "%f", vert.ny); break; + case VERTEXLIST_COL_NZ: snprintf(dest, destSize, "%f", vert.nz); break; + + default: + truncate_cpy(dest, destSize, "Invalid"); + break; + } +} + +static void FormatVertColRawType(char *dest, size_t destSize, const void *data, int type, int offset); +static void FormatVertColRawColor(char *dest, size_t destSize, const void *data, int type); + +void FormatVertColRaw(VertexDecoder *decoder, char *dest, size_t destSize, int row, int col) { + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) { + truncate_cpy(dest, destSize, "Invalid"); + return; + } + + // We could use the vertex decoder and reader, but those already do some minor adjustments. + // There's only a few values - let's just go after them directly. + const u8 *vert = Memory::GetPointer(gpuDebug->GetVertexAddress()) + row * decoder->size; + const u8 *pos = vert + decoder->posoff; + const u8 *tc = vert + decoder->tcoff; + const u8 *color = vert + decoder->coloff; + const u8 *norm = vert + decoder->nrmoff; + + switch (col) { + case VERTEXLIST_COL_X: + FormatVertColRawType(dest, destSize, pos, decoder->pos, 0); + break; + case VERTEXLIST_COL_Y: + FormatVertColRawType(dest, destSize, pos, decoder->pos, 1); + break; + case VERTEXLIST_COL_Z: + FormatVertColRawType(dest, destSize, pos, decoder->pos, 2); + break; + case VERTEXLIST_COL_U: + FormatVertColRawType(dest, destSize, tc, decoder->tc, 0); + break; + case VERTEXLIST_COL_V: + FormatVertColRawType(dest, destSize, tc, decoder->tc, 1); + break; + case VERTEXLIST_COL_COLOR: + FormatVertColRawColor(dest, destSize, color, decoder->col); + break; + + case VERTEXLIST_COL_NX: FormatVertColRawType(dest, destSize, norm, decoder->nrm, 0); break; + case VERTEXLIST_COL_NY: FormatVertColRawType(dest, destSize, norm, decoder->nrm, 1); break; + case VERTEXLIST_COL_NZ: FormatVertColRawType(dest, destSize, norm, decoder->nrm, 2); break; + + default: + truncate_cpy(dest, destSize, "Invalid"); + break; + } +} + +static void FormatVertColRawType(char *dest, size_t destSize, const void *data, int type, int offset) { + switch (type) { + case 0: + truncate_cpy(dest, destSize, "-"); + break; + + case 1: // 8-bit + snprintf(dest, destSize, "%02x", ((const u8 *)data)[offset]); + break; + + case 2: // 16-bit + snprintf(dest, destSize, "%04x", ((const u16_le *)data)[offset]); + break; + + case 3: // float + snprintf(dest, destSize, "%f", ((const float *)data)[offset]); + break; + + default: + truncate_cpy(dest, destSize, "Invalid"); + break; + } +} + +static void FormatVertColRawColor(char *dest, size_t destSize, const void *data, int type) { + switch (type) { + case GE_VTYPE_COL_NONE >> GE_VTYPE_COL_SHIFT: + truncate_cpy(dest, destSize, "-"); + break; + + case GE_VTYPE_COL_565 >> GE_VTYPE_COL_SHIFT: + case GE_VTYPE_COL_5551 >> GE_VTYPE_COL_SHIFT: + case GE_VTYPE_COL_4444 >> GE_VTYPE_COL_SHIFT: + snprintf(dest, destSize, "%04x", *(const u16_le *)data); + break; + + case GE_VTYPE_COL_8888 >> GE_VTYPE_COL_SHIFT: + snprintf(dest, destSize, "%08x", *(const u32_le *)data); + break; + + default: + truncate_cpy(dest, destSize, "Invalid"); + break; + } +} diff --git a/GPU/Debugger/State.h b/GPU/Debugger/State.h new file mode 100644 index 0000000000..7b9b396ea7 --- /dev/null +++ b/GPU/Debugger/State.h @@ -0,0 +1,90 @@ +#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, +}; + +enum VertexListCols { + VERTEXLIST_COL_X, + VERTEXLIST_COL_Y, + VERTEXLIST_COL_Z, + VERTEXLIST_COL_U, + VERTEXLIST_COL_V, + VERTEXLIST_COL_COLOR, + VERTEXLIST_COL_NX, + VERTEXLIST_COL_NY, + VERTEXLIST_COL_NZ, +}; + +class GPUDebugInterface; + + +struct TabStateRow { + std::string_view title; + uint8_t cmd; + CmdFormatType fmt; + uint8_t enableCmd; + uint8_t otherCmd; + uint8_t otherCmd2; +}; + +extern const TabStateRow g_stateFlagsRows[]; +extern const TabStateRow g_stateLightingRows[]; +extern const TabStateRow g_stateTextureRows[]; +extern const TabStateRow g_stateSettingsRows[]; +extern const size_t g_stateFlagsRowsSize; +extern const size_t g_stateLightingRowsSize; +extern const size_t g_stateTextureRowsSize; +extern const size_t g_stateSettingsRowsSize; + +struct GPUDebugVertex; +class VertexDecoder; + +void FormatStateRow(GPUDebugInterface *debug, char *dest, size_t destSize, CmdFormatType fmt, u32 value, bool enabled, u32 otherValue, u32 otherValue2); +void FormatVertCol(char *dest, size_t destSize, const GPUDebugVertex &vert, int col); +void FormatVertColRaw(VertexDecoder *decoder, char *dest, size_t destSize, int row, int col); 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..0b045fdbfa 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1581,6 +1581,16 @@ bool GPUCommon::GetCurrentDisplayList(DisplayList &list) { return true; } +bool GPUCommon::GetCurrentCommand(u32 *cmd) { + DisplayList list; + if (GetCurrentDisplayList(list)) { + *cmd = Memory::Read_U32(list.pc); + return true; + } else { + return false; + } +} + std::vector GPUCommon::ActiveDisplayLists() { std::vector result; @@ -1995,23 +2005,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/GPU/GPUCommon.h b/GPU/GPUCommon.h index 0d3aaf857e..c36f20c6af 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -328,7 +328,7 @@ public: // From GPUDebugInterface. bool GetCurrentDisplayList(DisplayList &list) override; bool GetCurrentSimpleVertices(int count, std::vector &vertices, std::vector &indices) override; - + bool GetCurrentCommand(u32 *cmd) override; FramebufferManagerCommon *GetFramebufferManagerCommon() override { return nullptr; } diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 98b7ed623f..efb3c18ec6 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 State", nullptr, &cfg_.geStateOpen); 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_.geStateOpen) { + DrawGeStateWindow(cfg_, gpuDebug); + } } void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, CoreState coreState) { @@ -1148,6 +1153,8 @@ void ImConfig::SyncConfig(IniFile *ini, bool save) { sync.Sync("audioChannelsOpen", &audioChannelsOpen, false); sync.Sync("texturesOpen", &texturesOpen, false); sync.Sync("debugStatsOpen", &debugStatsOpen, false); + sync.Sync("geDebuggerOpen", &geDebuggerOpen, false); + sync.Sync("geStateOpen", &geStateOpen, false); sync.SetSection(ini->GetOrCreateSection("Settings")); sync.Sync("displayLatched", &displayLatched, false); diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 08f4016be3..8661c8e9b5 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -80,6 +80,7 @@ struct ImConfig { bool audioChannelsOpen; bool debugStatsOpen; bool geDebuggerOpen; + bool geStateOpen; // HLE explorer settings // bool filterByUsed = true; diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index 4534dc650e..cc0e339890 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -2,11 +2,14 @@ #include "ext/imgui/imgui_impl_thin3d.h" #include "UI/ImDebugger/ImGe.h" #include "UI/ImDebugger/ImDebugger.h" +#include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureCacheCommon.h" #include "Core/HLE/sceDisplay.h" #include "Core/HW/Display.h" +#include "GPU/Debugger/State.h" +#include "GPU/GPUState.h" void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager) { ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); @@ -85,3 +88,54 @@ void DrawGeDebuggerWindow(ImConfig &cfg) { ImGui::End(); } + +// TODO: Separate window or merge into Ge debugger? +void DrawGeStateWindow(ImConfig &cfg, GPUDebugInterface *gpuDebug) { + ImGui::SetNextWindowSize(ImVec2(300, 500), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("GE State", &cfg.geStateOpen)) { + ImGui::End(); + return; + } + + if (ImGui::BeginTabBar("GeRegs", ImGuiTabBarFlags_None)) { + auto buildStateTab = [&](const char *tabName, const TabStateRow *rows, size_t numRows) { + if (ImGui::BeginTabItem(tabName)) { + if (ImGui::BeginTable("fpr", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("bkpt", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("State", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch); + + for (size_t i = 0; i < numRows; i++) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("-"); // breakpoint + ImGui::TableNextColumn(); + ImGui::TextUnformatted(rows[i].title.data(), rows[i].title.data() + rows[i].title.size()); + ImGui::TableNextColumn(); + char temp[256]; + auto &info = rows[i]; + + const bool enabled = info.enableCmd == 0 || (gstate.cmdmem[info.enableCmd] & 1) == 1; + const u32 value = gstate.cmdmem[info.cmd] & 0xFFFFFF; + const u32 otherValue = gstate.cmdmem[info.otherCmd] & 0xFFFFFF; + const u32 otherValue2 = gstate.cmdmem[info.otherCmd2] & 0xFFFFFF; + + FormatStateRow(gpuDebug, temp, sizeof(temp), info.fmt, value, enabled, otherValue, otherValue2); + ImGui::TextUnformatted(temp); + } + + ImGui::EndTable(); + } + ImGui::EndTabItem(); + } + }; + + buildStateTab("Flags", g_stateFlagsRows, g_stateFlagsRowsSize); + buildStateTab("Lighting", g_stateLightingRows, g_stateLightingRowsSize); + buildStateTab("Texture", g_stateTextureRows, g_stateTextureRowsSize); + buildStateTab("Settings", g_stateSettingsRows, g_stateSettingsRowsSize); + + ImGui::EndTabBar(); + } + ImGui::End(); +} diff --git a/UI/ImDebugger/ImGe.h b/UI/ImDebugger/ImGe.h index f75d1acf12..eed0a4a0dd 100644 --- a/UI/ImDebugger/ImGe.h +++ b/UI/ImDebugger/ImGe.h @@ -6,12 +6,14 @@ struct ImConfig; class FramebufferManagerCommon; class TextureCacheCommon; +class GPUDebugInterface; void DrawFramebuffersWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager); void DrawTexturesWindow(ImConfig &cfg, TextureCacheCommon *textureCache); void DrawDisplayWindow(ImConfig &cfg, FramebufferManagerCommon *framebufferManager); void DrawDebugStatsWindow(ImConfig &cfg); void DrawGeDebuggerWindow(ImConfig &cfg); +void DrawGeStateWindow(ImConfig &cfg, GPUDebugInterface *gpuDebug); 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..54176cc5da 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,238 +59,6 @@ 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; - CmdFormatType fmt; - u8 enableCmd; - u8 otherCmd; - u8 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 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 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 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 }, -}; - -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 }, - // TODO: Format? - { L"Patch division", GE_CMD_PATCHDIVISION, CMD_FMT_HEX }, - { L"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 }, - // TODO: Format? - { L"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...): -// GE_CMD_PRIM, GE_CMD_BEZIER, GE_CMD_SPLINE, GE_CMD_BOUNDINGBOX, -// GE_CMD_JUMP, GE_CMD_BJUMP, GE_CMD_CALL, GE_CMD_RET, GE_CMD_END, GE_CMD_SIGNAL, GE_CMD_FINISH, -// GE_CMD_BONEMATRIXNUMBER, GE_CMD_BONEMATRIXDATA, GE_CMD_WORLDMATRIXNUMBER, GE_CMD_WORLDMATRIXDATA, -// GE_CMD_VIEWMATRIXNUMBER, GE_CMD_VIEWMATRIXDATA, GE_CMD_PROJMATRIXNUMBER, GE_CMD_PROJMATRIXDATA, -// GE_CMD_TGENMATRIXNUMBER, GE_CMD_TGENMATRIXDATA, -// GE_CMD_LOADCLUT, GE_CMD_TEXFLUSH, GE_CMD_TEXSYNC, -// GE_CMD_TRANSFERSTART, -// GE_CMD_UNKNOWN_* - static std::vector watchList; static void ToggleWatchList(const TabStateRow &info) { @@ -320,7 +90,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 +101,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 +114,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 +124,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 +135,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 +151,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 +188,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 +267,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 +277,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; } @@ -1099,9 +346,9 @@ void CtrlStateValues::PromptBreakpointCond(const TabStateRow &info) { } -TabStateValues::TabStateValues(const TabStateRow *rows, int rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent) +TabStateValues::TabStateValues(const TabStateRow *rows, size_t rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent) : Dialog(dialogID, _hInstance, _hParent) { - values = new CtrlStateValues(rows, rowCount, GetDlgItem(m_hDlg, IDC_GEDBG_VALUES)); + values = new CtrlStateValues(rows, (int)rowCount, GetDlgItem(m_hDlg, IDC_GEDBG_VALUES)); } TabStateValues::~TabStateValues() { @@ -1149,19 +396,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, g_stateFlagsRowsSize, (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, g_stateLightingRowsSize, (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, g_stateSettingsRowsSize, (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, g_stateTextureRowsSize, (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..61428ac450 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; @@ -55,7 +55,7 @@ private: class TabStateValues : public Dialog { public: - TabStateValues(const TabStateRow *rows, int rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent); + TabStateValues(const TabStateRow *rows, size_t rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent); ~TabStateValues(); void Update() override { diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index 4304084a4d..b693752059 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -32,6 +32,7 @@ #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Debugger/Breakpoints.h" #include "GPU/Debugger/Stepping.h" +#include "GPU/Debugger/State.h" static const GenericListViewColumn vertexListCols[] = { { L"X", 0.1f }, @@ -50,18 +51,6 @@ GenericListViewDef vertexListDef = { vertexListCols, ARRAY_SIZE(vertexListCols), NULL, false }; -enum VertexListCols { - VERTEXLIST_COL_X, - VERTEXLIST_COL_Y, - VERTEXLIST_COL_Z, - VERTEXLIST_COL_U, - VERTEXLIST_COL_V, - VERTEXLIST_COL_COLOR, - VERTEXLIST_COL_NX, - VERTEXLIST_COL_NY, - VERTEXLIST_COL_NZ, -}; - static const GenericListViewColumn matrixListCols[] = { { L"", 0.03f }, { L"Name", 0.21f }, @@ -138,7 +127,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,133 +135,24 @@ 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 index %d", row); return; } row = indices[row]; } + char temp[256]; if (raw_) { - FormatVertColRaw(dest, row, col); + FormatVertColRaw(decoder, temp, sizeof(temp), 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; } - FormatVertCol(dest, vertices[row], col); - } -} - -void CtrlVertexList::FormatVertCol(wchar_t *dest, const GPUDebugVertex &vert, int col) { - switch (col) { - case VERTEXLIST_COL_X: swprintf(dest, 255, L"%f", vert.x); break; - case VERTEXLIST_COL_Y: swprintf(dest, 255, L"%f", vert.y); break; - case VERTEXLIST_COL_Z: swprintf(dest, 255, L"%f", vert.z); break; - case VERTEXLIST_COL_U: swprintf(dest, 255, L"%f", vert.u); break; - case VERTEXLIST_COL_V: swprintf(dest, 255, L"%f", vert.v); break; - case VERTEXLIST_COL_COLOR: - swprintf(dest, 255, L"%02x%02x%02x%02x", vert.c[0], vert.c[1], vert.c[2], vert.c[3]); - break; - case VERTEXLIST_COL_NX: swprintf(dest, 255, L"%f", vert.nx); break; - case VERTEXLIST_COL_NY: swprintf(dest, 255, L"%f", vert.ny); break; - case VERTEXLIST_COL_NZ: swprintf(dest, 255, L"%f", vert.nz); break; - - default: - wcscpy(dest, L"Invalid"); - break; - } -} - -void CtrlVertexList::FormatVertColRaw(wchar_t *dest, int row, int col) { - auto memLock = Memory::Lock(); - if (!PSP_IsInited()) { - wcscpy(dest, L"Invalid"); - return; - } - - // We could use the vertex decoder and reader, but those already do some minor adjustments. - // There's only a few values - let's just go after them directly. - const u8 *vert = Memory::GetPointer(gpuDebug->GetVertexAddress()) + row * decoder->size; - const u8 *pos = vert + decoder->posoff; - const u8 *tc = vert + decoder->tcoff; - const u8 *color = vert + decoder->coloff; - const u8 *norm = vert + decoder->nrmoff; - - switch (col) { - case VERTEXLIST_COL_X: - FormatVertColRawType(dest, pos, decoder->pos, 0); - break; - case VERTEXLIST_COL_Y: - FormatVertColRawType(dest, pos, decoder->pos, 1); - break; - case VERTEXLIST_COL_Z: - FormatVertColRawType(dest, pos, decoder->pos, 2); - break; - case VERTEXLIST_COL_U: - FormatVertColRawType(dest, tc, decoder->tc, 0); - break; - case VERTEXLIST_COL_V: - FormatVertColRawType(dest, tc, decoder->tc, 1); - break; - case VERTEXLIST_COL_COLOR: - FormatVertColRawColor(dest, color, decoder->col); - break; - - case VERTEXLIST_COL_NX: FormatVertColRawType(dest, norm, decoder->nrm, 0); break; - case VERTEXLIST_COL_NY: FormatVertColRawType(dest, norm, decoder->nrm, 1); break; - case VERTEXLIST_COL_NZ: FormatVertColRawType(dest, norm, decoder->nrm, 2); break; - - default: - wcscpy(dest, L"Invalid"); - break; - } -} - -void CtrlVertexList::FormatVertColRawType(wchar_t *dest, const void *data, int type, int offset) { - switch (type) { - case 0: - wcscpy(dest, L"-"); - break; - - case 1: // 8-bit - swprintf(dest, 255, L"%02x", ((const u8 *)data)[offset]); - break; - - case 2: // 16-bit - swprintf(dest, 255, L"%04x", ((const u16_le *)data)[offset]); - break; - - case 3: // float - swprintf(dest, 255, L"%f", ((const float *)data)[offset]); - break; - - default: - wcscpy(dest, L"Invalid"); - break; - } -} - -void CtrlVertexList::FormatVertColRawColor(wchar_t *dest, const void *data, int type) { - switch (type) { - case GE_VTYPE_COL_NONE >> GE_VTYPE_COL_SHIFT: - wcscpy(dest, L"-"); - break; - - case GE_VTYPE_COL_565 >> GE_VTYPE_COL_SHIFT: - case GE_VTYPE_COL_5551 >> GE_VTYPE_COL_SHIFT: - case GE_VTYPE_COL_4444 >> GE_VTYPE_COL_SHIFT: - swprintf(dest, 255, L"%04x", *(const u16_le *)data); - break; - - case GE_VTYPE_COL_8888 >> GE_VTYPE_COL_SHIFT: - swprintf(dest, 255, L"%08x", *(const u32_le *)data); - break; - - default: - wcscpy(dest, L"Invalid"); - break; + FormatVertCol(temp, sizeof(temp), vertices[row], col); } + ConvertUTF8ToWString(dest, destSize, temp); } int CtrlVertexList::GetRowCount() { @@ -291,9 +171,8 @@ int CtrlVertexList::GetRowCount() { rowCount_ = state.prim & 0xFFFF; // Override if we're on a prim command. - DisplayList list; - if (gpuDebug->GetCurrentDisplayList(list)) { - u32 cmd = Memory::Read_U32(list.pc); + u32 cmd; + if (gpuDebug->GetCurrentCommand(&cmd)) { if ((cmd >> 24) == GE_CMD_PRIM || (cmd >> 24) == GE_CMD_BOUNDINGBOX) { rowCount_ = cmd & 0xFFFF; } else if ((cmd >> 24) == GE_CMD_BEZIER || (cmd >> 24) == GE_CMD_SPLINE) { @@ -302,7 +181,6 @@ int CtrlVertexList::GetRowCount() { rowCount_ = u * v; } } - if (!gpuDebug->GetCurrentSimpleVertices(rowCount_, vertices, indices)) { rowCount_ = 0; } @@ -461,7 +339,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..14feda5595 100644 --- a/Windows/GEDebugger/TabVertices.h +++ b/Windows/GEDebugger/TabVertices.h @@ -36,15 +36,10 @@ 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: - void FormatVertCol(wchar_t *dest, const GPUDebugVertex &vert, int col); - void FormatVertColRaw(wchar_t *dest, int row, int col); - void FormatVertColRawType(wchar_t *dest, const void *data, int type, int offset); - void FormatVertColRawColor(wchar_t *dest, const void *data, int type); - std::vector vertices; std::vector indices; int rowCount_; @@ -78,7 +73,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 \