mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-11 20:15:07 -05:00
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;
This commit is contained in:
parent
98af2c468c
commit
41bcad78a3
@ -701,11 +701,54 @@ extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path)
|
|||||||
return (Gfx*)&res->instructions[0];
|
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>(
|
auto res = std::static_pointer_cast<Ship::DisplayList>(
|
||||||
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
|
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)
|
extern "C" char* ResourceMgr_LoadArrayByName(const char* path)
|
||||||
|
@ -60,7 +60,8 @@ AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path);
|
|||||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
|
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
|
||||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
|
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
|
||||||
Gfx* ResourceMgr_LoadGfxByName(const char* path);
|
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);
|
char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path);
|
||||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||||
|
|
||||||
|
@ -2290,27 +2290,22 @@ Color_RGB8 sSandstormEnvColors[] = {
|
|||||||
{ 50, 40, 0 },
|
{ 50, 40, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
Gfx* gFieldSandstormDL_Custom = NULL;
|
u16 previousPatchedSandstormScreenSize = 0;
|
||||||
|
|
||||||
void Environment_PatchSandstorm(GlobalContext* globalCtx) {
|
void Environment_PatchSandstorm(GlobalContext* globalCtx) {
|
||||||
if (gFieldSandstormDL_Custom) return;
|
if (previousPatchedSandstormScreenSize == ABS(OTRGetRectDimensionFromLeftEdge(0)) + ABS(OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH))) {
|
||||||
|
return;
|
||||||
gFieldSandstormDL_Custom = ResourceMgr_PatchGfxByName(gFieldSandstormDL, -3);
|
|
||||||
|
|
||||||
const Gfx gFSPatchDL[2] = { gsSPEndDisplayList() };
|
|
||||||
bool patched = false;
|
|
||||||
Gfx* cmd = gFieldSandstormDL_Custom;
|
|
||||||
int id = 0;
|
|
||||||
|
|
||||||
while (!patched) {
|
|
||||||
const uint32_t opcode = cmd->words.w0 >> 24;
|
|
||||||
if (opcode == G_TEXRECT) {
|
|
||||||
gFieldSandstormDL_Custom[id] = gFSPatchDL[0];
|
|
||||||
patched = true;
|
|
||||||
}
|
|
||||||
++cmd;
|
|
||||||
id++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
|
||||||
|
previousPatchedSandstormScreenSize = ABS(OTRGetRectDimensionFromLeftEdge(0)) + ABS(OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) {
|
void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) {
|
||||||
@ -2435,10 +2430,7 @@ void Environment_DrawSandstorm(GlobalContext* globalCtx, u8 sandstormState) {
|
|||||||
0xFFF - ((u32)sp92 % 0x1000), 0x100, 0x40));
|
0xFFF - ((u32)sp92 % 0x1000), 0x100, 0x40));
|
||||||
gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE);
|
gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE);
|
||||||
|
|
||||||
gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL_Custom);
|
gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL);
|
||||||
gSPWideTextureRectangle(POLY_XLU_DISP++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0,
|
|
||||||
OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, 0x03C0, G_TX_RENDERTILE, 0, 0, 0x008C,
|
|
||||||
-0x008C);
|
|
||||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||||
|
|
||||||
D_8015FDB0 += (s32)sp98;
|
D_8015FDB0 += (s32)sp98;
|
||||||
|
Loading…
Reference in New Issue
Block a user