Skip to content

Commit

Permalink
- Fix Super Mario Sunshine system freeze.
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Mar 9, 2019
1 parent c3b9224 commit 028a9d7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cube/swiss/include/patcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ extern u8 GXSetViewportJitterPatch[];
extern u32 GXSetViewportJitterPatch_length;
extern u8 GXSetViewportPatch[];
extern u32 GXSetViewportPatch_length;
extern u8 GXTokenInterruptHandlerHook[];
extern u32 GXTokenInterruptHandlerHook_length;
extern u8 MTXFrustumHook[];
extern u32 MTXFrustumHook_length;
extern u8 MTXLightFrustumHook[];
Expand Down Expand Up @@ -124,6 +126,7 @@ enum patchIds {
GX_INITTEXOBJLODHOOK,
GX_SETPROJECTIONHOOK,
GX_SETSCISSORHOOK,
GX_TOKENINTERRUPTHANDLERHOOK,
MTX_FRUSTUMHOOK,
MTX_LIGHTFRUSTUMHOOK,
MTX_LIGHTPERSPECTIVEHOOK,
Expand Down
63 changes: 63 additions & 0 deletions cube/swiss/source/patcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ void *installPatch(int patchId) {
patchSize = GXSetProjectionHook_length; patchLocation = GXSetProjectionHook; break;
case GX_SETSCISSORHOOK:
patchSize = GXSetScissorHook_length; patchLocation = GXSetScissorHook; break;
case GX_TOKENINTERRUPTHANDLERHOOK:
patchSize = GXTokenInterruptHandlerHook_length; patchLocation = GXTokenInterruptHandlerHook; break;
case MTX_FRUSTUMHOOK:
patchSize = MTXFrustumHook_length; patchLocation = MTXFrustumHook; break;
case MTX_LIGHTFRUSTUMHOOK:
Expand Down Expand Up @@ -1610,6 +1612,13 @@ void Patch_VideoMode(u32 *data, u32 length, int dataType)
{ 549, 289, 38, 110, 7, 9, NULL, 0, "__GXInitGX F" }, // SN Systems ProDG
{ 590, 333, 34, 119, 28, 11, NULL, 0, "__GXInitGX G" }
};
FuncPattern GXTokenInterruptHandlerSigs[5] = {
{ 33, 11, 3, 4, 1, 2, NULL, 0, "GXTokenInterruptHandlerD A" },
{ 34, 12, 4, 4, 1, 3, NULL, 0, "GXTokenInterruptHandler A" },
{ 33, 11, 4, 4, 0, 4, NULL, 0, "GXTokenInterruptHandler B" }, // SN Systems ProDG
{ 36, 9, 5, 4, 0, 4, NULL, 0, "GXTokenInterruptHandler C" }, // SN Systems ProDG
{ 34, 13, 4, 4, 1, 3, NULL, 0, "GXTokenInterruptHandler D" }
};
FuncPattern GXAdjustForOverscanSigs[4] = {
{ 57, 6, 4, 0, 3, 11, GXAdjustForOverscanPatch, GXAdjustForOverscanPatch_length, "GXAdjustForOverscanD A" },
{ 72, 17, 15, 0, 3, 5, GXAdjustForOverscanPatch, GXAdjustForOverscanPatch_length, "GXAdjustForOverscan A" },
Expand Down Expand Up @@ -2231,6 +2240,31 @@ void Patch_VideoMode(u32 *data, u32 length, int dataType)
break;
}
}

for (j = 0; j < sizeof(GXTokenInterruptHandlerSigs) / sizeof(FuncPattern); j++) {
if (!GXTokenInterruptHandlerSigs[j].offsetFoundAt && compare_pattern(&fp, &GXTokenInterruptHandlerSigs[j])) {
switch (j) {
case 0:
if (findx_pattern(data, dataType, i + 13, length, &OSSetCurrentContextSig) &&
findx_pattern(data, dataType, i + 21, length, &OSSetCurrentContextSig))
GXTokenInterruptHandlerSigs[j].offsetFoundAt = i;
break;
case 1:
case 2:
case 4:
if (findx_pattern(data, dataType, i + 14, length, &OSSetCurrentContextSig) &&
findx_pattern(data, dataType, i + 22, length, &OSSetCurrentContextSig))
GXTokenInterruptHandlerSigs[j].offsetFoundAt = i;
break;
case 3:
if (findx_pattern(data, dataType, i + 16, length, &OSSetCurrentContextSig) &&
findx_pattern(data, dataType, i + 24, length, &OSSetCurrentContextSig))
GXTokenInterruptHandlerSigs[j].offsetFoundAt = i;
break;
}
break;
}
}
i += fp.Length - 1;
}

Expand Down Expand Up @@ -3205,6 +3239,35 @@ void Patch_VideoMode(u32 *data, u32 length, int dataType)
}
}

for (j = 0; j < sizeof(GXTokenInterruptHandlerSigs) / sizeof(FuncPattern); j++)
if (GXTokenInterruptHandlerSigs[j].offsetFoundAt) break;

if (j < sizeof(GXTokenInterruptHandlerSigs) / sizeof(FuncPattern) && (i = GXTokenInterruptHandlerSigs[j].offsetFoundAt)) {
u32 *GXTokenInterruptHandler = Calc_ProperAddress(data, dataType, i * sizeof(u32));
u32 *GXTokenInterruptHandlerHook;

if (GXTokenInterruptHandler) {
GXTokenInterruptHandlerHook = getPatchAddr(GX_TOKENINTERRUPTHANDLERHOOK);

switch (j) {
case 0:
data[i + 16] = 0x7D8903A6; // mtctr r12
data[i + 17] = branchAndLink(GXTokenInterruptHandlerHook, GXTokenInterruptHandler + 17);
break;
case 1:
case 4:
data[i + 17] = 0x7D8903A6; // mtctr r12
case 2:
data[i + 18] = branchAndLink(GXTokenInterruptHandlerHook, GXTokenInterruptHandler + 18);
break;
case 3:
data[i + 20] = branchAndLink(GXTokenInterruptHandlerHook, GXTokenInterruptHandler + 20);
break;
}
print_gecko("Found:[%s] @ %08X\n", GXTokenInterruptHandlerSigs[j].Name, GXTokenInterruptHandler);
}
}

if (swissSettings.gameVMode >= 1 && swissSettings.gameVMode <= 5) {
for (j = 0; j < sizeof(GXAdjustForOverscanSigs) / sizeof(FuncPattern); j++)
if (GXAdjustForOverscanSigs[j].offsetFoundAt) break;
Expand Down
22 changes: 22 additions & 0 deletions cube/swiss/source/patches/gx/GXTokenInterruptHandlerHook.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "../asm.h"
#define _LANGUAGE_ASSEMBLY
#include "../../../../reservedarea.h"

.globl GXTokenInterruptHandlerHook
GXTokenInterruptHandlerHook:
lis %r4, 0xCC00
li %r0, 0
1: stw %r0, 0x404E (%r4)
mftb %r5
2: mftb %r6
sub %r6, %r6, %r5
cmplwi %r6, 10
ble 2b
lwz %r0, 0x404E (%r4)
cmplwi %r0, 0
bne 1b
bctr

.globl GXTokenInterruptHandlerHook_length
GXTokenInterruptHandlerHook_length:
.long (GXTokenInterruptHandlerHook_length - GXTokenInterruptHandlerHook)

0 comments on commit 028a9d7

Please sign in to comment.