From a1cb9210429080fa5422807ec2f1f2f33fe9a072 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 23 Jan 2023 15:04:37 -0600 Subject: [PATCH] v1 Dlist Viewer (#2387) --- soh/CMakeLists.txt | 2 + .../cosmetics/CosmeticsEditor.cpp | 8 +- soh/soh/Enhancements/debugger/debugger.cpp | 2 + soh/soh/Enhancements/debugger/dlViewer.cpp | 144 ++++++++++++++++++ soh/soh/Enhancements/debugger/dlViewer.h | 3 + soh/soh/GameMenuBar.cpp | 8 + 6 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 soh/soh/Enhancements/debugger/dlViewer.cpp create mode 100644 soh/soh/Enhancements/debugger/dlViewer.h diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 8f5d42f45..6069c5d0e 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -182,6 +182,7 @@ set(Header_Files__soh__Enhancements__sfx_editor source_group("Header Files\\soh\\Enhancements\\sfx-editor" FILES ${Header_Files__soh__Enhancements__sfx_editor}) set(Header_Files__soh__Enhancements__debugger + "soh/Enhancements/debugger/dlViewer.h" "soh/Enhancements/debugger/actorViewer.h" "soh/Enhancements/debugger/colViewer.h" "soh/Enhancements/debugger/debugger.h" @@ -505,6 +506,7 @@ set(Source_Files__soh__Enhancements__sfx_editor source_group("Source Files\\soh\\Enhancements\\sfx-editor" FILES ${Source_Files__soh__Enhancements__sfx_editor}) set(Source_Files__soh__Enhancements__debugger + "soh/Enhancements/debugger/dlViewer.cpp" "soh/Enhancements/debugger/actorViewer.cpp" "soh/Enhancements/debugger/colViewer.cpp" "soh/Enhancements/debugger/debugger.cpp" diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index e89442d8f..933fc420c 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -133,11 +133,11 @@ typedef struct { directly to gDPSetPrimColor/gDPSetEnvColor in code. If you find one, try changing the arguments and see if that's what you are looking for. If this fails, and you aren't able to find any colors within the source of the actor/whatever you will now need to investigate the DLists - that are being rendered. The easiest way to do this is to check out the branch https://github.com/garrettjoecox/oot/tree/dlist-viewer - and use the DList viewer. An alternative to this is to dig through the source of the DLists after you have built the zeldaret/oot repository, - but this will be much more manual, and I can't provide instructions for it. + that are being rendered. The easiest way to do this is to use the experimental Display List Viewer in the developer tools options. An + alternative to this is to dig through the source of the DLists after you have built the zeldaret/oot repository, but this will be much more + manual, and I can't provide instructions for it. - Assuming you have checked out the dlist-viewer branch, you need to find the name of the DList to inspect. In the same areas you were looking + Assuming you are planning on using the Display List Viewer, you need to find the name of the DList to inspect. In the same areas you were looking for RGB values you now want to look for calls to gSPDisplayList, or variables that end in "DL". Once you have this name start typing parts of it into the dlist-viewer (in the developer dropdown) and select the desired dlist in the dropdown, there may be many. You will now see a list of commands associated with the DList you have selected. If you are lucky, there will be calls to gsDPSetPrimColor/gsDPSetEnvColor with diff --git a/soh/soh/Enhancements/debugger/debugger.cpp b/soh/soh/Enhancements/debugger/debugger.cpp index 9cb553e1c..9a157377f 100644 --- a/soh/soh/Enhancements/debugger/debugger.cpp +++ b/soh/soh/Enhancements/debugger/debugger.cpp @@ -2,6 +2,7 @@ #include "debugSaveEditor.h" #include "colViewer.h" #include "actorViewer.h" +#include "dlViewer.h" extern "C" { @@ -9,6 +10,7 @@ void Debug_Init(void) { InitSaveEditor(); InitColViewer(); InitActorViewer(); + InitDLViewer(); } void Debug_Draw(void) { diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp new file mode 100644 index 000000000..9be8f3c0c --- /dev/null +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -0,0 +1,144 @@ +#include "actorViewer.h" +#include "../../util.h" +#include "../../UIWidgets.hpp" +#include +#include "ResourceMgr.h" +#include "DisplayList.h" +#include "../../OTRGlobals.h" + +#include +#include +#include +#include +#include + +extern "C" { +#include +#include "z64math.h" +#include "variables.h" +#include "functions.h" +#include "macros.h" +extern PlayState* gPlayState; + +char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); +} + +char searchString[64] = ""; +int displayListsSearchResultsCount; +char** displayListsSearchResults; +char* activeDisplayList = nullptr; + +std::map cmdMap = { + { G_SETPRIMCOLOR, "gsDPSetPrimColor" }, + { G_SETENVCOLOR, "gsDPSetEnvColor" }, + { G_RDPPIPESYNC, "gsDPPipeSync" }, + { G_SETGRAYSCALE, "gsSPGrayscale" }, + { G_SETINTENSITY, "gsDPSetGrayscaleColor" }, + { G_LOADTLUT, "gsDPLoadTLUT" }, + { G_ENDDL, "gsSPEndDisplayList" }, +}; + +void DrawDLViewer(bool& open) { + if (!open) { + CVarSetInteger("gDLViewerEnabled", 0); + return; + } + + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Display List Viewer", &open, ImGuiWindowFlags_NoFocusOnAppearing)) { + ImGui::End(); + return; + } + + if (ImGui::InputText("Search Display Lists", searchString, ARRAY_COUNT(searchString))) { + displayListsSearchResults = ResourceMgr_ListFiles(("*" + std::string(searchString) + "*DL").c_str(), &displayListsSearchResultsCount); + } + + if (ImGui::BeginCombo("Active Display List", activeDisplayList)) { + for (int i = 0; i < displayListsSearchResultsCount; i++) { + if (ImGui::Selectable(displayListsSearchResults[i])) { + activeDisplayList = displayListsSearchResults[i]; + break; + } + } + ImGui::EndCombo(); + } + if (activeDisplayList != nullptr) { + auto res = std::static_pointer_cast(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(activeDisplayList)); + for (int i = 0; i < res->Instructions.size(); i++) { + std::string id = "##CMD" + std::to_string(i); + Gfx* gfx = (Gfx*)&res->Instructions[i]; + int cmd = gfx->words.w0 >> 24; + if (cmdMap.find(cmd) == cmdMap.end()) continue; + + std::string cmdLabel = cmdMap.at(cmd); + + ImGui::BeginGroup(); + ImGui::PushItemWidth(25.0f); + ImGui::Text("%d", i); + ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::PushItemWidth(150.0f); + if (ImGui::BeginCombo(("CMD" + id).c_str(), cmdLabel.c_str())) { + if (ImGui::Selectable("gsDPSetPrimColor") && cmd != G_SETPRIMCOLOR) { + *gfx = gsDPSetPrimColor(0, 0, 0, 0, 0, 255); + } + if (ImGui::Selectable("gsDPSetEnvColor")) { + *gfx = gsDPSetEnvColor(0, 0, 0, 255); + } + if (ImGui::Selectable("gsDPPipeSync")) { + *gfx = gsDPPipeSync(); + } + if (ImGui::Selectable("gsSPGrayscale")) { + *gfx = gsSPGrayscale(true); + } + if (ImGui::Selectable("gsDPSetGrayscaleColor")) { + *gfx = gsDPSetGrayscaleColor(0, 0, 0, 255); + } + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); + if (gfx->words.w0 >> 24 == G_SETPRIMCOLOR || gfx->words.w0 >> 24 == G_SETINTENSITY || gfx->words.w0 >> 24 == G_SETENVCOLOR) { + uint8_t r = _SHIFTR(gfx->words.w1, 24, 8); + uint8_t g = _SHIFTR(gfx->words.w1, 16, 8); + uint8_t b = _SHIFTR(gfx->words.w1, 8, 8); + uint8_t a = _SHIFTR(gfx->words.w1, 0, 8); + ImGui::PushItemWidth(30.0f); + ImGui::SameLine(); + if (ImGui::InputScalar(("r" + id).c_str(), ImGuiDataType_U8, &r)) { + gfx->words.w1 = _SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8); + } + ImGui::SameLine(); + if (ImGui::InputScalar(("g" + id).c_str(), ImGuiDataType_U8, &g)) { + gfx->words.w1 = _SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8); + } + ImGui::SameLine(); + if (ImGui::InputScalar(("b" + id).c_str(), ImGuiDataType_U8, &b)) { + gfx->words.w1 = _SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8); + } + ImGui::SameLine(); + if (ImGui::InputScalar(("a" + id).c_str(), ImGuiDataType_U8, &a)) { + gfx->words.w1 = _SHIFTL(r, 24, 8) | _SHIFTL(g, 16, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8); + } + ImGui::PopItemWidth(); + } + if (gfx->words.w0 >> 24 == G_RDPPIPESYNC) { + } + if (gfx->words.w0 >> 24 == G_SETGRAYSCALE) { + bool* state = (bool*)&gfx->words.w1; + ImGui::SameLine(); + if (ImGui::Checkbox(("state" + id).c_str(), state)) { + // + } + } + ImGui::EndGroup(); + } + } + ImGui::End(); +} + +void InitDLViewer() { + SohImGui::AddWindow("Developer Tools", "Display List Viewer", DrawDLViewer); + + displayListsSearchResults = ResourceMgr_ListFiles("*DL", &displayListsSearchResultsCount); +} diff --git a/soh/soh/Enhancements/debugger/dlViewer.h b/soh/soh/Enhancements/debugger/dlViewer.h new file mode 100644 index 000000000..6fd5fa5fa --- /dev/null +++ b/soh/soh/Enhancements/debugger/dlViewer.h @@ -0,0 +1,3 @@ +#pragma once + +void InitDLViewer(); diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 72d69916f..186fad2ea 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -1169,6 +1169,14 @@ namespace GameMenuBar { SohImGui::RequestCvarSaveOnNextTick(); SohImGui::EnableWindow("Actor Viewer", CVarGetInteger("gActorViewerEnabled", 0)); } + UIWidgets::Spacer(0); + if (ImGui::Button(GetWindowButtonText("Display List Viewer", CVarGetInteger("gDLViewerEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) + { + bool currentValue = CVarGetInteger("gDLViewerEnabled", 0); + CVarSetInteger("gDLViewerEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Display List Viewer", CVarGetInteger("gDLViewerEnabled", 0)); + } ImGui::PopStyleVar(3); ImGui::PopStyleColor(1);