Skip to content

Commit 50a65fd

Browse files
Upgraded all fixes to use transactional patterns and HookEach
1 parent 2239348 commit 50a65fd

File tree

1 file changed

+177
-83
lines changed

1 file changed

+177
-83
lines changed

source/SilentPatchYK2.cpp

Lines changed: 177 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define _WIN32_WINNT 0x0601
66

77
#include <windows.h>
8+
#include "Utils/HookEach.hpp"
89
#include "Utils/MemoryMgr.h"
910
#include "Utils/Trampoline.h"
1011
#include "Utils/Patterns.h"
@@ -27,22 +28,36 @@ namespace ForcedMinigameFPS
2728
}
2829
}
2930

30-
static void (*orgSetMinigameFPSCap)(int cap);
31-
3231
template<bool force>
33-
static void SetMinigameFPSCap_ForcedFPS( int cap )
32+
struct MinigameFPSCap
3433
{
35-
orgSetMinigameFPSCap( cap );
36-
if constexpr ( force )
34+
template<std::size_t Index>
35+
static inline void (*orgSetMinigameFPSCap)(int cap);
36+
37+
static void ToggleFPSCap()
3738
{
38-
userFPSCap_ForMinigame = 0;
39+
if constexpr (force)
40+
{
41+
userFPSCap_ForMinigame = 0;
42+
}
43+
else
44+
{
45+
userFPSCap_ForMinigame = userFPSCap;
46+
}
47+
minigameFPSForced = force;
3948
}
40-
else
49+
50+
template<std::size_t Index>
51+
static void SetMinigameFPSCap_ForcedFPS( int cap )
4152
{
42-
userFPSCap_ForMinigame = userFPSCap;
53+
orgSetMinigameFPSCap<Index>( cap );
54+
ToggleFPSCap();
4355
}
44-
minigameFPSForced = force;
45-
}
56+
57+
HOOK_EACH_INIT_CTR(M2, 0, orgSetMinigameFPSCap, SetMinigameFPSCap_ForcedFPS);
58+
HOOK_EACH_INIT_CTR(VF5, 1, orgSetMinigameFPSCap, SetMinigameFPSCap_ForcedFPS);
59+
HOOK_EACH_INIT_CTR(Karaoke, 2, orgSetMinigameFPSCap, SetMinigameFPSCap_ForcedFPS);
60+
};
4661
};
4762

4863

@@ -51,118 +66,197 @@ void OnInitializeHook()
5166
std::unique_ptr<ScopedUnprotect::Unprotect> Protect = ScopedUnprotect::UnprotectSectionOrFullModule( GetModuleHandle( nullptr ), ".text" );
5267

5368
using namespace Memory;
54-
using namespace hook;
69+
using namespace hook::txn;
5570

5671

5772
// Make frame limiter busy loop so it's more accurate
73+
try
5874
{
5975
auto oneUsCompare = get_pattern( "48 2B C8 48 81 F9 E8 03 00 00", 10 );
6076
Patch<uint8_t>( oneUsCompare, 0xEB ); // jl -> jmp
6177
}
78+
TXN_CATCH();
6279

6380

6481
// Uncap minigames which did not need to be capped
82+
83+
// Mahjong
84+
try
6585
{
66-
void* noppedFpsCalls[] = {
67-
// Mahjong
68-
get_pattern( "8D 48 3C E8 ? ? ? ? 33 C9", 3 ),
69-
get_pattern( "E8 ? ? ? ? 90 49 8B CE 4C 8D 5C 24 ? 49 8B 5B 30" ),
70-
71-
// Oicho Kabu
72-
get_pattern( "B9 ? ? ? ? E8 ? ? ? ? 33 C0 48 89 83 00 07 00 00", 5 ),
73-
get_pattern( "E8 ? ? ? ? 90 89 2D" ),
74-
75-
// Cee-lo/chinchiro
76-
get_pattern( "E8 ? ? ? ? 90 48 8B 8B ? ? ? ? 48 85 C9 74 16" ),
77-
get_pattern( "B9 ? ? ? ? E8 ? ? ? ? 90 48 8D 4C 24 48", 5 ),
78-
79-
// Tougijyo (Colliseum) menu
80-
get_pattern( "8D 4B 3C E8 ? ? ? ? 48 8D 05", 3 ),
81-
get_pattern( "33 C9 E8 ? ? ? ? 90 33 D2", 2 ),
82-
83-
// Batting center
84-
get_pattern( "8D 4D 3C E8 ? ? ? ? 49 8B 46 28", 3 ),
85-
get_pattern( "33 C9 E8 ? ? ? ? 48 8B 87 B0 00 00 00", 2 ),
86-
get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B CB 48 8B 5C 24 78", 2 ),
87-
88-
// Blackjack
89-
get_pattern( "8D 4B 3C E8 ? ? ? ? 48 8B CF", 3 ),
90-
// The other one is below
91-
92-
// Poker
93-
get_pattern( "8D 4B 3C E8 ? ? ? ? B9 40 01 00 00", 3 ),
94-
// The other one is below
95-
96-
// Hanafuda/Koi-Koi
97-
get_pattern( "8D 4E 3C E8 ? ? ? ? 89 B3 80 00 00 00", 3 ),
98-
get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B 5C 24 68", 2 ),
99-
100-
// Unknown baseball game
101-
get_pattern( "8D 4B 3C E8 ? ? ? ? 48 8B 46 28", 3 ),
102-
get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B 43 28", 2 ),
103-
104-
// Unknown baseball game #2
105-
get_pattern( "33 C9 E8 ? ? ? ? 90 48 8D 93 1C 03 00 00", 2 ),
106-
get_pattern( "48 89 91 50 03 00 00 B9 ? ? ? ? E8 ?", 12 ),
107-
108-
// Darts
109-
get_pattern( "B9 ? ? ? ? E8 ? ? ? ? 48 8D 05 ? ? ? ? 48 89 44 24 58", 5 ),
110-
get_pattern( "33 C9 E8 ? ? ? ? 90 48 8D 8E 30 08 00 00", 2 )
111-
};
112-
113-
for ( void* addr : noppedFpsCalls )
114-
{
115-
Nop( addr, 5 );
116-
}
86+
auto ctor = get_pattern( "8D 48 3C E8 ? ? ? ? 33 C9", 3 );
87+
auto dtor = get_pattern( "E8 ? ? ? ? 90 49 8B CE 4C 8D 5C 24 ? 49 8B 5B 30" );
88+
89+
Nop(ctor, 5);
90+
Nop(dtor, 5);
91+
}
92+
TXN_CATCH();
93+
94+
// Oicho Kabu
95+
try
96+
{
97+
auto ctor = get_pattern( "B9 ? ? ? ? E8 ? ? ? ? 33 C0 48 89 83 00 07 00 00", 5 );
98+
auto dtor = get_pattern( "E8 ? ? ? ? 90 89 2D" );
99+
100+
Nop(ctor, 5);
101+
Nop(dtor, 5);
102+
}
103+
TXN_CATCH();
104+
105+
// Cee-lo/chinchiro
106+
try
107+
{
108+
auto ctor = get_pattern( "E8 ? ? ? ? 90 48 8B 8B ? ? ? ? 48 85 C9 74 16" );
109+
auto dtor = get_pattern( "B9 ? ? ? ? E8 ? ? ? ? 90 48 8D 4C 24 48", 5 );
110+
111+
Nop(ctor, 5);
112+
Nop(dtor, 5);
113+
}
114+
TXN_CATCH();
115+
116+
// Tougijyo (Colliseum) menu
117+
try
118+
{
119+
auto ctor = get_pattern( "8D 4B 3C E8 ? ? ? ? 48 8D 05", 3 );
120+
auto dtor = get_pattern( "33 C9 E8 ? ? ? ? 90 33 D2", 2 );
121+
122+
Nop(ctor, 5);
123+
Nop(dtor, 5);
124+
}
125+
TXN_CATCH();
126+
127+
// Batting center
128+
try
129+
{
130+
auto ctor1 = get_pattern( "8D 4D 3C E8 ? ? ? ? 49 8B 46 28", 3 );
131+
auto ctor2 = get_pattern( "33 C9 E8 ? ? ? ? 48 8B 87 B0 00 00 00", 2 );
132+
auto dtor = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B CB 48 8B 5C 24 78", 2 );
133+
134+
Nop(ctor1, 5);
135+
Nop(ctor2, 5);
136+
Nop(dtor, 5);
137+
}
138+
TXN_CATCH();
117139

118-
// Blackjack and poker dtors
119-
pattern( "33 C9 E8 ? ? ? ? 90 48 8B CB 48 8B 5C 24 40" ).count(2).for_each_result( [] ( pattern_match match ) {
140+
// Poker & Blackjack
141+
try
142+
{
143+
auto blackjack_ctor = get_pattern( "8D 4B 3C E8 ? ? ? ? 48 8B CF", 3 );
144+
auto poker_ctor = get_pattern( "8D 4B 3C E8 ? ? ? ? B9 40 01 00 00", 3 );
145+
auto dtors = pattern( "33 C9 E8 ? ? ? ? 90 48 8B CB 48 8B 5C 24 40" ).count(2);
146+
147+
Nop(blackjack_ctor, 5);
148+
Nop(poker_ctor, 5);
149+
150+
dtors.for_each_result( [] ( pattern_match match ) {
120151
Nop( match.get<void>( 2 ), 5 );
121152
} );
122153
}
154+
TXN_CATCH();
155+
156+
// Hanafuda/Koi-Koi
157+
try
158+
{
159+
auto ctor = get_pattern( "8D 4E 3C E8 ? ? ? ? 89 B3 80 00 00 00", 3 );
160+
auto dtor = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B 5C 24 68", 2 );
161+
162+
Nop(ctor, 5);
163+
Nop(dtor, 5);
164+
}
165+
TXN_CATCH();
166+
167+
// Unknown baseball game
168+
try
169+
{
170+
auto ctor = get_pattern( "8D 4B 3C E8 ? ? ? ? 48 8B 46 28", 3 );
171+
auto dtor = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B 43 28", 2 );
172+
173+
Nop(ctor, 5);
174+
Nop(dtor, 5);
175+
}
176+
TXN_CATCH();
177+
178+
// Unknown baseball game #2
179+
try
180+
{
181+
auto ctor = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8D 93 1C 03 00 00", 2 );
182+
auto dtor = get_pattern( "48 89 91 50 03 00 00 B9 ? ? ? ? E8", 12 );
183+
184+
Nop(ctor, 5);
185+
Nop(dtor, 5);
186+
}
187+
TXN_CATCH();
188+
189+
// Darts
190+
try
191+
{
192+
auto ctor = get_pattern( "B9 ? ? ? ? E8 ? ? ? ? 48 8D 05 ? ? ? ? 48 89 44 24 58", 5 );
193+
auto dtor = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8D 8E 30 08 00 00", 2 );
194+
195+
Nop(ctor, 5);
196+
Nop(dtor, 5);
197+
}
198+
TXN_CATCH();
123199

124200

125201
// Cap Toylets to 30FPS
202+
try
126203
{
127204
auto toyletsFpsCap = get_pattern( "B9 ? ? ? ? E8 ? ? ? ? B9 07 00 00 00", 1 );
128205
Patch<int32_t>( toyletsFpsCap, 30 );
129206
}
207+
TXN_CATCH();
130208

131209

132210
// Force 60FPS cap on arcade games even if 30FPS is selected in options
211+
try
133212
{
134213
using namespace ForcedMinigameFPS;
135214

136215
Trampoline* trampoline = Trampoline::MakeTrampoline( GetModuleHandle( nullptr ) );
137216

138-
auto enableCapTrampoline = trampoline->Jump(SetMinigameFPSCap_ForcedFPS<true>);
139-
auto disableCapTrampoline = trampoline->Jump(SetMinigameFPSCap_ForcedFPS<false>);
140-
141217
auto setFPSCap = get_pattern( "EB 02 33 C9 E8 ? ? ? ? 4C 8B 05", 4 );
142218
auto tickUserFPSCheck = get_pattern( "48 8B 15 ? ? ? ? 85 D2", 3 );
143219

144-
auto enableArcadeFPSCap_m2 = get_pattern( "E8 ? ? ? ? 44 88 64 24 40" );
145-
auto disableArcadeFPSCap_m2 = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8D 8B 00 03 00 00", 2 );
220+
auto TrampolineInterceptCall = [trampoline](auto address, auto&& func, auto&& hook)
221+
{
222+
InterceptCall(address, func, trampoline->Jump(hook));
223+
};
146224

147-
auto enableArcadeFPSCap_vf5 = get_pattern( "41 8D 4E 3C E8", 4 );
148-
auto disableArcadeFPSCap_vf5 = get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B 8B 10 03 00 00", 2 );
225+
TrampolineInterceptCall(setFPSCap, orgSetUserFPSCap, SetUserFPSCap_ForcedFPS);
226+
WriteOffsetValue(tickUserFPSCheck, &userFPSCap_ForMinigame); // This comes from the Trampoline memory!
149227

150-
auto enableFPSCap_Karaoke = get_pattern( "41 8D 4C 24 3C E8 ? ? ? ? B2 01", 5 );
151-
auto disableFPSCap_Karaoke = get_pattern( "33 C9 E8 ? ? ? ? 90 41 B8 ? ? ? ? 48 8D 54 24 ? 48 8B CB E8 ? ? ? ? 90 4C 8B C0", 2 );
228+
// M2 games
229+
try
230+
{
231+
std::array<void*, 1> enableCap { get_pattern( "E8 ? ? ? ? 44 88 64 24 40" ) };
232+
std::array<void*, 1> disableCap { get_pattern( "33 C9 E8 ? ? ? ? 90 48 8D 8B 00 03 00 00", 2 ) };
152233

153-
ReadCall( setFPSCap, orgSetUserFPSCap );
154-
InjectHook( setFPSCap, trampoline->Jump(SetUserFPSCap_ForcedFPS) );
234+
MinigameFPSCap<true>::HookEach_M2(enableCap, TrampolineInterceptCall);
235+
MinigameFPSCap<false>::HookEach_M2(disableCap, TrampolineInterceptCall);
236+
}
237+
TXN_CATCH();
155238

156-
ReadCall( enableArcadeFPSCap_m2, orgSetMinigameFPSCap );
157-
InjectHook( enableArcadeFPSCap_m2, enableCapTrampoline );
158-
InjectHook( disableArcadeFPSCap_m2, disableCapTrampoline );
239+
// VF5
240+
try
241+
{
242+
std::array<void*, 1> enableCap { get_pattern( "41 8D 4E 3C E8", 4 ) };
243+
std::array<void*, 1> disableCap { get_pattern( "33 C9 E8 ? ? ? ? 90 48 8B 8B 10 03 00 00", 2 ) };
159244

160-
InjectHook( enableArcadeFPSCap_vf5, enableCapTrampoline );
161-
InjectHook( disableArcadeFPSCap_vf5, disableCapTrampoline );
245+
MinigameFPSCap<true>::HookEach_VF5(enableCap, TrampolineInterceptCall);
246+
MinigameFPSCap<false>::HookEach_VF5(disableCap, TrampolineInterceptCall);
247+
}
248+
TXN_CATCH();
162249

163-
InjectHook(enableFPSCap_Karaoke, enableCapTrampoline);
164-
InjectHook(disableFPSCap_Karaoke, disableCapTrampoline);
250+
// Karaoke
251+
try
252+
{
253+
std::array<void*, 1> enableCap { get_pattern( "41 8D 4C 24 3C E8 ? ? ? ? B2 01", 5 ) };
254+
std::array<void*, 1> disableCap { get_pattern( "33 C9 E8 ? ? ? ? 90 41 B8 ? ? ? ? 48 8D 54 24 ? 48 8B CB E8 ? ? ? ? 90 4C 8B C0", 2 ) };
165255

166-
WriteOffsetValue( tickUserFPSCheck, &userFPSCap_ForMinigame ); // This comes from Trampoline memory!
256+
MinigameFPSCap<true>::HookEach_Karaoke(enableCap, TrampolineInterceptCall);
257+
MinigameFPSCap<false>::HookEach_Karaoke(disableCap, TrampolineInterceptCall);
258+
}
259+
TXN_CATCH();
167260
}
261+
TXN_CATCH();
168262
}

0 commit comments

Comments
 (0)