Skip to content

Commit 3cfb852

Browse files
committed
Fix heap corruptions in pre-SQ phase 2 cutscenes
The first fix is for bom_01 (Fahr Outpost), and the second fix is for mri_00 (The Great Tree) (This one may not actually cause a heap corruption, but changing it anyway just to be safe). Made several other adjustments to performRelPatches. Added all of the rel ids to seq_mapchange.h. Made checkIfInGame use the DMO enum from seq_mapchange.h.
1 parent e1efede commit 3cfb852

File tree

4 files changed

+126
-52
lines changed

4 files changed

+126
-52
lines changed

ttyd-tools/rel/include/commonfunctions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ bool checkButtonComboEveryFrame(uint32_t combo);
2525
bool checkButtonComboDemo(uint32_t combo);
2626
bool checkForSpecificSeq(ttyd::seqdrv::SeqIndex wantedSeq);
2727
bool checkIfInGame();
28-
gc::OSModule::OSModuleInfo *getCurrentRelModuleInfo();
28+
gc::OSModule::OSModuleInfo *getCurrentRelPtr();
2929
void *getBattleWorkPointer();
3030
void *getMarioBattlePointer();
3131
void *getPartnerBattlePointer();

ttyd-tools/rel/include/ttyd/seq_mapchange.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,54 @@
44

55
namespace ttyd::seq_mapchange {
66

7+
enum REL_ID : uint32_t
8+
{
9+
AAA = 1, // Mario's house
10+
AJI, // X-Naut Fortress
11+
BOM, // Fahr Outpost
12+
13+
#ifndef TTYD_US
14+
DIG,
15+
#endif
16+
17+
DMO, // Intro sequence
18+
DOU, // Pirate's Grotto
19+
EKI, // Riverside Station
20+
END, // Ending credits
21+
GON, // Hooktail Castle
22+
GOR, // Rogueport (excluding sewers)
23+
GRA, // Twilight Trail
24+
HEI, // Petal Meadows
25+
HOM, // Excess Express traveling cutscenes
26+
JIN, // Creepy Steeple
27+
JON, // Pit of 100 Trials
28+
KPA, // Bowser stages
29+
LAS, // Palace of Shadow
30+
MOO, // Moon
31+
MRI, // The Great Tree
32+
MUJ, // Keelhaul Key
33+
NOK, // Petalburg
34+
PIK, // Poshley Heights
35+
36+
#ifndef TTYD_US
37+
QIZ,
38+
#endif
39+
40+
RSH, // Excess Express
41+
SYS, // Chapter start screens/Game Over screen
42+
TIK, // Rogueport Sewers
43+
TOU, // Glitzville (excluding arena)
44+
TOU2, // Glitzville arena
45+
46+
#ifdef TTYD_EU
47+
TST,
48+
#endif
49+
50+
USU, // Twilight Town
51+
WIN, // Boggly Woods
52+
YUU, // Pianta Parlor minigames
53+
};
54+
755
extern "C" {
856

957
// _relUnLoad

ttyd-tools/rel/source/commonfunctions.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,16 @@ bool checkIfInGame()
7979
return false;
8080
}
8181

82-
gc::OSModule::OSModuleInfo *CurrentRelModuleInfo = getCurrentRelModuleInfo();
83-
if (!CurrentRelModuleInfo)
82+
gc::OSModule::OSModuleInfo *CurrentRelPtr = getCurrentRelPtr();
83+
if (!CurrentRelPtr)
8484
{
8585
return false;
8686
}
8787

88-
#ifdef TTYD_US
89-
const uint32_t DMO = 0x4;
90-
#elif defined TTYD_JP
91-
const uint32_t DMO = 0x5;
92-
#elif defined TTYD_EU
93-
const uint32_t DMO = 0x5;
94-
#endif
95-
96-
return CurrentRelModuleInfo->id != DMO;
88+
return CurrentRelPtr->id != ttyd::seq_mapchange::REL_ID::DMO;
9789
}
9890

99-
gc::OSModule::OSModuleInfo *getCurrentRelModuleInfo()
91+
gc::OSModule::OSModuleInfo *getCurrentRelPtr()
10092
{
10193
return *reinterpret_cast<gc::OSModule::OSModuleInfo **>(
10294
reinterpret_cast<uint32_t>(

ttyd-tools/rel/source/main.cpp

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -443,57 +443,91 @@ bool Mod::performRelPatches(gc::OSModule::OSModuleInfo *newModule, void *bss)
443443
return Result;
444444
}
445445

446-
// Make sure a REL file is currently loaded
447-
gc::OSModule::OSModuleInfo *CurrentRelModuleInfo = getCurrentRelModuleInfo();
448-
if (!CurrentRelModuleInfo)
449-
{
450-
return Result;
451-
}
452-
453446
#ifdef TTYD_US
454-
const uint32_t LAS = 0x10;
455-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_Offset = 0x36FBC;
456-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_Loop_Offset = 0x64;
457-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_WaitMS_Offset = 0x114;
447+
// BOM
448+
constexpr uint32_t minnnanokoe_evt_bom_Offset = 0xD2FC;
449+
constexpr uint32_t minnnanokoe_evt_bom_WaitMS_Offset = 0x674;
450+
451+
// LAS
452+
constexpr uint32_t last_evt_3_2_Offset = 0x36FBC;
453+
constexpr uint32_t last_evt_3_2_Loop_Offset = 0x64;
454+
constexpr uint32_t last_evt_3_2_WaitMS_Offset = 0x114;
455+
456+
// MRI
457+
constexpr uint32_t minnnanokoe_evt_mri_Offset = 0x2BE80;
458+
constexpr uint32_t minnnanokoe_evt_mri_WaitMS_Offset = 0x968;
458459
#elif defined TTYD_JP
459-
const uint32_t LAS = 0x11;
460-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_Offset = 0x36FC0;
461-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_Loop_Offset = 0x58;
462-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_WaitMS_Offset = 0xD4;
460+
// BOM
461+
constexpr uint32_t minnnanokoe_evt_bom_Offset = 0xD2C4;
462+
constexpr uint32_t minnnanokoe_evt_bom_WaitMS_Offset = 0x634;
463+
464+
// LAS
465+
constexpr uint32_t last_evt_3_2_Offset = 0x36FC0;
466+
constexpr uint32_t last_evt_3_2_Loop_Offset = 0x58;
467+
constexpr uint32_t last_evt_3_2_WaitMS_Offset = 0xD4;
468+
469+
// MRI
470+
constexpr uint32_t minnnanokoe_evt_mri_Offset = 0x2BA98;
471+
constexpr uint32_t minnnanokoe_evt_mri_WaitMS_Offset = 0x968;
463472
#elif defined TTYD_EU
464-
const uint32_t LAS = 0x11;
465-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_Offset = 0x36FBC;
466-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_Loop_Offset = 0x64;
467-
const uint32_t SQ_Cutscene_Spawn_Textboxes_Script_WaitMS_Offset = 0x114;
473+
// BOM
474+
constexpr uint32_t minnnanokoe_evt_bom_Offset = 0xD35C;
475+
constexpr uint32_t minnnanokoe_evt_bom_WaitMS_Offset = 0x634;
476+
477+
// LAS
478+
constexpr uint32_t last_evt_3_2_Offset = 0x36FBC;
479+
constexpr uint32_t last_evt_3_2_Loop_Offset = 0x64;
480+
constexpr uint32_t last_evt_3_2_WaitMS_Offset = 0x114;
481+
482+
// MRI
483+
constexpr uint32_t minnnanokoe_evt_mri_Offset = 0x2BE80;
484+
constexpr uint32_t minnnanokoe_evt_mri_WaitMS_Offset = 0x968;
468485
#endif
469486

470-
uint32_t CurrentRelModuleInfoRaw = reinterpret_cast<uint32_t>(CurrentRelModuleInfo);
471-
switch (CurrentRelModuleInfo->id)
487+
uint32_t CurrentRelPtrRaw = reinterpret_cast<uint32_t>(newModule);
488+
switch (newModule->id)
472489
{
473-
case LAS:
490+
case ttyd::seq_mapchange::REL_ID::BOM:
474491
{
475-
if (compareStringToNextMap("las_29"))
476-
{
477-
// Make changes to the function that spawns the textboxes, to prevent the standard heap from being corrupted
478-
// Change the loop count from 10 to 5
479-
*reinterpret_cast<uint32_t *>(
480-
CurrentRelModuleInfoRaw +
481-
SQ_Cutscene_Spawn_Textboxes_Script_Offset +
482-
SQ_Cutscene_Spawn_Textboxes_Script_Loop_Offset) = 5;
483-
484-
// Wait for 400ms instead of 200ms at the end of the loop
485-
*reinterpret_cast<uint32_t *>(
486-
CurrentRelModuleInfoRaw +
487-
SQ_Cutscene_Spawn_Textboxes_Script_Offset +
488-
SQ_Cutscene_Spawn_Textboxes_Script_WaitMS_Offset) = 400;
489-
}
490-
return Result;
492+
// Shadow Queen cutscene fix, just before 2nd fight
493+
// Make changes to the script that spawns the textboxes, to prevent the standard heap from being corrupted
494+
// Wait 400ms instead of 300ms at the end of the loop
495+
*reinterpret_cast<uint32_t *>(CurrentRelPtrRaw +
496+
minnnanokoe_evt_bom_Offset + minnnanokoe_evt_bom_WaitMS_Offset) = 400;
497+
498+
break;
499+
}
500+
case ttyd::seq_mapchange::REL_ID::LAS:
501+
{
502+
// Shadow Queen cutscene fix, just before 2nd fight
503+
// Make changes to the script that spawns the textboxes, to prevent the standard heap from being corrupted
504+
// Change the loop count from 10 to 5
505+
*reinterpret_cast<uint32_t *>(CurrentRelPtrRaw +
506+
last_evt_3_2_Offset + last_evt_3_2_Loop_Offset) = 5;
507+
508+
// Wait 400ms instead of 200ms at the end of the loop
509+
*reinterpret_cast<uint32_t *>(CurrentRelPtrRaw +
510+
last_evt_3_2_Offset + last_evt_3_2_WaitMS_Offset) = 400;
511+
512+
break;
513+
}
514+
case ttyd::seq_mapchange::REL_ID::MRI:
515+
{
516+
// Shadow Queen cutscene fix, just before 2nd fight
517+
// Make changes to the script that spawns the textboxes, to prevent the standard heap from being corrupted
518+
// Wait 400ms instead of 300ms at the end of the loop
519+
*reinterpret_cast<uint32_t *>(CurrentRelPtrRaw +
520+
minnnanokoe_evt_mri_Offset + minnnanokoe_evt_mri_WaitMS_Offset) = 400;
521+
522+
break;
491523
}
492524
default:
493525
{
494-
return Result;
526+
break;
495527
}
496528
}
529+
530+
return Result;
497531
}
498532

499533
void clearHeapCorruptionBuffer()

0 commit comments

Comments
 (0)