v1 Dlist Viewer (#2387)

This commit is contained in:
Garrett Cox 2023-01-23 15:04:37 -06:00 committed by GitHub
parent e79bd2587d
commit a1cb921042
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 4 deletions

View File

@ -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"

View File

@ -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

View File

@ -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) {

View File

@ -0,0 +1,144 @@
#include "actorViewer.h"
#include "../../util.h"
#include "../../UIWidgets.hpp"
#include <ImGuiImpl.h>
#include "ResourceMgr.h"
#include "DisplayList.h"
#include "../../OTRGlobals.h"
#include <array>
#include <bit>
#include <map>
#include <string>
#include <libultraship/bridge.h>
extern "C" {
#include <z64.h>
#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<int, std::string> 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<Ship::DisplayList>(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);
}

View File

@ -0,0 +1,3 @@
#pragma once
void InitDLViewer();

View File

@ -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);