ImGeDebugger: Implement the new state viewer

This commit is contained in:
Henrik Rydgård 2024-12-10 17:21:30 +01:00
parent c756842b7b
commit d3789367a4
5 changed files with 399 additions and 204 deletions

View file

@ -189,7 +189,7 @@ static constexpr GECmdInfo geCmdInfo[] = {
{ GE_CMD_LAC3, "light3ambient", GECmdFormat::RGB, "Light ambient 3", CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 },
{ GE_CMD_LDC3, "light3diffuse", GECmdFormat::RGB, "Light diffuse 3", CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 },
{ GE_CMD_LSC3, "light3specular", GECmdFormat::RGB, "Light specular 3", CMD_FMT_HEX, GE_CMD_LIGHTENABLE3 },
{ GE_CMD_CULL, "cullccw", GECmdFormat::FLAG, "Cull mode", CMD_FMT_FLAG, CMD_FMT_CULL, GE_CMD_CULLFACEENABLE},
{ GE_CMD_CULL, "cullccw", GECmdFormat::FLAG, "Cull mode", CMD_FMT_CULL, GE_CMD_CULLFACEENABLE},
{ GE_CMD_FRAMEBUFPTR, "fbptr", GECmdFormat::LOW_ADDR_ONLY, "Framebuffer", CMD_FMT_PTRWIDTH, 0, GE_CMD_FRAMEBUFWIDTH},
{ GE_CMD_FRAMEBUFWIDTH, "fbstride", GECmdFormat::STRIDE, "Framebuffer stride" },
{ GE_CMD_ZBUFPTR, "zbptr", GECmdFormat::LOW_ADDR_ONLY, "Depth buffer", CMD_FMT_PTRWIDTH, 0, GE_CMD_ZBUFWIDTH},
@ -252,7 +252,7 @@ static constexpr GECmdInfo geCmdInfo[] = {
{ GE_CMD_MAXZ, "maxz", GECmdFormat::DATA16, "Max Z", CMD_FMT_HEX},
{ GE_CMD_COLORTEST, "ctestfunc", GECmdFormat::COLOR_TEST_FUNC, "Color test", CMD_FMT_COLORTEST, GE_CMD_COLORTESTENABLE, GE_CMD_COLORREF, GE_CMD_COLORTESTMASK},
{ GE_CMD_COLORREF, "ctestref", GECmdFormat::RGB, "Color test ref", CMD_FMT_HEX, },
{ GE_CMD_COLORTESTMASK, "ctestmask", GECmdFormat::RGB, "Color test mask", CMD_FMT_HEX},
{ GE_CMD_COLORTESTMASK, "ctestmask", GECmdFormat::RGB, "Color test mask", CMD_FMT_HEX, GE_CMD_COLORTESTENABLE},
{ GE_CMD_ALPHATEST, "atest", GECmdFormat::ALPHA_TEST, "Alpha test mask", CMD_FMT_ALPHATEST, GE_CMD_ALPHATESTENABLE},
{ GE_CMD_STENCILTEST, "stest", GECmdFormat::ALPHA_TEST, "Stencil test", CMD_FMT_STENCILTEST, GE_CMD_STENCILTESTENABLE},
{ GE_CMD_STENCILOP, "stencilop", GECmdFormat::STENCIL_OP, "Stencil op", CMD_FMT_STENCILOP, GE_CMD_STENCILTESTENABLE},

View file

@ -18,7 +18,6 @@
#pragma once
#include <cstdint>
#include <string_view>
#include "GPU/ge_constants.h"
@ -120,9 +119,9 @@ enum CmdFormatType {
struct GECmdInfo {
GECommand cmd;
std::string_view name; // scripting / expression name
const char *name; // scripting / expression name
GECmdFormat cmdFmt;
std::string_view uiName; // friendly name
const char *uiName; // friendly name
CmdFormatType fmt;
uint8_t enableCmd;
uint8_t otherCmd;

View file

@ -8,188 +8,6 @@
#include "GPU/Common/VertexDecoderCommon.h"
#include "Core/System.h"
const GECommand g_stateFlagsRows[] = {
GE_CMD_LIGHTINGENABLE,
GE_CMD_LIGHTENABLE0,
GE_CMD_LIGHTENABLE1,
GE_CMD_LIGHTENABLE2,
GE_CMD_LIGHTENABLE3,
GE_CMD_DEPTHCLAMPENABLE,
GE_CMD_CULLFACEENABLE,
GE_CMD_TEXTUREMAPENABLE,
GE_CMD_FOGENABLE,
GE_CMD_DITHERENABLE,
GE_CMD_ALPHABLENDENABLE,
GE_CMD_ALPHATESTENABLE,
GE_CMD_ZTESTENABLE,
GE_CMD_STENCILTESTENABLE,
GE_CMD_ANTIALIASENABLE,
GE_CMD_PATCHCULLENABLE,
GE_CMD_COLORTESTENABLE,
GE_CMD_LOGICOPENABLE,
GE_CMD_ZWRITEDISABLE,
};
const size_t g_stateFlagsRowsSize = ARRAY_SIZE(g_stateFlagsRows);
const GECommand g_stateLightingRows[] = {
GE_CMD_AMBIENTCOLOR,
GE_CMD_AMBIENTALPHA,
GE_CMD_MATERIALUPDATE,
GE_CMD_MATERIALEMISSIVE,
GE_CMD_MATERIALAMBIENT,
GE_CMD_MATERIALDIFFUSE,
GE_CMD_MATERIALALPHA,
GE_CMD_MATERIALSPECULAR,
GE_CMD_MATERIALSPECULARCOEF,
GE_CMD_REVERSENORMAL,
GE_CMD_SHADEMODE,
GE_CMD_LIGHTMODE,
GE_CMD_LIGHTTYPE0,
GE_CMD_LIGHTTYPE1,
GE_CMD_LIGHTTYPE2,
GE_CMD_LIGHTTYPE3,
GE_CMD_LX0,
GE_CMD_LX1,
GE_CMD_LX2,
GE_CMD_LX3,
GE_CMD_LDX0,
GE_CMD_LDX1,
GE_CMD_LDX2,
GE_CMD_LDX3,
GE_CMD_LKA0,
GE_CMD_LKA1,
GE_CMD_LKA2,
GE_CMD_LKA3,
GE_CMD_LKS0,
GE_CMD_LKS1,
GE_CMD_LKS2,
GE_CMD_LKS3,
GE_CMD_LKO0,
GE_CMD_LKO1,
GE_CMD_LKO2,
GE_CMD_LKO3,
GE_CMD_LAC0,
GE_CMD_LDC0,
GE_CMD_LSC0,
GE_CMD_LAC1,
GE_CMD_LDC1,
GE_CMD_LSC1,
GE_CMD_LAC2,
GE_CMD_LDC2,
GE_CMD_LSC2,
GE_CMD_LAC3,
GE_CMD_LDC3,
GE_CMD_LSC3,
};
const size_t g_stateLightingRowsSize = ARRAY_SIZE(g_stateLightingRows);
const GECommand g_stateTextureRows[] = {
GE_CMD_TEXADDR0,
GE_CMD_TEXSIZE0,
GE_CMD_TEXFORMAT,
GE_CMD_CLUTADDR,
GE_CMD_CLUTFORMAT,
GE_CMD_TEXSCALEU,
GE_CMD_TEXSCALEV,
GE_CMD_TEXOFFSETU,
GE_CMD_TEXOFFSETV,
GE_CMD_TEXMAPMODE,
GE_CMD_TEXSHADELS,
GE_CMD_TEXFUNC,
GE_CMD_TEXENVCOLOR,
GE_CMD_TEXMODE,
GE_CMD_TEXFILTER,
GE_CMD_TEXWRAP,
GE_CMD_TEXLEVEL,
GE_CMD_TEXLODSLOPE,
GE_CMD_TEXADDR1,
GE_CMD_TEXADDR2,
GE_CMD_TEXADDR3,
GE_CMD_TEXADDR4,
GE_CMD_TEXADDR5,
GE_CMD_TEXADDR6,
GE_CMD_TEXADDR7,
GE_CMD_TEXSIZE1,
GE_CMD_TEXSIZE2,
GE_CMD_TEXSIZE3,
GE_CMD_TEXSIZE4,
GE_CMD_TEXSIZE5,
GE_CMD_TEXSIZE6,
GE_CMD_TEXSIZE7,
};
const size_t g_stateTextureRowsSize = ARRAY_SIZE(g_stateTextureRows);
const GECommand g_stateSettingsRows[] = {
GE_CMD_FRAMEBUFPTR,
GE_CMD_FRAMEBUFPIXFORMAT,
GE_CMD_ZBUFPTR,
GE_CMD_VIEWPORTXSCALE,
GE_CMD_VIEWPORTXCENTER,
GE_CMD_SCISSOR1,
GE_CMD_REGION1,
GE_CMD_COLORTEST,
GE_CMD_ALPHATEST,
GE_CMD_CLEARMODE,
GE_CMD_STENCILTEST,
GE_CMD_STENCILOP,
GE_CMD_ZTEST,
GE_CMD_MASKRGB,
GE_CMD_MASKALPHA,
GE_CMD_TRANSFERSRC,
GE_CMD_TRANSFERSRCPOS,
GE_CMD_TRANSFERDST,
GE_CMD_TRANSFERDSTPOS,
GE_CMD_TRANSFERSIZE,
GE_CMD_VERTEXTYPE,
GE_CMD_OFFSETADDR,
GE_CMD_VADDR,
GE_CMD_IADDR,
GE_CMD_MINZ,
GE_CMD_MAXZ,
GE_CMD_OFFSETX,
GE_CMD_CULL,
GE_CMD_BLENDMODE,
GE_CMD_BLENDFIXEDA,
GE_CMD_BLENDFIXEDB,
GE_CMD_LOGICOP,
GE_CMD_FOG1,
GE_CMD_FOG2,
GE_CMD_FOGCOLOR,
GE_CMD_MORPHWEIGHT0,
GE_CMD_MORPHWEIGHT1,
GE_CMD_MORPHWEIGHT2,
GE_CMD_MORPHWEIGHT3,
GE_CMD_MORPHWEIGHT4,
GE_CMD_MORPHWEIGHT5,
GE_CMD_MORPHWEIGHT6,
GE_CMD_MORPHWEIGHT7,
GE_CMD_PATCHDIVISION,
GE_CMD_PATCHPRIMITIVE,
GE_CMD_PATCHFACING,
GE_CMD_DITH0,
GE_CMD_DITH1,
GE_CMD_DITH2,
GE_CMD_DITH3,
GE_CMD_VSCX,
GE_CMD_VSCZ,
GE_CMD_VTCS,
GE_CMD_VCV,
GE_CMD_VSCV,
GE_CMD_VFC,
GE_CMD_VAP,
};
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:

View file

@ -330,6 +330,181 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
ImGui::End();
}
struct StateItem {
bool header; GECommand cmd; const char *title; bool closedByDefault;
};
static const StateItem g_rasterState[] = {
{true, GE_CMD_NOP, "Framebuffer"},
{false, GE_CMD_FRAMEBUFPTR},
{false, GE_CMD_FRAMEBUFPIXFORMAT},
{false, GE_CMD_CLEARMODE},
{true, GE_CMD_ZTESTENABLE},
{false, GE_CMD_ZBUFPTR},
{false, GE_CMD_ZTEST},
{false, GE_CMD_ZWRITEDISABLE},
{true, GE_CMD_STENCILTESTENABLE},
{false, GE_CMD_STENCILTEST},
{false, GE_CMD_STENCILOP},
{true, GE_CMD_ALPHABLENDENABLE},
{false, GE_CMD_BLENDMODE},
{false, GE_CMD_BLENDFIXEDA},
{false, GE_CMD_BLENDFIXEDB},
{true, GE_CMD_ALPHATESTENABLE},
{false, GE_CMD_ALPHATEST},
{true, GE_CMD_COLORTESTENABLE},
{false, GE_CMD_COLORTEST},
{false, GE_CMD_COLORTESTMASK},
{true, GE_CMD_FOGENABLE},
{false, GE_CMD_FOGCOLOR},
{false, GE_CMD_FOG1},
{false, GE_CMD_FOG2},
{true, GE_CMD_CULLFACEENABLE},
{false, GE_CMD_CULL},
{true, GE_CMD_LOGICOPENABLE},
{false, GE_CMD_LOGICOP},
{true, GE_CMD_NOP, "Clipping/Clamping"},
{false, GE_CMD_MINZ},
{false, GE_CMD_MAXZ},
{false, GE_CMD_DEPTHCLAMPENABLE},
{true, GE_CMD_NOP, "Other raster state"},
{false, GE_CMD_MASKRGB},
{false, GE_CMD_MASKALPHA},
{false, GE_CMD_SCISSOR1},
{false, GE_CMD_REGION1},
{false, GE_CMD_OFFSETX},
{false, GE_CMD_DITH0},
{false, GE_CMD_DITH1},
{false, GE_CMD_DITH2},
{false, GE_CMD_DITH3},
};
static const StateItem g_textureState[] = {
{true, GE_CMD_TEXTUREMAPENABLE},
{false, GE_CMD_TEXADDR0},
{false, GE_CMD_TEXSIZE0},
{false, GE_CMD_TEXENVCOLOR},
{false, GE_CMD_TEXMAPMODE},
{false, GE_CMD_TEXSHADELS},
{false, GE_CMD_TEXFORMAT},
{false, GE_CMD_CLUTFORMAT},
{false, GE_CMD_TEXFILTER},
{false, GE_CMD_TEXWRAP},
{false, GE_CMD_TEXLEVEL},
{false, GE_CMD_TEXFUNC},
{false, GE_CMD_TEXLODSLOPE},
{false, GE_CMD_TEXSCALEU},
{false, GE_CMD_TEXSCALEV},
{false, GE_CMD_TEXOFFSETU},
{false, GE_CMD_TEXOFFSETV},
{true, GE_CMD_NOP, "Additional mips", true},
{false, GE_CMD_TEXADDR1},
{false, GE_CMD_TEXADDR2},
{false, GE_CMD_TEXADDR3},
{false, GE_CMD_TEXADDR4},
{false, GE_CMD_TEXADDR5},
{false, GE_CMD_TEXADDR6},
{false, GE_CMD_TEXADDR7},
{false, GE_CMD_TEXSIZE1},
{false, GE_CMD_TEXSIZE2},
{false, GE_CMD_TEXSIZE3},
{false, GE_CMD_TEXSIZE4},
{false, GE_CMD_TEXSIZE5},
{false, GE_CMD_TEXSIZE6},
{false, GE_CMD_TEXSIZE7},
};
static const StateItem g_lightingState[] = {
{false, GE_CMD_AMBIENTCOLOR},
{false, GE_CMD_AMBIENTALPHA},
{false, GE_CMD_MATERIALUPDATE},
{false, GE_CMD_MATERIALEMISSIVE},
{false, GE_CMD_MATERIALAMBIENT},
{false, GE_CMD_MATERIALDIFFUSE},
{false, GE_CMD_MATERIALALPHA},
{false, GE_CMD_MATERIALSPECULAR},
{false, GE_CMD_MATERIALSPECULARCOEF},
{false, GE_CMD_REVERSENORMAL},
{false, GE_CMD_SHADEMODE},
{false, GE_CMD_LIGHTMODE},
{false, GE_CMD_LIGHTTYPE0},
{false, GE_CMD_LIGHTTYPE1},
{false, GE_CMD_LIGHTTYPE2},
{false, GE_CMD_LIGHTTYPE3},
{false, GE_CMD_LX0},
{false, GE_CMD_LX1},
{false, GE_CMD_LX2},
{false, GE_CMD_LX3},
{false, GE_CMD_LDX0},
{false, GE_CMD_LDX1},
{false, GE_CMD_LDX2},
{false, GE_CMD_LDX3},
{false, GE_CMD_LKA0},
{false, GE_CMD_LKA1},
{false, GE_CMD_LKA2},
{false, GE_CMD_LKA3},
{false, GE_CMD_LKS0},
{false, GE_CMD_LKS1},
{false, GE_CMD_LKS2},
{false, GE_CMD_LKS3},
{false, GE_CMD_LKO0},
{false, GE_CMD_LKO1},
{false, GE_CMD_LKO2},
{false, GE_CMD_LKO3},
{false, GE_CMD_LAC0},
{false, GE_CMD_LDC0},
{false, GE_CMD_LSC0},
{false, GE_CMD_LAC1},
{false, GE_CMD_LDC1},
{false, GE_CMD_LSC1},
{false, GE_CMD_LAC2},
{false, GE_CMD_LDC2},
{false, GE_CMD_LSC2},
{false, GE_CMD_LAC3},
{false, GE_CMD_LDC3},
{false, GE_CMD_LSC3},
};
static const StateItem g_vertexState[] = {
{true, GE_CMD_NOP, "Vertex type and transform"},
{false, GE_CMD_VERTEXTYPE},
{false, GE_CMD_VADDR},
{false, GE_CMD_IADDR},
{false, GE_CMD_OFFSETADDR},
{false, GE_CMD_VIEWPORTXSCALE},
{false, GE_CMD_VIEWPORTXCENTER},
{false, GE_CMD_MORPHWEIGHT0},
{false, GE_CMD_MORPHWEIGHT1},
{false, GE_CMD_MORPHWEIGHT2},
{false, GE_CMD_MORPHWEIGHT3},
{false, GE_CMD_MORPHWEIGHT4},
{false, GE_CMD_MORPHWEIGHT5},
{false, GE_CMD_MORPHWEIGHT6},
{false, GE_CMD_MORPHWEIGHT7},
{false, GE_CMD_TEXSCALEU},
{false, GE_CMD_TEXSCALEV},
{false, GE_CMD_TEXOFFSETU},
{false, GE_CMD_TEXOFFSETV},
{true, GE_CMD_NOP, "Tessellation"},
{false, GE_CMD_PATCHPRIMITIVE},
{false, GE_CMD_PATCHDIVISION},
{false, GE_CMD_PATCHCULLENABLE},
{false, GE_CMD_PATCHFACING},
};
// TODO: Separate window or merge into Ge debugger?
void DrawGeStateWindow(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
ImGui::SetNextWindowSize(ImVec2(300, 500), ImGuiCond_FirstUseEver);
@ -338,26 +513,43 @@ void DrawGeStateWindow(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
return;
}
if (ImGui::BeginTabBar("GeRegs", ImGuiTabBarFlags_None)) {
auto buildStateTab = [&](const char *tabName, const GECommand *rows, size_t numRows) {
auto buildStateTab = [&](const char *tabName, const StateItem *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);
ImGui::TableSetupColumn("bkpt", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
bool anySection = false;
bool sectionOpen = false;
for (size_t i = 0; i < numRows; i++) {
const GECmdInfo &info = GECmdInfoByCmd(rows[i]);
const GECmdInfo &info = GECmdInfoByCmd(rows[i].cmd);
if (rows[i].header) {
anySection = true;
if (sectionOpen) {
ImGui::TreePop();
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
sectionOpen = ImGui::TreeNodeEx(rows[i].cmd ? info.uiName : rows[i].title, rows[i].closedByDefault ? 0 : ImGuiTreeNodeFlags_DefaultOpen);
ImGui::TableNextColumn();
} else {
if (!sectionOpen && anySection) {
continue;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
}
const bool enabled = info.enableCmd == 0 || (gstate.cmdmem[info.enableCmd] & 1) == 1;
if (!enabled)
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 128));
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("-"); // breakpoint
ImGui::TableNextColumn();
ImGui::TextUnformatted(info.uiName.data(), info.uiName.data() + info.uiName.size());
ImGui::TableNextColumn();
if (!rows[i].header) {
ImGui::TextUnformatted(info.uiName);
ImGui::TableNextColumn();
}
char temp[256];
const u32 value = gstate.cmdmem[info.cmd] & 0xFFFFFF;
@ -369,6 +561,9 @@ void DrawGeStateWindow(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
if (!enabled)
ImGui::PopStyleColor();
}
if (sectionOpen) {
ImGui::TreePop();
}
ImGui::EndTable();
}
@ -376,10 +571,10 @@ void DrawGeStateWindow(ImConfig &cfg, GPUDebugInterface *gpuDebug) {
}
};
buildStateTab("Flags", g_stateFlagsRows, g_stateFlagsRowsSize);
buildStateTab("Lighting", g_stateLightingRows, g_stateLightingRowsSize);
buildStateTab("Texture", g_stateTextureRows, g_stateTextureRowsSize);
buildStateTab("Settings", g_stateSettingsRows, g_stateSettingsRowsSize);
buildStateTab("Raster", g_rasterState, ARRAY_SIZE(g_rasterState));
buildStateTab("Texture", g_textureState, ARRAY_SIZE(g_textureState));
buildStateTab("Lighting", g_lightingState, ARRAY_SIZE(g_lightingState));
buildStateTab("Transform/Tess", g_vertexState, ARRAY_SIZE(g_vertexState));
// Do a vertex tab (maybe later a separate window)
if (ImGui::BeginTabItem("Vertices")) {

View file

@ -32,6 +32,7 @@
#include "Windows/W32Util/ContextMenu.h"
#include "GPU/GPUState.h"
#include "GPU/GeDisasm.h"
#include "GPU/Debugger/GECommandTable.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "GPU/Debugger/Breakpoints.h"
#include "GPU/Debugger/Stepping.h"
@ -61,6 +62,188 @@ enum StateValuesCols {
static std::vector<GECommand> watchList;
const GECommand g_stateFlagsRows[] = {
GE_CMD_LIGHTINGENABLE,
GE_CMD_LIGHTENABLE0,
GE_CMD_LIGHTENABLE1,
GE_CMD_LIGHTENABLE2,
GE_CMD_LIGHTENABLE3,
GE_CMD_DEPTHCLAMPENABLE,
GE_CMD_CULLFACEENABLE,
GE_CMD_TEXTUREMAPENABLE,
GE_CMD_FOGENABLE,
GE_CMD_DITHERENABLE,
GE_CMD_ALPHABLENDENABLE,
GE_CMD_ALPHATESTENABLE,
GE_CMD_ZTESTENABLE,
GE_CMD_STENCILTESTENABLE,
GE_CMD_ANTIALIASENABLE,
GE_CMD_PATCHCULLENABLE,
GE_CMD_COLORTESTENABLE,
GE_CMD_LOGICOPENABLE,
GE_CMD_ZWRITEDISABLE,
};
const size_t g_stateFlagsRowsSize = ARRAY_SIZE(g_stateFlagsRows);
const GECommand g_stateLightingRows[] = {
GE_CMD_AMBIENTCOLOR,
GE_CMD_AMBIENTALPHA,
GE_CMD_MATERIALUPDATE,
GE_CMD_MATERIALEMISSIVE,
GE_CMD_MATERIALAMBIENT,
GE_CMD_MATERIALDIFFUSE,
GE_CMD_MATERIALALPHA,
GE_CMD_MATERIALSPECULAR,
GE_CMD_MATERIALSPECULARCOEF,
GE_CMD_REVERSENORMAL,
GE_CMD_SHADEMODE,
GE_CMD_LIGHTMODE,
GE_CMD_LIGHTTYPE0,
GE_CMD_LIGHTTYPE1,
GE_CMD_LIGHTTYPE2,
GE_CMD_LIGHTTYPE3,
GE_CMD_LX0,
GE_CMD_LX1,
GE_CMD_LX2,
GE_CMD_LX3,
GE_CMD_LDX0,
GE_CMD_LDX1,
GE_CMD_LDX2,
GE_CMD_LDX3,
GE_CMD_LKA0,
GE_CMD_LKA1,
GE_CMD_LKA2,
GE_CMD_LKA3,
GE_CMD_LKS0,
GE_CMD_LKS1,
GE_CMD_LKS2,
GE_CMD_LKS3,
GE_CMD_LKO0,
GE_CMD_LKO1,
GE_CMD_LKO2,
GE_CMD_LKO3,
GE_CMD_LAC0,
GE_CMD_LDC0,
GE_CMD_LSC0,
GE_CMD_LAC1,
GE_CMD_LDC1,
GE_CMD_LSC1,
GE_CMD_LAC2,
GE_CMD_LDC2,
GE_CMD_LSC2,
GE_CMD_LAC3,
GE_CMD_LDC3,
GE_CMD_LSC3,
};
const size_t g_stateLightingRowsSize = ARRAY_SIZE(g_stateLightingRows);
const GECommand g_stateTextureRows[] = {
GE_CMD_TEXADDR0,
GE_CMD_TEXSIZE0,
GE_CMD_TEXFORMAT,
GE_CMD_CLUTADDR,
GE_CMD_CLUTFORMAT,
GE_CMD_TEXSCALEU,
GE_CMD_TEXSCALEV,
GE_CMD_TEXOFFSETU,
GE_CMD_TEXOFFSETV,
GE_CMD_TEXMAPMODE,
GE_CMD_TEXSHADELS,
GE_CMD_TEXFUNC,
GE_CMD_TEXENVCOLOR,
GE_CMD_TEXMODE,
GE_CMD_TEXFILTER,
GE_CMD_TEXWRAP,
GE_CMD_TEXLEVEL,
GE_CMD_TEXLODSLOPE,
GE_CMD_TEXADDR1,
GE_CMD_TEXADDR2,
GE_CMD_TEXADDR3,
GE_CMD_TEXADDR4,
GE_CMD_TEXADDR5,
GE_CMD_TEXADDR6,
GE_CMD_TEXADDR7,
GE_CMD_TEXSIZE1,
GE_CMD_TEXSIZE2,
GE_CMD_TEXSIZE3,
GE_CMD_TEXSIZE4,
GE_CMD_TEXSIZE5,
GE_CMD_TEXSIZE6,
GE_CMD_TEXSIZE7,
};
const size_t g_stateTextureRowsSize = ARRAY_SIZE(g_stateTextureRows);
const GECommand g_stateSettingsRows[] = {
GE_CMD_FRAMEBUFPTR,
GE_CMD_FRAMEBUFPIXFORMAT,
GE_CMD_ZBUFPTR,
GE_CMD_VIEWPORTXSCALE,
GE_CMD_VIEWPORTXCENTER,
GE_CMD_SCISSOR1,
GE_CMD_REGION1,
GE_CMD_COLORTEST,
GE_CMD_ALPHATEST,
GE_CMD_CLEARMODE,
GE_CMD_STENCILTEST,
GE_CMD_STENCILOP,
GE_CMD_ZTEST,
GE_CMD_MASKRGB,
GE_CMD_MASKALPHA,
GE_CMD_TRANSFERSRC,
GE_CMD_TRANSFERSRCPOS,
GE_CMD_TRANSFERDST,
GE_CMD_TRANSFERDSTPOS,
GE_CMD_TRANSFERSIZE,
GE_CMD_VERTEXTYPE,
GE_CMD_OFFSETADDR,
GE_CMD_VADDR,
GE_CMD_IADDR,
GE_CMD_MINZ,
GE_CMD_MAXZ,
GE_CMD_OFFSETX,
GE_CMD_CULL,
GE_CMD_BLENDMODE,
GE_CMD_BLENDFIXEDA,
GE_CMD_BLENDFIXEDB,
GE_CMD_LOGICOP,
GE_CMD_FOG1,
GE_CMD_FOG2,
GE_CMD_FOGCOLOR,
GE_CMD_MORPHWEIGHT0,
GE_CMD_MORPHWEIGHT1,
GE_CMD_MORPHWEIGHT2,
GE_CMD_MORPHWEIGHT3,
GE_CMD_MORPHWEIGHT4,
GE_CMD_MORPHWEIGHT5,
GE_CMD_MORPHWEIGHT6,
GE_CMD_MORPHWEIGHT7,
GE_CMD_PATCHDIVISION,
GE_CMD_PATCHPRIMITIVE,
GE_CMD_PATCHFACING,
GE_CMD_DITH0,
GE_CMD_DITH1,
GE_CMD_DITH2,
GE_CMD_DITH3,
GE_CMD_VSCX,
GE_CMD_VSCZ,
GE_CMD_VTCS,
GE_CMD_VCV,
GE_CMD_VSCV,
GE_CMD_VFC,
GE_CMD_VAP,
};
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_*
static void ToggleWatchList(const GECommand cmd) {
for (size_t i = 0; i < watchList.size(); ++i) {
if (watchList[i] == cmd) {
@ -175,21 +358,21 @@ void CtrlStateValues::OnDoubleClick(int row, int column) {
const auto state = gpuDebug->GetGState();
u32 newValue = state.cmdmem[info.cmd] & 0x00FFFFFF;
snprintf(title, sizeof(title), "New value for %.*s", (int)info.uiName.size(), info.uiName.data());
snprintf(title, sizeof(title), "New value for %s", info.uiName);
if (PromptStateValue(info, GetHandle(), title, newValue)) {
newValue |= state.cmdmem[info.cmd] & 0xFF000000;
SetCmdValue(newValue);
if (info.otherCmd) {
newValue = state.cmdmem[info.otherCmd] & 0x00FFFFFF;
snprintf(title, sizeof(title), "New value for %.*s (secondary)", (int)info.uiName.size(), info.uiName.data());
snprintf(title, sizeof(title), "New value for %s (secondary)", info.uiName);
if (PromptStateValue(info, GetHandle(), title, newValue)) {
newValue |= state.cmdmem[info.otherCmd] & 0xFF000000;
SetCmdValue(newValue);
if (info.otherCmd2) {
newValue = state.cmdmem[info.otherCmd2] & 0x00FFFFFF;
snprintf(title, sizeof(title), "New value for %.*s (tertiary)", (int)info.uiName.size(), info.uiName.data());
snprintf(title, sizeof(title), "New value for %s (tertiary)", info.uiName);
if (PromptStateValue(info, GetHandle(), title, newValue)) {
newValue |= state.cmdmem[info.otherCmd2] & 0xFF000000;
SetCmdValue(newValue);