-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathNFSU_XtendedInput_FEng.h
452 lines (410 loc) · 14.8 KB
/
NFSU_XtendedInput_FEng.h
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
#pragma once
#define GAMEFLOWMANAGER_STATUS_ADDR 0x0077A920
#define FEMOUSECURSOR_BUTTONPRESS_ADDR 0x007064B0
#define FEMOUSECURSOR_CARORBIT_X_ADDR 0x007064A4
#define FEMOUSECURSOR_CARORBIT_Y_ADDR 0x007064A8
#define CFENG_PINSTANCE_ADDR 0x0073578C
enum ResourceFileType
{
RESOURCE_FILE_NONE = 0,
RESOURCE_FILE_GLOBAL = 1,
RESOURCE_FILE_FRONTEND = 2,
RESOURCE_FILE_INGAME = 3,
RESOURCE_FILE_TRACK = 4,
RESOURCE_FILE_NIS = 5,
RESOURCE_FILE_CAR = 6,
RESOURCE_FILE_LANGUAGE = 7,
RESOURCE_FILE_REPLAY = 8,
};
#define LASTCONTROLLED_KB 0
#define LASTCONTROLLED_CONTROLLER 1
unsigned int LastControlledDevice = 0; // 0 = keyboard, 1 = controller
unsigned int LastControlledDeviceOldState = 0;
#define CONTROLLERICON_XBOXONE 0
#define CONTROLLERICON_PS4 1
unsigned int ControllerIconMode = 0; // 0 = Xbox (One and later only for now), 1 = PlayStation (4 only now) -- planned to add: Nintendo (Wii/U Classic Controller, Switch), PS3/PS2, Xbox 360
bool bLoadedConsoleButtonTex = false;
char LastFEngPackage[128];
char CurrentSplashText[64];
void* (*CreateResourceFile)(char* filename, int ResType, int unk1, int unk2, int unk3) = (void* (*)(char*, int, int, int, int))0x004482F0;
void(*ServiceResourceLoading)() = (void(*)())0x004483C0;
unsigned int(*GetTextureInfo)(unsigned int hash, int unk, int unk2) = (unsigned int(*)(unsigned int, int, int))0x005461C0;
void(__thiscall* _FEngSetColor)(void* FEObject, unsigned int color) = (void(__thiscall*)(void*, unsigned int))0x004F75B0;
void(__thiscall* OptionsSelectorMenu_NotificationMessage)(void* UndergroundBriefScreen, unsigned int msg, void* FEObject, unsigned int unk2, unsigned int unk3) = (void(__thiscall*)(void*, unsigned int, void*, unsigned int, unsigned int))0x004D4610;
unsigned int ResourceFile_BeginLoading_Addr = 0x00448110;
void __stdcall ResourceFile_BeginLoading(void* ResourceFile, void* unk1, int unk2)
{
_asm
{
mov edx, ResourceFile
mov ecx, unk2
mov eax, unk1
call ResourceFile_BeginLoading_Addr
}
}
void __stdcall LoadResourceFile(char* filename, int ResType, int unk1, void* unk2, int unk3, int unk4, int unk5)
{
ResourceFile_BeginLoading(CreateResourceFile(filename, ResType, unk1, unk4, unk5), unk2, unk3);
}
unsigned int FEHashUpper_Addr = 0x004FD230;
unsigned int __stdcall FEHashUpper(const char* instr)
{
unsigned int result = 0;
_asm
{
mov edx, instr
call FEHashUpper_Addr
mov result, eax
}
return result;
}
// texture & control stuff
unsigned int FEPkgMgr_FindPackage_Addr = 0x004F65D0;
unsigned int FEPackageManager_FindPackage_Addr = 0x004F3F90;
unsigned int FEngFindObject_Addr = 0x004FFB70;
unsigned int FEngSendMessageToPackage_Addr = 0x004C96C0;
unsigned int FEPrintf_Addr = 0x004F68A0;
#pragma runtime_checks( "", off )
int __stdcall FEPrintf(void* FEString, char* format)
{
_asm
{
mov eax, FEString
push format
call FEPrintf_Addr
}
}
#pragma runtime_checks( "", restore )
void __stdcall FEngSendMessageToPackage(unsigned int msg, char* dest)
{
_asm
{
push msg
mov eax, dest
call FEngSendMessageToPackage_Addr
add esp, 4
}
}
unsigned int __stdcall FEPkgMgr_FindPackage(const char* pkgname)
{
unsigned int result = 0;
_asm
{
mov eax, pkgname
call FEPkgMgr_FindPackage_Addr
mov result, eax
}
return result;
}
unsigned int __stdcall FEPackageManager_FindPackage(const char* pkgname)
{
unsigned int result = 0;
_asm
{
push 0x00746104
mov eax, pkgname
call FEPackageManager_FindPackage_Addr
mov result, eax
}
return result;
}
unsigned int __stdcall _FEngFindObject(const char* pkg, int hash)
{
unsigned int result = 0;
_asm
{
mov ecx, hash
mov edx, pkg
call FEngFindObject_Addr
mov result, eax
}
return result;
}
unsigned int __stdcall FEngFindObject(const char* pkg, int hash)
{
char* pkgname = (char*)FEPkgMgr_FindPackage(pkg);
if (!pkgname)
return 0;
else
return _FEngFindObject(pkgname, hash);
}
unsigned int __stdcall FEngSetTextureHash(unsigned int FEImage, int hash)
{
int v2;
if (FEImage)
{
if (*(int*)(FEImage + 36) != hash)
{
v2 = *(int*)(FEImage + 28);
*(int*)(FEImage + 36) = hash;
*(int*)(FEImage + 28) = v2 | 0x400000;
}
}
return FEImage;
}
int __stdcall FEngFindString(const char* pkgname, int hash)
{
int result; // r3
result = FEngFindObject(pkgname, hash);
if (!result || *(int*)(result + 24) != 2)
result = 0;
return result;
}
int __stdcall FEngFindImage(const char* pkgname, int hash)
{
int result;
result = FEngFindObject(pkgname, hash);
if (!result || *(int*)(result + 24) != 1)
result = 0;
return result;
}
unsigned int FEngSetButtonState_Addr = 0x004F5F80;
void __stdcall FEngSetButtonState(const char* pkgname, unsigned int hash, unsigned int state)
{
int cfeng_instance = *(int*)CFENG_PINSTANCE_ADDR;
_asm
{
push state
mov edi, hash
mov eax, pkgname
push cfeng_instance
call FEngSetButtonState_Addr
//add esp, 4
}
}
#pragma runtime_checks( "", off )
void __stdcall FEngSetColor(void* FEObject, unsigned int color)
{
_FEngSetColor(FEObject, color);
_asm add esp, 4
}
#pragma runtime_checks( "", restore )
// we need to disable controller options menu because they crash the game
// (and currently are unusable anyways -- this will require extensive research to hook into the joypad config properly, for now we just stick to an ini config file)
void DisableControllerOptions()
{
FEngSetButtonState("MU_OptionsSelector_PC.fng", FEHashUpper("Controller"), 0);
FEngSetColor((void*)FEngFindObject("MU_OptionsSelector_PC.fng", FEHashUpper("Controller")), 0xFF404040);
}
void SnoopLastFEPackage(char* format, char* pkg)
{
strcpy(LastFEngPackage, pkg);
}
void SetPCFEButtons(char* pkgname)
{
int FEImage = 0;
if (FEImage = FEngFindImage(pkgname, 0x06749436)) // DeleteProfile_hotkey
FEngSetTextureHash(FEImage, PC_DELETE);
if (FEImage = FEngFindImage(pkgname, 0xA7615A5D)) // DeletePersona_hotkey
FEngSetTextureHash(FEImage, PC_DELETE);
if (FEImage = FEngFindImage(pkgname, 0x6E1D75B7)) // Default_hotkey
FEngSetTextureHash(FEImage, PC_CREATEROOM);
if (FEImage = FEngFindImage(pkgname, 0x83A65176)) // Stock_hotkey
FEngSetTextureHash(FEImage, PC_CREATEROOM);
if (FEImage = FEngFindImage(pkgname, 0xC8754FA4)) // Performance_hotkey
FEngSetTextureHash(FEImage, PC_PERFORMANCE);
if (FEImage = FEngFindImage(pkgname, 0xA16A1877)) // Changecolor_hotkey -- during car color changer
FEngSetTextureHash(FEImage, PC_X);
if (FEImage = FEngFindImage(pkgname, 0xBDD6AEEA)) // DecalColor_hotkey
FEngSetTextureHash(FEImage, PC_CREATEROOM);
if (FEImage = FEngFindImage(pkgname, 0x548F2015)) // Quit_hotkey
FEngSetTextureHash(FEImage, PC_QUIT);
if (FEImage = FEngFindImage(pkgname, 0x55DAFA35)) // customize_hotkey
FEngSetTextureHash(FEImage, PC_CUSTOM);
if (FEImage = FEngFindImage(pkgname, 0x571A8D51)) // Next_hotkey -- the "accept" button
FEngSetTextureHash(FEImage, PC_X);
if (FEImage = FEngFindImage(pkgname, 0x2A1208C3)) // Back_hotkey
FEngSetTextureHash(FEImage, PC_BACK);
if (FEImage = FEngFindImage(pkgname, 0x6340B325)) // PC_tutorial_01 (tutorial key)
FEngSetTextureHash(FEImage, PC_TUTORIAL);
if (FEImage = FEngFindImage(pkgname, 0x6340B326)) // PC_tutorial_02 (tutorial key)
FEngSetTextureHash(FEImage, PC_TUTORIAL);
// set splash screen text
if (FEHashUpper(pkgname) == 0x2729D8C3) // if we're in LS_Splash_PC.fng
{
wcstombs(CurrentSplashText, *(wchar_t**)(FEngFindString("LS_Splash_PC.fng", 0x13CF446D) + 0x60), 0x800);
if (FEHashUpper(CurrentSplashText) != 0xE7126192) // "Press enter to continue" -- TODO: multi-lingual support...
FEPrintf((void*)FEngFindString("LS_Splash_PC.fng", 0x13CF446D), "Press enter to continue"); // mouse_click text object
}
}
void SetPCIGButtons(char* pkgname)
{
int FEImage = 0;
if (FEImage = FEngFindImage(pkgname, 0x571A8D51)) // Next_hotkey -- the "accept" button
FEngSetTextureHash(FEImage, PC_X);
if (FEImage = FEngFindImage(pkgname, 0x2A1208C3)) // Back_hotkey
FEngSetTextureHash(FEImage, PC_BACK);
if (FEImage = FEngFindImage(pkgname, 0x548F2015)) // Quit_hotkey
FEngSetTextureHash(FEImage, PC_QUIT);
}
void SetXboxFEButtons(char* pkgname)
{
int FEImage = 0;
if (FEImage = FEngFindImage(pkgname, 0x06749436)) // DeleteProfile_hotkey
FEngSetTextureHash(FEImage, XBOXY_HASH);
if (FEImage = FEngFindImage(pkgname, 0xA7615A5D)) // DeletePersona_hotkey
FEngSetTextureHash(FEImage, XBOXY_HASH);
if (FEImage = FEngFindImage(pkgname, 0x6E1D75B7)) // Default_hotkey
FEngSetTextureHash(FEImage, XBOXY_HASH);
if (FEImage = FEngFindImage(pkgname, 0x83A65176)) // Stock_hotkey
FEngSetTextureHash(FEImage, XBOXX_HASH);
//if (FEImage = FEngFindImage(pkgname, 0xAD7303C0)) // CreateGame_hotkey
// FEngSetTextureHash(FEImage, XBOXY_HASH);
if (FEImage = FEngFindImage(pkgname, 0xC8754FA4)) // Performance_hotkey
FEngSetTextureHash(FEImage, XBOXX_HASH);
if (FEImage = FEngFindImage(pkgname, 0xA16A1877)) // Changecolor_hotkey -- during car color changer
FEngSetTextureHash(FEImage, XBOXA_HASH);
if (FEImage = FEngFindImage(pkgname, 0xBDD6AEEA)) // DecalColor_hotkey
FEngSetTextureHash(FEImage, XBOXX_HASH);
if (FEImage = FEngFindImage(pkgname, 0x548F2015)) // Quit_hotkey
FEngSetTextureHash(FEImage, XBOXBACK_HASH);
if (FEImage = FEngFindImage(pkgname, 0x55DAFA35)) // customize_hotkey
FEngSetTextureHash(FEImage, XBOXX_HASH);
if (FEImage = FEngFindImage(pkgname, 0x571A8D51)) // Next_hotkey -- the "accept" button
FEngSetTextureHash(FEImage, XBOXA_HASH);
if (FEImage = FEngFindImage(pkgname, 0x2A1208C3)) // Back_hotkey
FEngSetTextureHash(FEImage, XBOXB_HASH);
if (FEImage = FEngFindImage(pkgname, 0x6340B325)) // PC_tutorial_01 (tutorial key)
FEngSetTextureHash(FEImage, XBOXLT_HASH);
if (FEImage = FEngFindImage(pkgname, 0x6340B326)) // PC_tutorial_02 (tutorial key)
FEngSetTextureHash(FEImage, XBOXLT_HASH);
// set splash screen text
if (FEHashUpper(pkgname) == 0x2729D8C3) // if we're in LS_Splash_PC.fng
{
wcstombs(CurrentSplashText, *(wchar_t**)(FEngFindString("LS_Splash_PC.fng", 0x13CF446D) + 0x60), 0x800);
if (FEHashUpper(CurrentSplashText) != 0xD7027E29) // "Press A button"
FEPrintf((void*)FEngFindString("LS_Splash_PC.fng", 0x13CF446D), "Press A button"); // mouse_click text object
}
}
void SetXboxIGButtons(char* pkgname)
{
int FEImage = 0;
if (FEImage = FEngFindImage(pkgname, 0x571A8D51)) // Next_hotkey -- the "accept" button
FEngSetTextureHash(FEImage, XBOXA_HASH);
if (FEImage = FEngFindImage(pkgname, 0x2A1208C3)) // Back_hotkey
FEngSetTextureHash(FEImage, XBOXB_HASH);
if (FEImage = FEngFindImage(pkgname, 0x548F2015)) // Quit_hotkey
FEngSetTextureHash(FEImage, XBOXBACK_HASH);
}
void SetPlayStationFEButtons(char* pkgname)
{
int FEImage = 0;
if (FEImage = FEngFindImage(pkgname, 0x06749436)) // DeleteProfile_hotkey
FEngSetTextureHash(FEImage, PSTRIANGLE_HASH);
if (FEImage = FEngFindImage(pkgname, 0xA7615A5D)) // DeletePersona_hotkey
FEngSetTextureHash(FEImage, PSTRIANGLE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x6E1D75B7)) // Default_hotkey
FEngSetTextureHash(FEImage, PSSQUARE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x83A65176)) // Stock_hotkey
FEngSetTextureHash(FEImage, PSSQUARE_HASH);
//if (FEImage = FEngFindImage(pkgname, 0xAD7303C0)) // CreateGame_hotkey
// FEngSetTextureHash(FEImage, PSTRIANGLE_HASH);
if (FEImage = FEngFindImage(pkgname, 0xC8754FA4)) // Performance_hotkey
FEngSetTextureHash(FEImage, PSSQUARE_HASH);
if (FEImage = FEngFindImage(pkgname, 0xA16A1877)) // Changecolor_hotkey -- during car color changer
FEngSetTextureHash(FEImage, PSCROSS_HASH);
if (FEImage = FEngFindImage(pkgname, 0xBDD6AEEA)) // DecalColor_hotkey
FEngSetTextureHash(FEImage, PSSQUARE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x548F2015)) // Quit_hotkey
FEngSetTextureHash(FEImage, PSSHARE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x55DAFA35)) // customize_hotkey
FEngSetTextureHash(FEImage, PSSQUARE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x571A8D51)) // Next_hotkey -- the "accept" button
FEngSetTextureHash(FEImage, PSCROSS_HASH);
if (FEImage = FEngFindImage(pkgname, 0x2A1208C3)) // Back_hotkey
FEngSetTextureHash(FEImage, PSCIRCLE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x6340B325)) // PC_tutorial_01 (tutorial key)
FEngSetTextureHash(FEImage, PSL2_HASH);
if (FEImage = FEngFindImage(pkgname, 0x6340B326)) // PC_tutorial_02 (tutorial key)
FEngSetTextureHash(FEImage, PSL2_HASH);
// set splash screen text
if (FEHashUpper(pkgname) == 0x2729D8C3) // if we're in LS_Splash_PC.fng
{
wcstombs(CurrentSplashText, *(wchar_t**)(FEngFindString("LS_Splash_PC.fng", 0x13CF446D) + 0x60), 0x800);
if (FEHashUpper(CurrentSplashText) != 0x10EC9E60) // "Press X button"
FEPrintf((void*)FEngFindString("LS_Splash_PC.fng", 0x13CF446D), "Press X button"); // mouse_click text object
}
}
void SetPlayStationIGButtons(char* pkgname)
{
int FEImage = 0;
if (FEImage = FEngFindImage(pkgname, 0x571A8D51)) // Next_hotkey -- the "accept" button
FEngSetTextureHash(FEImage, PSCROSS_HASH);
if (FEImage = FEngFindImage(pkgname, 0x2A1208C3)) // Back_hotkey
FEngSetTextureHash(FEImage, PSCIRCLE_HASH);
if (FEImage = FEngFindImage(pkgname, 0x548F2015)) // Quit_hotkey
FEngSetTextureHash(FEImage, PSSHARE_HASH);
}
void __stdcall SetControllerFEng(char* pkgname)
{
if (!bLoadedConsoleButtonTex)
{
LoadResourceFile("GLOBAL\\UG_ConsoleButtons.tpk", RESOURCE_FILE_NONE, 0, NULL, 0, 0, 0);
ServiceResourceLoading();
bLoadedConsoleButtonTex = true;
}
if (*(int*)GAMEFLOWMANAGER_STATUS_ADDR == 3)
{
if (LastControlledDevice == LASTCONTROLLED_CONTROLLER)
{
switch (ControllerIconMode)
{
case CONTROLLERICON_PS4:
SetPlayStationFEButtons(pkgname);
break;
case CONTROLLERICON_XBOXONE:
default:
SetXboxFEButtons(pkgname);
break;
}
}
if (LastControlledDevice == LASTCONTROLLED_KB)
SetPCFEButtons(pkgname);
}
if (*(int*)GAMEFLOWMANAGER_STATUS_ADDR == 6)
{
if (LastControlledDevice == LASTCONTROLLED_CONTROLLER)
{
switch (ControllerIconMode)
{
case CONTROLLERICON_PS4:
SetPlayStationIGButtons(pkgname);
break;
case CONTROLLERICON_XBOXONE:
default:
SetXboxIGButtons(pkgname);
break;
}
}
if (LastControlledDevice == LASTCONTROLLED_KB)
SetPCIGButtons(pkgname);
}
}
// entrypoint: 0x004F7C08
unsigned int FEngGlobalCaveExit = 0x004F7C0E;
unsigned int FEngGlobalCaveEBP = 0;
unsigned int FEngGlobalCaveESI = 0;
char* CurrentFEngPackage = NULL;
void __declspec(naked) FEngGlobalCave()
{
_asm mov FEngGlobalCaveEBP, ebp
_asm mov FEngGlobalCaveESI, esi
CurrentFEngPackage = *(char**)(FEngGlobalCaveESI + 0xC);
SetControllerFEng(CurrentFEngPackage);
_asm
{
mov esi, FEngGlobalCaveESI
mov ebp, FEngGlobalCaveEBP
cmp ebp, 0xC519BFC3
jmp FEngGlobalCaveExit
}
}
#pragma runtime_checks( "", off )
void __stdcall OptionsSelectorMenu_NotificationMessage_Hook(unsigned int unk1, void* FEObject, unsigned int unk2, unsigned int unk3)
{
unsigned int thethis = 0;
_asm mov thethis, ecx
DisableControllerOptions();
return OptionsSelectorMenu_NotificationMessage((void*)thethis, unk1, FEObject, unk2, unk3);
}
#pragma runtime_checks( "", restore )