mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 05:13:39 -07:00
Fix unhandled opcode crash with authentic gfx patches (#5206)
This commit is contained in:
parent
084627b8af
commit
5bf1dc8285
1 changed files with 89 additions and 59 deletions
|
@ -18,7 +18,7 @@ typedef struct {
|
||||||
int startInstruction;
|
int startInstruction;
|
||||||
} DListPatchInfo;
|
} DListPatchInfo;
|
||||||
|
|
||||||
static DListPatchInfo freezardEffectDListPatchInfos[] = {
|
static DListPatchInfo freezardBodyDListPatchInfos[] = {
|
||||||
{ gFreezardIntactDL, 5 },
|
{ gFreezardIntactDL, 5 },
|
||||||
{ gFreezardTopRightHornChippedDL, 5 },
|
{ gFreezardTopRightHornChippedDL, 5 },
|
||||||
{ gFreezardHeadChippedDL, 5 },
|
{ gFreezardHeadChippedDL, 5 },
|
||||||
|
@ -67,76 +67,97 @@ static DListPatchInfo ironKnuckleDListPatchInfos[] = {
|
||||||
|
|
||||||
void PatchDekuStickTextureOverflow() {
|
void PatchDekuStickTextureOverflow() {
|
||||||
// Custom texture for holding Deku Stick that accounts for overflow texture reading
|
// Custom texture for holding Deku Stick that accounts for overflow texture reading
|
||||||
Gfx gDekuStickOverflowTexFix = gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b, 1, gDekuStickOverflowTex);
|
Gfx dekuSticTexkWithOverflowFixGfx = gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b, 1, gDekuStickOverflowTex);
|
||||||
|
|
||||||
// Gfx instructions to fix authentic vanilla bug where the Deku Stick texture is read as the wrong size
|
// Gfx instructions to fix authentic vanilla bug where the Deku Stick texture is read as the wrong size
|
||||||
Gfx gDekuStickTexFix[] = {
|
Gfx dekuStickTexWithSizeFixGfx[] = {
|
||||||
gsDPLoadTextureBlock(gDekuStickTex, G_IM_FMT_I, G_IM_SIZ_8b, 8, 8, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
gsDPLoadTextureBlock(gDekuStickTex, G_IM_FMT_I, G_IM_SIZ_8b, 8, 8, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
||||||
G_TX_NOMIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD)
|
G_TX_NOMIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD),
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* dlist = gLinkChildLinkDekuStickDL;
|
const char* dlist = gLinkChildLinkDekuStickDL;
|
||||||
int start = 5;
|
int start = 5;
|
||||||
|
|
||||||
|
// Patch using custom overflowed texture
|
||||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + i;
|
||||||
std::string unpatchName = "DekuStickFix" + std::to_string(instruction);
|
std::string unpatchName = "dekuStickWithSizeFix_" + std::to_string(instruction);
|
||||||
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string patchName = "DekuStickOverflow" + std::to_string(start);
|
std::string patchName = "dekuStickWithOverflowFix_" + std::to_string(start);
|
||||||
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), start, gDekuStickOverflowTexFix);
|
std::string patchName2 = "dekuStickWithOverflowFix_" + std::to_string(start + 1);
|
||||||
} else {
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), start, dekuSticTexkWithOverflowFixGfx);
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName2.c_str(), start + 1, gsSPNoOp());
|
||||||
|
} else { // Patch texture to use correct image size/fmt
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
std::string unpatchName = "DekuStickOverflow" + std::to_string(start);
|
std::string unpatchName = "dekuStickWithOverflowFix_" + std::to_string(start);
|
||||||
|
std::string unpatchName2 = "dekuStickWithOverflowFix_" + std::to_string(start + 1);
|
||||||
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
||||||
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName2.c_str());
|
||||||
for (size_t i = 0; i < 7; i++) {
|
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
for (size_t i = 0; i < 8; i++) {
|
||||||
std::string patchName = "DekuStickFix" + std::to_string(instruction);
|
int instruction = start + i;
|
||||||
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, gDekuStickTexFix[i]);
|
std::string patchName = "dekuStickWithSizeFix_" + std::to_string(instruction);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, gsSPNoOp());
|
||||||
|
} else {
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, dekuStickTexWithSizeFixGfx[i - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchFreezardTextureOverflow() {
|
void PatchFreezardTextureOverflow() {
|
||||||
// Custom texture for Freezard effect that accounts for overflow texture reading
|
// Custom texture for Freezard effect that accounts for overflow texture reading
|
||||||
Gfx gEffUnknown12OverflowTextFix = gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, gEffUnknown12OverflowTex);
|
Gfx freezardBodyTextureWithOverflowFixGfx =
|
||||||
|
gsDPSetTextureImage(G_IM_FMT_IA, G_IM_SIZ_16b, 1, gEffUnknown12OverflowTex);
|
||||||
|
|
||||||
// Gfx instructions to fix authentic vanilla bug where the Freezard effect texture is read as the wrong format
|
// Gfx instructions to fix authentic vanilla bug where the Freezard effect texture is read as the wrong format
|
||||||
Gfx gEffUnknown12TexFix[] = {
|
Gfx freezardBodyTextureWithFormatFixGfx[] = {
|
||||||
gsDPLoadTextureBlock(gEffUnknown12Tex, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR |
|
gsDPLoadTextureBlock(gEffUnknown12Tex, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
||||||
G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD)
|
G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& patchInfo : freezardEffectDListPatchInfos) {
|
bool fixTexturesOOB = CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0);
|
||||||
|
|
||||||
|
for (const auto& patchInfo : freezardBodyDListPatchInfos) {
|
||||||
const char* dlist = patchInfo.dlist;
|
const char* dlist = patchInfo.dlist;
|
||||||
int start = patchInfo.startInstruction;
|
int start = patchInfo.startInstruction;
|
||||||
|
|
||||||
char patchNameBuf[24];
|
|
||||||
|
|
||||||
// Patch using custom overflowed texture
|
// Patch using custom overflowed texture
|
||||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
if (!fixTexturesOOB) {
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + i;
|
||||||
std::string unpatchName = "gEffUnknown12Fix" + std::to_string(instruction);
|
std::string unpatchName = "freezardBodyTextureWithFormatFix_" + std::to_string(instruction);
|
||||||
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string patchName = "gEffUnknown12Overflow" + std::to_string(start);
|
std::string patchName = "freezardBodyTextureWithOverflowFix_" + std::to_string(start);
|
||||||
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), start, gEffUnknown12OverflowTextFix);
|
std::string patchName2 = "freezardBodyTextureWithOverflowFix_" + std::to_string(start + 1);
|
||||||
} else { // Patch texture to use correct image size
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), start, freezardBodyTextureWithOverflowFixGfx);
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName2.c_str(), start + 1, gsSPNoOp());
|
||||||
|
} else { // Patch texture to use correct image size/fmt
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
std::string unpatchName = "gEffUnknown12Overflow" + std::to_string(start);
|
std::string unpatchName = "freezardBodyTextureWithOverflowFix_" + std::to_string(start);
|
||||||
|
std::string unpatchName2 = "freezardBodyTextureWithOverflowFix_" + std::to_string(start + 1);
|
||||||
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
||||||
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName2.c_str());
|
||||||
|
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + i;
|
||||||
std::string patchName = "gEffUnknown12Fix" + std::to_string(instruction);
|
std::string patchName = "freezardBodyTextureWithFormatFix_" + std::to_string(instruction);
|
||||||
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, gEffUnknown12TexFix[i]);
|
|
||||||
|
if (i == 0) {
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, gsSPNoOp());
|
||||||
|
} else {
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction,
|
||||||
|
freezardBodyTextureWithFormatFixGfx[i - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,44 +165,53 @@ void PatchFreezardTextureOverflow() {
|
||||||
|
|
||||||
void PatchIronKnuckleTextureOverflow() {
|
void PatchIronKnuckleTextureOverflow() {
|
||||||
// Custom texture for Iron Knuckle that accounts for overflow texture reading
|
// Custom texture for Iron Knuckle that accounts for overflow texture reading
|
||||||
Gfx gIronKnuckleMetalOverflowTexFix = gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b, 1, gIronKnuckleMetalOverflowTex);
|
Gfx ironKnuckleFireTexWithOverflowFixGfx =
|
||||||
|
gsDPSetTextureImage(G_IM_FMT_I, G_IM_SIZ_8b, 1, gIronKnuckleMetalOverflowTex);
|
||||||
|
|
||||||
// Gfx instructions to fix authentic vanilla bug where the Iron Knuckle texture is read as the wrong format
|
// Gfx instructions to fix authentic vanilla bug where the Iron Knuckle texture is read as the wrong format
|
||||||
Gfx gIronKnuckleMetalTexFix[] = {
|
Gfx ironKnuckleFireTexWithFormatFixGfx[] = {
|
||||||
gsDPLoadTextureBlock(gIronKnuckleMetalTex, G_IM_FMT_I, G_IM_SIZ_4b, 32, 64, 0, G_TX_MIRROR | G_TX_WRAP,
|
gsDPLoadTextureBlock_4b(gIronKnuckleMetalTex, G_IM_FMT_I, 32, 64, 0, G_TX_MIRROR | G_TX_WRAP,
|
||||||
G_TX_MIRROR | G_TX_WRAP, 5, 6, G_TX_NOLOD, G_TX_NOLOD)
|
G_TX_MIRROR | G_TX_WRAP, 5, 6, G_TX_NOLOD, G_TX_NOLOD),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool fixTexturesOOB = CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0);
|
||||||
|
|
||||||
for (const auto& patchInfo : ironKnuckleDListPatchInfos) {
|
for (const auto& patchInfo : ironKnuckleDListPatchInfos) {
|
||||||
const char* dlist = patchInfo.dlist;
|
const char* dlist = patchInfo.dlist;
|
||||||
int start = patchInfo.startInstruction;
|
int start = patchInfo.startInstruction;
|
||||||
|
|
||||||
// OTRTODO: Patching to use the correct size format for Iron Knuckle causes a tile size failure
|
|
||||||
// Until this is solved, Iron Knuckle will be hardcoded to always display with the "authentic" texture fix
|
|
||||||
|
|
||||||
// Patch using custom overflowed texture
|
// Patch using custom overflowed texture
|
||||||
// if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
|
if (!fixTexturesOOB) {
|
||||||
// Unpatch the other texture fix
|
// Unpatch the other texture fix
|
||||||
for (size_t i = 0; i < 7; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
int instruction = start + (i == 0 ? 0 : i + 1);
|
int instruction = start + i;
|
||||||
std::string unpatchName = "MetalTexFix" + std::to_string(instruction);
|
std::string unpatchName = "ironKnuckleFireTexWithSizeFix_" + std::to_string(instruction);
|
||||||
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string patchName = "MetalTexOverflow" + std::to_string(start);
|
std::string patchName = "ironKnuckleFireTexWithOverflowFix_" + std::to_string(start);
|
||||||
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), start, gIronKnuckleMetalOverflowTexFix);
|
std::string patchName2 = "ironKnuckleFireTexWithOverflowFix_" + std::to_string(start + 1);
|
||||||
// } else { // Patch texture to use correct image size
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), start, ironKnuckleFireTexWithOverflowFixGfx);
|
||||||
// // Unpatch the other texture fix
|
ResourceMgr_PatchGfxByName(dlist, patchName2.c_str(), start + 1, ironKnuckleFireTexWithOverflowFixGfx);
|
||||||
// std::string unpatchName = "MetalTexOverflow" + std::to_string(start);
|
} else { // Patch texture to use correct image size/fmt
|
||||||
// ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
// Unpatch the other texture fix
|
||||||
|
std::string unpatchName = "ironKnuckleFireTexWithOverflowFix_" + std::to_string(start);
|
||||||
|
std::string unpatchName2 = "ironKnuckleFireTexWithOverflowFix_" + std::to_string(start + 1);
|
||||||
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName.c_str());
|
||||||
|
ResourceMgr_UnpatchGfxByName(dlist, unpatchName2.c_str());
|
||||||
|
|
||||||
// // Patch texture to use correct image size
|
for (size_t i = 0; i < 8; i++) {
|
||||||
// for (size_t i = 0; i < 7; i++) {
|
int instruction = start + i;
|
||||||
// int instruction = start + (i == 0 ? 0 : i + 1);
|
std::string patchName = "ironKnuckleFireTexWithSizeFix_" + std::to_string(instruction);
|
||||||
// std::string patchName = "MetalTexFix" + std::to_string(instruction);
|
|
||||||
// ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, gIronKnuckleMetalTexFix[i]);
|
if (i == 0) {
|
||||||
// }
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction, gsSPNoOp());
|
||||||
// }
|
} else {
|
||||||
|
ResourceMgr_PatchGfxByName(dlist, patchName.c_str(), instruction,
|
||||||
|
ironKnuckleFireTexWithFormatFixGfx[i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue