-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSoH_PauseBuffer.ahk
276 lines (237 loc) · 8.37 KB
/
SoH_PauseBuffer.ahk
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
SetTitleMatchMode 2 ; Avoids the need to specify the full path of files.
;;==============================[Load Libraries]===============================
#Include lib\Initialization.ahk
#Include lib\XInput.ahk
#Include lib\Functions.ahk
#Include lib\MemoryLibrary.ahk
#Include lib\classMemory.ahk
;@Ahk2Exe-AddResource lib\Initialization.ahk
;@Ahk2Exe-AddResource lib\XInput.ahk
;@Ahk2Exe-AddResource lib\Functions.ahk
;@Ahk2Exe-AddResource lib\MemoryLibrary.ahk
;@Ahk2Exe-AddResource lib\classMemory.ahk
/*
;gamepad button types
dwPacketNumber
wButtons 0x0000 -> 0xFFFF
bLeftTrigger 0 -> 255
bRightTrigger 0 -> 255
sThumbLX -32,768 -> 32,767
sThumbLY -32,768 -> 32,767
sThumbRX -32,768 -> 32,767
sThumbRY -32,768 -> 32,767
;gamepad buttons
XINPUT_GAMEPAD_DPAD_UP
XINPUT_GAMEPAD_DPAD_DOWN
XINPUT_GAMEPAD_DPAD_LEFT
XINPUT_GAMEPAD_DPAD_RIGHT
XINPUT_GAMEPAD_START
XINPUT_GAMEPAD_BACK
XINPUT_GAMEPAD_LEFT_THUMB
XINPUT_GAMEPAD_RIGHT_THUMB
XINPUT_GAMEPAD_LEFT_SHOULDER
XINPUT_GAMEPAD_RIGHT_SHOULDER
XINPUT_GAMEPAD_GUIDE
XINPUT_GAMEPAD_A
XINPUT_GAMEPAD_B
XINPUT_GAMEPAD_X
XINPUT_GAMEPAD_Y
*/
;Make XInput variables global
global XINPUT_GAMEPAD_DPAD_UP
global XINPUT_GAMEPAD_DPAD_DOWN
global XINPUT_GAMEPAD_DPAD_LEFT
global XINPUT_GAMEPAD_DPAD_RIGHT
global XINPUT_GAMEPAD_START
global XINPUT_GAMEPAD_BACK
global XINPUT_GAMEPAD_LEFT_THUMB
global XINPUT_GAMEPAD_RIGHT_THUMB
global XINPUT_GAMEPAD_LEFT_SHOULDER
global XINPUT_GAMEPAD_RIGHT_SHOULDER
global XINPUT_GAMEPAD_GUIDE
global XINPUT_GAMEPAD_A
global XINPUT_GAMEPAD_B
global XINPUT_GAMEPAD_X
global XINPUT_GAMEPAD_Y
global state
;;================================[Main Loop]==================================
InitVars() , OnExit("InitVars")
;Main Loop
Loop{
;Check that Soh is still open
GoSub SoHexeCheck
;Read & store your Controller's state
state := Xinput_GetState(0)
;Check if pressed a Hotkey
Gosub SoHhotkeys
;Loop while pause is pressed
if Xpressed(XINPUT_GAMEPAD_START){
While Xpressed(XINPUT_GAMEPAD_START){
state := Xinput_GetState(0)
GoSub SoHhotkeys
}
}
;Allow you to pause if "GAMEPAD_DPAD_UP" is pressed (and loop until released)
if XonlyDPAD(XINPUT_GAMEPAD_DPAD_UP){
ChangeP1Controller("Keyboard")
send {space down}
QPCsleep(51)
send {space up}
ChangeP1Controller(0)
state := Xinput_GetState(0)
While Xpressed(XINPUT_GAMEPAD_DPAD_UP){
state := Xinput_GetState(0)
GoSub SoHhotkeys
}
}
;While paused...
while (GetPauseMenuState() >= 0x06){
Paused:
;Check that Soh is still open
Gosub SoHexeCheck
;Read & store your Controller's state
state := Xinput_GetState(0)
;Check if pressed a Hotkey
Gosub SoHhotkeys
;Check that pressed "GAMEPAD_START" or "GAMEPAD_DPAD_UP"
if (Xpressed(XINPUT_GAMEPAD_START) or XonlyDPAD(XINPUT_GAMEPAD_DPAD_UP) or ((GetPauseMenuState() = 0x07) & (Xpressed(XINPUT_GAMEPAD_B) or Xpressed(XINPUT_GAMEPAD_A))) ){
;Store Time
Time := QPC()
;If DPAD_UP detected send KB "Start" down (For frame advance logic)
if Xpressed(XINPUT_GAMEPAD_DPAD_UP){
ChangeP1Controller("Keyboard")
send {space down}
}
;Eliminate retriggering lock-on if already being held
if (Xpressed(XINPUT_GAMEPAD_LEFT_SHOULDER) & !Getkeystate("z") & !!GetFocusStatus())
send {z down}
;Give time for Controller command to reach SoH
QPCsleep(51)
;Change p1's control as "Keyboard"
ChangeP1Controller("Keyboard")
;Wait until game unpauses
While (GetPauseMenuState() <> 0x00) {
state := Xinput_GetState(0)
Gosub SoHreset
;if it fails to do so in 400ms return to "Paused" sub and reset variables
if ((QPC() - Time) > 400){
ChangeP1Controller(0)
send {space up}
send {z up}
goto Paused
}
;If DPAD_UP detected send KB "Start" down (For frame advance logic)
if ( Xpressed(XINPUT_GAMEPAD_DPAD_UP) & !GetKeyState("Space") )
send {space down}
}
;Change p1's controller index to 0 (Game Controller)
ChangeP1Controller(0)
;Frame Advance Logic
if getkeystate("space"){
QPCsleep(60) ;This specific timing seems to work
ChangeP1Controller("Keyboard")
send {space down}
QPCsleep(51)
}
;Re-initialize variables before exiting
InitVars()
} ;Unpausing
} ;Paused
} ;Main loop
;;=============================[Custom Functions]==============================
InitVars(){
;Initialize XInput function
XInput_Init()
;Change p1's controller index to 0 (Game Controller)
ChangeP1Controller(0)
;Reset keyboard commands
send {z up}
send {space up}
send {F5 up}
send {F6 up}
send {F7 up}
send {Ctrl up}
send {R up}
}
;Check if XInput button is being pressed (only wButtons)
Xpressed(XINPUT_GAMEPAD=""){
return (XINPUT_GAMEPAD = (XINPUT_GAMEPAD & state.wButtons))
}
;Check if DPAD button is the only DPAD button being pressed (ignores other buttons)
XonlyDPAD(XINPUT_GAMEPAD=""){
DPAD_UP := Xpressed(XINPUT_GAMEPAD_DPAD_UP)
DPAD_DOWN := Xpressed(XINPUT_GAMEPAD_DPAD_DOWN)
DPAD_LEFT := Xpressed(XINPUT_GAMEPAD_DPAD_LEFT)
DPAD_RIGHT := Xpressed(XINPUT_GAMEPAD_DPAD_RIGHT)
return ( Xpressed(XINPUT_GAMEPAD) & ((DPAD_UP + DPAD_DOWN + DPAD_LEFT + DPAD_RIGHT) = 1) )
}
;;===============================[Custom Subs]=================================
;Calling Subs is more efficient than calling functions!
SoHexeCheck:
;If "SoH.exe" not detected, loop until it is
If (!!ProcessPID("SoH.Exe") = false){
CleanExit()
While (!!ProcessPID("SoH.Exe") = false)
QPCsleep(2000)
QPCsleep(1000)
MemReInit()
}
GoSub MainMenuCheck
Return
MainMenuCheck:
;If in Main menu, loop until you aren't
If (GetGameState()<2){
while ((GetGameState()<1) & (!!ProcessPID("SoH.Exe") = true)){
QPCsleep(500)
;Re-initialize memory reads
MemReInit()
}
;Reload Script once you re-enter game (I could not get it to rehook without a script reload)
while (GetGameState()=1)
QPCsleep(200)
Reload
}
Return
SoHhotkeys:
Gosub SoHreset
;SaveState
if XonlyDPAD(XINPUT_GAMEPAD_DPAD_LEFT){
Send {F5 down}
QPCsleep(51)
Send {F5 up}
;Loop until released
While Xpressed(XINPUT_GAMEPAD_DPAD_LEFT){
state := Xinput_GetState(0)
}
}
;NextState
if XonlyDPAD(XINPUT_GAMEPAD_DPAD_DOWN){
Send {F6 down}
QPCsleep(51)
Send {F6 up}
;Loop until released
While Xpressed(XINPUT_GAMEPAD_DPAD_DOWN){
state := Xinput_GetState(0)
}
}
;LoadState
if XonlyDPAD(XINPUT_GAMEPAD_DPAD_RIGHT){
Send {F7 down}
QPCsleep(51)
Send {F7 up}
;Loop until released
While Xpressed(XINPUT_GAMEPAD_DPAD_RIGHT){
state := Xinput_GetState(0)
}
}
Return
SoHreset:
;ResetGame
if (Xpressed(XINPUT_GAMEPAD_DPAD_DOWN) & Xpressed(XINPUT_GAMEPAD_START)){
Send {Ctrl down}
Send {R down}
QPCsleep(51)
Send {Ctrl up}
Send {R up}
}
Return