summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2022-10-12 16:20:13 -0500
committerGitHub <noreply@github.com>2022-10-12 17:20:13 -0400
commit41bcad78a3068e8ff8d0bbccb0f2d43967831f69 (patch)
treeecbc6cb5e0d86b091a0f6238e2e1e03e746b2770
parent98af2c468cc84a00d055f2fd850cf5a724f61294 (diff)
Support for patching DLists outside of OTR (#1696)
* Support for patching DLists outside of OTR, mostly for cosmetics and bug fixes * Store original dlist instruction for unpatching * Rename sandstorm patch variable * Use unordered map for originalGfx;
-rw-r--r--soh/soh/OTRGlobals.cpp49
-rw-r--r--soh/soh/OTRGlobals.h3
-rw-r--r--soh/src/code/z_kankyo.c34
3 files changed, 61 insertions, 25 deletions
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index b1e248e0e..d2986892a 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -701,11 +701,54 @@ extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path)
return (Gfx*)&res->instructions[0];
}
-extern "C" Gfx* ResourceMgr_PatchGfxByName(const char* path, int size) {
+typedef struct {
+ int index;
+ Gfx instruction;
+} GfxPatch;
+
+std::unordered_map<std::string, std::unordered_map<std::string, GfxPatch>> originalGfx;
+
+// Attention! This is primarily for cosmetics & bug fixes. For things like mods and model replacement you should be using OTRs
+// instead (When that is available). Index can be found using the commented out section below.
+extern "C" void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction) {
auto res = std::static_pointer_cast<Ship::DisplayList>(
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
- res->instructions.resize(res->instructions.size() + size);
- return (Gfx*)&res->instructions[0];
+
+ // Leaving this here for people attempting to find the correct Dlist index to patch
+ /*if (strcmp("__OTR__objects/object_gi_longsword/gGiBiggoronSwordDL", path) == 0) {
+ for (int i = 0; i < res->instructions.size(); i++) {
+ Gfx* gfx = (Gfx*)&res->instructions[i];
+ // Log all commands
+ // SPDLOG_INFO("index:{} command:{}", i, gfx->words.w0 >> 24);
+ // Log only SetPrimColors
+ if (gfx->words.w0 >> 24 == 250) {
+ SPDLOG_INFO("index:{} r:{} g:{} b:{} a:{}", i, _SHIFTR(gfx->words.w1, 24, 8), _SHIFTR(gfx->words.w1, 16, 8), _SHIFTR(gfx->words.w1, 8, 8), _SHIFTR(gfx->words.w1, 0, 8));
+ }
+ }
+ }*/
+
+ Gfx* gfx = (Gfx*)&res->instructions[index];
+
+ if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) {
+ originalGfx[path][patchName] = {
+ index,
+ *gfx
+ };
+ }
+
+ *gfx = instruction;
+}
+
+extern "C" void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName) {
+ if (originalGfx.contains(path) && originalGfx[path].contains(patchName)) {
+ auto res = std::static_pointer_cast<Ship::DisplayList>(
+ OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
+
+ Gfx* gfx = (Gfx*)&res->instructions[originalGfx[path][patchName].index];
+ *gfx = originalGfx[path][patchName].instruction;
+
+ originalGfx[path].erase(patchName);
+ }
}
extern "C" char* ResourceMgr_LoadArrayByName(const char* path)
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index 0d3f24d58..6f4715b8c 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -60,7 +60,8 @@ AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path);
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
Gfx* ResourceMgr_LoadGfxByName(const char* path);
-Gfx* ResourceMgr_PatchGfxByName(const char* path, int size);
+void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
+void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path);
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c
index 540e58a76..b1144d966 100644
--- a/soh/src/code/z_kankyo.c
+++ b/soh/src/code/z_kankyo.c
@@ -2290,27 +2290,22 @@ Color_RGB8 sSandstormEnvColors[] = {
{ 50, 40, 0 },
};
-Gfx* gFieldSandstormDL_Custom = NULL;
+u16 previousPatchedSandstormScreenSize = 0;
void Environment_PatchSandstorm(GlobalContext* globalCtx) {
- if (gFieldSandstormDL_Custom) return;
-
- gFieldSandstormDL_Custom = ResourceMgr_PatchGfxByName(gFieldSandstormDL, -3);
+ if (previousPatchedSandstormScreenSize == ABS(OTRGetRectDimensionFromLeftEdge(0)) + ABS(OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH))) {
+ return;
+ }
- const Gfx gFSPatchDL[2] = { gsSPEndDisplayList() };
- bool patched = false;
- Gfx* cmd = gFieldSandstormDL_Custom;
- int id = 0;
+ Gfx gfxPatchSandstormRect[] = {
+ gsSPWideTextureRectangle(OTRGetRectDimensionFromLeftEdge(0) << 2, 0,
+ OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, 0x03C0, G_TX_RENDERTILE, 0, 0, 0x008C, -0x008C),
+ };
+ ResourceMgr_PatchGfxByName(gFieldSandstormDL, "gfxPatchSandstormRect0", 48, gfxPatchSandstormRect[0]);
+ ResourceMgr_PatchGfxByName(gFieldSandstormDL, "gfxPatchSandstormRect1", 50, gfxPatchSandstormRect[1]);
+ ResourceMgr_PatchGfxByName(gFieldSandstormDL, "gfxPatchSandstormRect2", 52, gfxPatchSandstormRect[2]);
- while (!patched) {
- const uint32_t opcode = cmd->words.w0 >> 24;
- if (opcode == G_TEXRECT) {
- gFieldSandstormDL_Custom[id] = gFSPatchDL[0];
- patched = true;
- }
- ++cmd;
- id++;
- }
+ previousPatchedSandstormScreenSize = ABS(OTRGetRectDimensionFromLeftEdge(0)) + ABS(OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH));
}
void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) {
@@ -2435,10 +2430,7 @@ void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) {
0xFFF - ((u32)sp92 % 0x1000), 0x100, 0x40));
gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE);
- gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL_Custom);
- gSPWideTextureRectangle(POLY_XLU_DISP++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0,
- OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, 0x03C0, G_TX_RENDERTILE, 0, 0, 0x008C,
- -0x008C);
+ gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL);
CLOSE_DISPS(globalCtx->state.gfxCtx);
D_8015FDB0 += (s32)sp98;