-
Notifications
You must be signed in to change notification settings - Fork 8
/
wwfcBugFix.cpp
86 lines (70 loc) · 2.21 KB
/
wwfcBugFix.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "import/mkw/net/net.hpp"
#include "import/mkw/system/raceConfig.hpp"
#include "wwfcPatch.hpp"
namespace wwfc::BugFix
{
#if RMC
u64 IsUltraShortcutCheckEnabled( //
u32 r3Discard, u32 r4Save
) asm("IsUltraShortcutCheckEnabled");
// Patch the Mario Kart Wii Ultra Shortcut bug
// Credit: MrBean35000vr, Chadderz
WWFC_DEFINE_PATCH = {
// Patch in RaceManagerPlayer::updateCheckpoint.
// This patch is implemented weirdly to be compatible with the existing
// Ultra UnCut code.
Patch::CallWithCTR(
WWFC_PATCH_LEVEL_BUGFIX | WWFC_PATCH_LEVEL_PARITY, //
RMCXD_PORT(0x80535120, 0x805305D8, 0x80534AA0, 0x80523178), //
ASM_LAMBDA(
// clang-format off
beq L_Equal;
mflr r28;
bl IsUltraShortcutCheckEnabled;
mtlr r28;
// Restore potentially clobbered registers
mulli r0, r4, 0x18;
add r5, r29, r0; // Restore r5
lhz r6, 0x4(r29); // Restore r6
cmpwi r3, 0;
beq L_NotEqual;
lbz r3, 0x1C(r29);
cmplwi r3, 1;
bgt L_Equal;
L_NotEqual:;
// Restore CTR
sub r12, r6, r4;
mtctr r12;
addi r5, r5, 0x18;
// Jump to 0x80535130
blr;
L_Equal:;
// Restore CTR
sub r12, r6, r4;
mtctr r12;
li r0, 1;
// Jump to 0x8053513C
mflr r12;
addi r12, r12, 0xC;
mtlr r12;
blr;
// clang-format on
)
)
};
u64 IsUltraShortcutCheckEnabled(u32 r3Discard, u32 r4Save)
{
bool enabled = false;
auto raceConfig = mkw::System::RaceConfig::Instance();
if (raceConfig->raceScenario().isOnlineVersusRace()) {
// Check if Worldwide or other vanilla match
auto netController = mkw::Net::NetController::Instance();
if (netController && netController->inVanillaMatch()) {
enabled = true;
}
}
// Return hack to save r4 from caller
return (u64(enabled ? 1 : 0) << 32) | r4Save;
}
#endif
} // namespace wwfc::BugFix