Spellforce-Spell-framework
Loading...
Searching...
No Matches
sf_prepare_new_game.c
Go to the documentation of this file.
1
7
8#include "../sf_wrappers.h"
9#include "../sf_ui_wrappers.h"
10#include "sf_campaign_hook.h"
11#include "sf_prepare_new_game.h"
12#include "../sf_hooks.h"
13#include "sf_vanilla_fix_hook.h"
14
15#include <stdint.h>
16#include <stdio.h>
17#include <string.h>
18#include <windows.h>
19
20static preloadGetResultCode_ptr pn_get_result_code;
21static gameInfoReset_ptr pn_gi_reset_avatar;
22static preloadGetAvatar_ptr pn_preload_get_avatar;
23static gameInfoSetAvatar_ptr pn_gi_set_avatar_equipdata;
24static gameInfoGetU8_ptr pn_gi_get_kit_index;
25static gameInfoFigureAbilities_ptr pn_gi_get_skill, pn_gi_get_subskill;
26static preloadGetU8_ptr pn_preload_get_kit_index;
27static preloadGetU32_ptr pn_preload_get_sotp_side, pn_preload_get_campaign_type;
28
29
30static giSetBoolU8_ptr pn_gi_set_premade_kit, pn_gi_apply_premade_kit;
31static giSetU32_ptr pn_gi_set_start_mode2, pn_gi_set_game_mode,
32 pn_gi_set_flag_a, pn_gi_set_flag_b;
33static giSetStr_ptr pn_gi_set_save_file_path, pn_gi_set_save_file_name;
34static giSetTemplateName_ptr pn_gi_set_template_name;
35static giVoid_ptr pn_gi_refresh_case7;
36static giStarterKitReset_ptr pn_gi_starterkit_reset;
37static preloadGetStr_ptr pn_preload_get_slot_name, pn_preload_get_avatar_name,
38 pn_preload_get_freegame_map, pn_preload_get_freegame_template;
39static appMenuReadSave_ptr pn_read_from_save;
40static getPregameScreen_ptr pn_get_pregame_screen;
41static getScreenName_ptr pn_screen_get_name;
42static screenDeleteControl_ptr pn_screen_delete_control;
43static screenSetActive_ptr pn_screen_set_active;
44static cfgCtor_ptr pn_cfg_ctor;
45static cfgDtor_ptr pn_cfg_dtor;
46static cfgSetString_ptr pn_cfg_set_string;
47static preloadUpdateKit_ptr pn_update_kit;
48static preloadUpdateKit2_ptr pn_update_kit_2;
49
50/* last-played globals best guesses */
51static SF_String *pn_s_cfg_key; /* DAT_00d24120 @ 0xd24120 (section?) */
52static SF_String *pn_s_last_addon; /* S_LAST_PLAYED_ADDON @ 0xd243d0 */
53static SF_String *pn_s_last_sotp; /* DAT_00d24480 @ 0xd24480 */
54static SF_String *pn_s_last_coop; /* DAT_00d23c90 @ 0xd23c90 */
57
58static InitUnknownAvatar_0x54_ptr InitUnknownAvatar_0x54, DisposeUnknownAvatar_0x54;
59static updatePreloadUnknown_0x54_ptr updatePreloadUnknown_0x54;
60static InitAvatarInternal_ptr InitAvatarInternal;
62static void install_preparenewgame_hook();
63
65{
66 pn_get_result_code = (preloadGetResultCode_ptr)(ASI::AddrOf(0x5fad30));
67
68 pn_gi_reset_avatar = (gameInfoReset_ptr)(ASI::AddrOf(0x1a1830));
69 pn_preload_get_avatar = (preloadGetAvatar_ptr)(ASI::AddrOf(0x5fae00));
70 pn_gi_set_avatar_equipdata = (gameInfoSetAvatar_ptr)(ASI::AddrOf(0x1a1440));
71 pn_gi_get_skill = (gameInfoFigureAbilities_ptr)(ASI::AddrOf(0x19e7a0));
72 pn_gi_get_subskill = (gameInfoFigureAbilities_ptr)(ASI::AddrOf(0x19e7c0));
73 pn_gi_get_kit_index = (gameInfoGetU8_ptr)(ASI::AddrOf(0x175f00));
74 pn_preload_get_sotp_side = (preloadGetU32_ptr)(ASI::AddrOf(0x60a3d0));
75 pn_preload_get_campaign_type = (preloadGetU32_ptr)(ASI::AddrOf(0x5faa10));
76
77 pn_preload_get_kit_index = (preloadGetU8_ptr)(ASI::AddrOf(0x5fae20));
78
79 pn_gi_set_premade_kit = (giSetBoolU8_ptr)(ASI::AddrOf(0x176760));
80 pn_gi_apply_premade_kit = (giSetBoolU8_ptr)(ASI::AddrOf(0x1a1b10));
81 pn_gi_set_start_mode2 = (giSetU32_ptr)(ASI::AddrOf(0x176780));
82 pn_gi_set_game_mode = (giSetU32_ptr)(ASI::AddrOf(0x1766f0));
83 pn_gi_set_flag_a = (giSetU32_ptr)(ASI::AddrOf(0x176740));
84 pn_gi_set_flag_b = (giSetU32_ptr)(ASI::AddrOf(0x176750));
85 pn_gi_set_save_file_path = (giSetStr_ptr)(ASI::AddrOf(0x176320));
86 pn_gi_set_save_file_name = (giSetStr_ptr)(ASI::AddrOf(0x176700));
87 pn_gi_set_template_name = (giSetTemplateName_ptr)(ASI::AddrOf(0x176790));
88 pn_gi_refresh_case7 = (giVoid_ptr)(ASI::AddrOf(0x176480));
89 pn_gi_starterkit_reset = (giStarterKitReset_ptr)(ASI::AddrOf(0x1763c0));
90 pn_preload_get_slot_name = (preloadGetStr_ptr)(ASI::AddrOf(0x609520));
91 pn_preload_get_avatar_name = (preloadGetStr_ptr)(ASI::AddrOf(0x609600));
92 pn_preload_get_freegame_map = (preloadGetStr_ptr)(ASI::AddrOf(0x60a3e0));
93 pn_preload_get_freegame_template = (preloadGetStr_ptr)(ASI::AddrOf(0x60a410));
94 pn_read_from_save = (appMenuReadSave_ptr)(ASI::AddrOf(0x186520));
95 pn_get_pregame_screen = (getPregameScreen_ptr)(ASI::AddrOf(0x50f930));
96 pn_screen_get_name = (getScreenName_ptr)(ASI::AddrOf(0x510cf0));
97 pn_screen_delete_control = (screenDeleteControl_ptr)(ASI::AddrOf(0x508560));
98 pn_screen_set_active = (screenSetActive_ptr)(ASI::AddrOf(0x512180));
99 pn_cfg_ctor = (cfgCtor_ptr)(ASI::AddrOf(0x389050));
100 pn_cfg_dtor = (cfgDtor_ptr)(ASI::AddrOf(0x387e20));
101 pn_cfg_set_string = (cfgSetString_ptr)(ASI::AddrOf(0x3897b0));
102 pn_update_kit = (preloadUpdateKit_ptr)(ASI::AddrOf(0x176760));
103 pn_update_kit_2 = (preloadUpdateKit2_ptr)(ASI::AddrOf(0x1a1b10));
105
107
108 pn_s_cfg_key = (SF_String *)(ASI::AddrOf(0x924120));
109 pn_s_last_addon = (SF_String *)(ASI::AddrOf(0x9243d0));
110 pn_s_last_sotp = (SF_String *)(ASI::AddrOf(0x924480));
111 pn_s_last_coop = (SF_String *)(ASI::AddrOf(0x923c90));
112
113 InitUnknownAvatar_0x54 = (InitUnknownAvatar_0x54_ptr)(ASI::AddrOf(0x17dd30));
114 DisposeUnknownAvatar_0x54 = (InitUnknownAvatar_0x54_ptr)(ASI::AddrOf(0x17f110));
115
116 updatePreloadUnknown_0x54 = (updatePreloadUnknown_0x54_ptr)(ASI::AddrOf(0x6097b0));
117 InitAvatarInternal = (InitAvatarInternal_ptr)(ASI::AddrOf(0x17d920));
119 install_preparenewgame_hook();
120}
121
123{
124 uint8_t is_coop = (_this->CUiMenuPreLoad_data.game_info)->is_coop;
125 if(is_coop == 0 && (_this->CUiMenuPreLoad_data).campaign_type == 0)
126 {
127 return (_this->CUiMenuPreLoad_data).skip_tutorial;
128 }
129 return 1;
130}
131
132SF_String * __thiscall getSavePath(CAppSession *_this, SF_String *output, uint32_t campaign_type);
133
134SF_String * build_load_path(CAppMenu *_this, void *preload, SF_String *out)
135{
136 SF_String base, avatar_name, slot_name;
137 uiAPI.SFStringConstructor(&base);
138 int ct = _this->CAppMenu_data.campaign_type;
140 {
141 SF_String coop_str;
142 uiAPI.SFStringConstructor_char(&coop_str, "CHAR\\");
143 getSavePath(_this->CAppMenu_data.CAppSession, &base, 0);
144 uiAPI.SFStringConcat(&base, &coop_str);
145 uiAPI.SFStringDestructor(&coop_str);
146 }
147 else
148 {
149 getSavePath(_this->CAppMenu_data.CAppSession, &base, ct);
150 }
151
152 pn_preload_get_avatar_name(preload, &avatar_name);
153 pn_preload_get_slot_name(preload, &slot_name);
154
155 const wchar_t *bp = base.raw_data ? base.raw_data : L"";
156 const wchar_t *an = avatar_name.raw_data ? avatar_name.raw_data : L"";
157 const wchar_t *sn = slot_name.raw_data ? slot_name.raw_data : L"";
158
159
160 uiAPI.SFStringConstructor(out);
162 {
163 uiAPI.SFprintf(out, L"%ls%ls.sav", bp, sn);
164 }
165 else
166 {
167 uiAPI.SFprintf(out, L"%ls%ls~%ls.sav", bp, an, sn);
168 }
169
170 uiAPI.SFStringDestructor(&slot_name);
171 uiAPI.SFStringDestructor(&avatar_name);
172 uiAPI.SFStringDestructor(&base);
173 return out;
174}
175
176void __thiscall hooked_prepare_new_game(CAppMenu *_this, CUiMenuPreLoad *preload)
177{
178 CUtlConfigFile configFile;
179 pn_cfg_ctor(&configFile, (char *)0x0);
180
181 uint8_t avatar_buf_a[224]; // Ghidra's local_1f8
182 uint8_t avatar_buf_b[224]; // Ghidra's auStack_11c
183 uint32_t result_code = preload->CUiMenuPreLoad_data.offset_0x8c;
184 SF_GameInfo *game_info = &(_this->CAppMenu_data).game_info;
185 (_this->CAppMenu_data).pregame_load_result = result_code;
186
187 GdAvatarData *avatar_data = &(game_info->AC82).avatarData;
188
189 GdAvatarInternal *internal_avatar = &avatar_data->internal;
190 uint16_t saved_avatar_type = internal_avatar->avatar_type;
191
192 pn_gi_reset_avatar(game_info, 0); // might be internal_avatar init
193 GdAvatarData *a = pn_preload_get_avatar(preload, (GdAvatarData *)avatar_buf_a);
194 uint16_t equip_word = *(uint16_t *)((uint8_t *)a + 0xd4); // read BEFORE 2nd call
195 GdAvatarData *b = pn_preload_get_avatar(preload, (GdAvatarData *)avatar_buf_b);
196
197 pn_gi_set_avatar_equipdata(game_info, (GdAvatar *)b, equip_word);
198 game_info->AC82.avatarData.internal.avatar_type = saved_avatar_type;
199
200 uint8_t skill_id = pn_gi_get_skill(game_info, 0);
201 uint8_t subskill_spec = pn_gi_get_subskill(game_info, 1);
202
203 CMnuScreen *pregame_screen = pn_get_pregame_screen((_this->CAppMenu_data).splash_screen);
204
205 if (pregame_screen != (CMnuScreen *)0)
206 {
207 SF_String *ctrl_name = pn_screen_get_name(pregame_screen);
208 pn_screen_delete_control((_this->CAppMenu_data).splash_screen, ctrl_name);
209 pn_screen_set_active((_this->CAppMenu_data).splash_screen, (CMnuScreen *)0);
210 }
211
212 CreateMnuHintExt(_this);
213
214 char store_last_played = 0;
215
216 SF_String dot_map, predefined_template;
217 uiAPI.SFStringConstructor_char(&predefined_template, "figure_template\\predefined\\");
218 uiAPI.SFStringConstructor_char(&dot_map, "*.map");
219 SF_String *nm = NULL;
220 switch((_this->CAppMenu_data).pregame_load_result)
221 {
222 case 0:
223 case 2:
224 {
225 if ((_this->CAppMenu_data).campaign_type == 2)
226 {
227 uint32_t sotp_side = pn_preload_get_sotp_side(preload);
228 uint32_t campaign_type = pn_preload_get_campaign_type(preload);
229 uint32_t skip_tutorial = pn_preload_get_skip_tutorial(preload);
230
231 initFirstMap(game_info, skip_tutorial & 0xff, skill_id, subskill_spec,
232 campaign_type, (uint8_t)sotp_side != 0);
233
234 uint8_t kit = pn_preload_get_kit_index(preload);
235 pn_update_kit(game_info, (_this->CAppMenu_data).pregame_load_result == 2, kit);
236
237 SF_String des_name;
238 uiAPI.SFStringConstructor(&des_name); /* 0x00783900 */
239
240 uint32_t side_again = pn_preload_get_sotp_side(preload);
241 uint8_t kit_idx = pn_gi_get_kit_index(game_info); /* 0x00575F00 */
242
243 uiAPI.SFprintf(&des_name,
244 (side_again == 0) ? L"PDC3_%02dp.des"
245 : L"PDC3_%02ds.des",
246 (kit_idx & 0xff) + 1); /* 0x00784170 */
247
248 game_info->start_mode = 2;
249
250 SF_String tmpl;
251 SF_String *full = uiAPI.SFStringConcatMulti(&predefined_template, &tmpl, &des_name);
252 pn_gi_set_template_name(game_info, full); /* 0x00576790 */
253
254 uiAPI.SFStringDestructor(&tmpl);
255 uiAPI.SFStringDestructor(&des_name);
256 uiAPI.SFStringDestructor(&predefined_template);
257
258 }
259 else
260 {
261 uint32_t campaign_id = pn_preload_get_campaign_type(preload);
262 uint32_t skip_tutorial = pn_preload_get_skip_tutorial(preload);
263
264 initFirstMap(game_info, skip_tutorial & 0xff, skill_id, subskill_spec,
265 campaign_id, false);
266
267 uint8_t kit = pn_preload_get_kit_index(preload);
268 pn_update_kit(game_info,
269 (_this->CAppMenu_data).pregame_load_result == 2, kit);
270
271 kit = pn_preload_get_kit_index(preload);
272 pn_update_kit_2(game_info,
273 (uint32_t)((_this->CAppMenu_data).pregame_load_result == 2), kit);
274 }
275
276 uiAPI.SFStringDeepCopy(&(_this->CAppMenu_data).pregrame_dotmap_string, &dot_map);
278 break;
279 }
280
281 case 7:
282 {
283 SF_String save_path;
284 SF_String dot_sav;
285 uiAPI.SFStringConstructor_wchar(&dot_sav, L".sav");
286 pn_preload_get_slot_name(preload, &save_path);
287 uiAPI.SFStringConcat(&save_path, &dot_sav);
288
289 pn_read_from_save(_this, &save_path);
290 uiAPI.SFStringDestructor(&save_path);
291 uiAPI.SFStringDestructor(&dot_sav);
292
293 pn_gi_refresh_case7(game_info);
294 uiAPI.SFStringDeepCopy(&(_this->CAppMenu_data).pregrame_dotmap_string, &dot_map);
295
296 SF_String avatar_name;
297 SF_String extra;
298
299 uiAPI.SFStringConstructor_wchar(&avatar_name,game_info->AC82.avatarData.internal.name);
300 uiAPI.SFStringConstructor_char(&extra, "");
301
302 CreateMenuPreMulti(_this, 0, 0, 6, 0, 0, 2, 6942, &extra, &avatar_name);
303
304 uiAPI.SFStringDestructor(&extra);
305 uiAPI.SFStringDestructor(&avatar_name);
306 break;
307 }
308 case 8:
309 {
310 game_info->unknown_0xf0 = 1;
311 game_info->unknown_0xf4 = 3;
312 game_info->unknown4 = 1;
313 SF_String map_name;
314 pn_preload_get_freegame_map(preload, &map_name);
315 pn_gi_set_save_file_name(game_info, &map_name);
316 uiAPI.SFStringDestructor(&map_name);
317
318 game_info->start_mode = 1;
319 SF_String template_name;
320 pn_preload_get_freegame_template(preload, &template_name);
321 uiAPI.SFStringConcat(&predefined_template, &template_name);
322 pn_gi_set_template_name(game_info, &predefined_template);
323 uiAPI.SFStringDestructor(&predefined_template);
324 SF_String extra;
325 uiAPI.SFStringConstructor_char(&extra, "");
326 s_start_game(_this, game_info, 100, 0,0, 0, &extra);
327 uiAPI.SFStringDestructor(&extra);
328 break;
329 }
330 case 9:
331 {
332 InitUnknownAvatar_0x54(&avatar_buf_b[0x54]);
333
334 uiAPI.SFStringConstructor((SF_String *)(&avatar_buf_b[0xc4]));
335 if (updatePreloadUnknown_0x54(preload, &avatar_buf_b[0x54]))
336 {
337 GdAvatarInternal *ava_int = InitAvatarInternal(&avatar_buf_a[0x8]);
338 if (importFromSave(_this, &avatar_buf_b[0x54], ava_int))
339 {
340 pn_gi_set_avatar_equipdata(game_info, ava_int, 0);
341 uint32_t sotp_side = avatar_buf_b[0xd4];
342 SF_String initial_map;
343 if (sotp_side)
344 {
345 uiAPI.SFStringConstructor_char(&initial_map, "map\\Campaign3\\P202_City_Of_Souls.map");
346 }
347 else
348 {
349 uiAPI.SFStringConstructor_char(&initial_map, "map\\Campaign3\\P201_Blackwater_Coast.map");
350 }
351 game_info->unknown_0xf0 = 1;
352 game_info->unknown_0xf4 = 3;
353 game_info->is_tutorial = 0;
354 game_info->start_mode = 3;
355 uiAPI.SFStringDeepCopy(&game_info->filename, &initial_map);
356 uiAPI.SFStringDestructor(&initial_map);
358 }
359 DisposeUnknownAvatar_0x54(&avatar_buf_b[0x54]);
360 }
361 break;
362 }
363 case 1:
364 case 3:
365 {
366 pn_gi_starterkit_reset(game_info, skill_id, subskill_spec);
367 uint8_t kit_index = pn_preload_get_kit_index (preload);
368 pn_update_kit(game_info, (_this->CAppMenu_data).pregame_load_result == 3, kit_index);
369 pn_gi_apply_premade_kit(game_info, (_this->CAppMenu_data).pregame_load_result == 3, kit_index);
370
371
372 uiAPI.SFStringDeepCopy(&_this->CAppMenu_data.pregrame_dotmap_string, &dot_map);
373
374 SF_String avatar_name;
375 SF_String extra;
376 uiAPI.SFStringConstructor_char(&extra, "");
377 pn_preload_get_avatar_name(preload, &avatar_name);
378
379 CreateMenuPreMulti(_this, 0, 0, 6, 0, 0, 2, 6942, &extra, &avatar_name);
380
381 uiAPI.SFStringDestructor(&extra);
382 uiAPI.SFStringDestructor(&avatar_name);
383 break;
384 }
385 case 6:
386 {
387 SF_String save_path; /* local_210 */
388
389 build_load_path(_this, preload, &save_path);
390
391 pn_gi_set_save_file_path(game_info, &save_path);
392
393 {
394 SF_String empty; /* local_220 */
395 uiAPI.SFStringConstructor(&empty);
396
397 s_start_game(_this, game_info, 100, 0, 0, 0, &empty);
398
399 uiAPI.SFStringDestructor(&empty);
400 }
401
402 uiAPI.SFStringDestructor(&save_path);
403 break;
404 }
405 default:
406 goto skip_name_lookup;
407 break;
408 }
409
410 SF_String avatar_name;
411 nm = pn_preload_get_avatar_name(preload, &avatar_name);
412 store_last_played = (nm->str_length == 0) ? 0 : 1;
413 uiAPI.SFStringDestructor(&avatar_name);
414
415skip_name_lookup:
416 if (store_last_played != 0)
417 {
418 SF_String empty;
419 SF_String name;
420
421 int ct = (_this->CAppMenu_data).campaign_type;
422
423 char key_buf[64];
424 if (ct == 1)
425 strncpy(key_buf, "LastPlayedAddon", sizeof(key_buf));
426 else if (ct == 2)
427 strncpy(key_buf, "LastPlayedAddOn", sizeof(key_buf));
428 else if (game_info->is_coop == 1)
429 strncpy(key_buf, "LastPlayedFree", sizeof(key_buf));
430 else
431 strncpy(key_buf, "LastPlayed", sizeof(key_buf));
432 key_buf[sizeof(key_buf) - 1] = '\0';
433
434 uiAPI.SFStringConstructor_char(&empty, "");
435 pn_preload_get_avatar_name(preload, &name);
436
437 char stored_buf[32];
438 strncpy(stored_buf, "Stored", sizeof(stored_buf));
439 stored_buf[sizeof(stored_buf) - 1] = '\0';
440 pn_cfg_set_string(&configFile, stored_buf, key_buf, &name, &empty);
441 uiAPI.SFStringDestructor(&name);
442 uiAPI.SFStringDestructor(&empty);
443 }
444
445 uiAPI.SFStringDestructor(&configFile.name_maybe);
446 uiAPI.SFStringDestructor(&dot_map);
447 pn_cfg_dtor(&configFile);
448}
449
450void install_preparenewgame_hook()
451{
452 ASI::MemoryRegion mreg(ASI::AddrOf(0x195e10), 5);
453 ASI::BeginRewrite(mreg);
454 *(unsigned char *)(ASI::AddrOf(0x195e10)) = 0xE9;
455 *(int *)(ASI::AddrOf(0x195e11)) = (int)(&hooked_prepare_new_game) - (int)(ASI::AddrOf(0x195e15));
456 ASI::EndRewrite(mreg);
457}
458
CreateMnuHintExt_ptr CreateMnuHintExt
CreateMenuPreMulti_ptr CreateMenuPreMulti
SF_String *__thiscall getSavePath(CAppSession *_this, SF_String *output, uint32_t campaign_type)
importFromSave_ptr importFromSave
uint8_t __thiscall pn_preload_get_skip_tutorial(CUiMenuPreLoad *_this)
void __thiscall hooked_prepare_new_game(CAppMenu *_this, CUiMenuPreLoad *preload)
startGame_ptr s_start_game
void initialize_preparenewgame_rewrite()
void __thiscall initFirstMap(SF_GameInfo *_this, uint32_t skip_tutorial, uint8_t skill, uint8_t subskill, uint32_t campaign_id, bool is_shadowblade)
Proper map selection code for the future.
playCampaignIntro_ptr s_play_campaign_intro
SF_String * build_load_path(CAppMenu *_this, void *preload, SF_String *out)
UiFunctions uiAPI
Definition sf_hooks.c:50
int AddrOf(int offset)
returns "real" virtual address of given memory offset
Definition sf_asi.h:135
bool BeginRewrite(MemoryRegion &mem_region)
allows rewriting code in a given memory region by overwriting permissions for that memory region
Definition sf_asi.cpp:6
bool EndRewrite(MemoryRegion &mem_region)
ends rewriting by restoring old permissions in a given memory region
Definition sf_asi.cpp:14
void(__thiscall * InitUnknownAvatar_0x54_ptr)(void *_this)
void(__thiscall * CreateMenuPreMulti_ptr)(CAppMenu *_this, uint32_t param_1, uint32_t param_2, uint32_t param_3, uint32_t param_4, uint32_t param_5, uint32_t param_6, uint16_t param_7, SF_String *param_8, SF_String *param_9)
void(__thiscall * giVoid_ptr)(SF_GameInfo *gi)
void(__thiscall * CreateMnuHintExt_ptr)(CAppMenu *_this)
SF_String *(__thiscall * preloadGetStr_ptr)(void *preload, SF_String *out)
void(__thiscall * preloadUpdateKit2_ptr)(SF_GameInfo *_this, uint32_t unknown, uint8_t kit)
CMnuScreen *(__thiscall * getPregameScreen_ptr)(CMnuScreen *_this)
void(__thiscall * appMenuReadSave_ptr)(CAppMenu *m, SF_String *s)
void(__thiscall * giStarterKitReset_ptr)(SF_GameInfo *gi, uint32_t skill, uint32_t subskill)
uint8_t(__thiscall * gameInfoGetU8_ptr)(SF_GameInfo *gi)
uint8_t(__thiscall * preloadGetU8_ptr)(void *preload)
uint8_t(__thiscall * updatePreloadUnknown_0x54_ptr)(CUiMenuPreLoad *_this, void *param1)
void *(__thiscall * cfgCtor_ptr)(CUtlConfigFile *cfg, const char *p)
void(__thiscall * giSetBoolU8_ptr)(SF_GameInfo *gi, uint32_t b, uint8_t i)
void(__thiscall * preloadUpdateKit_ptr)(SF_GameInfo *_this, uint8_t unknown, uint8_t kit)
uint8_t(__thiscall * screenDeleteControl_ptr)(CMnuScreen *screen, SF_String *ctl)
GdAvatarData *(__thiscall * preloadGetAvatar_ptr)(void *preload, void *out)
SF_String *(__thiscall * giSetTemplateName_ptr)(SF_GameInfo *gi, SF_String *s)
uint8_t(__thiscall * gameInfoFigureAbilities_ptr)(SF_GameInfo *gi, uint32_t param_2)
uint32_t(__thiscall * preloadGetResultCode_ptr)(void *preload)
uint32_t(__thiscall * importFromSave_ptr)(CAppMenu *_this, void *param_1, GdAvatarInternal *param_2)
SF_String *(__thiscall * getScreenName_ptr)(CMnuScreen *_this)
void(__thiscall * screenSetActive_ptr)(CMnuScreen *screen, CMnuScreen *v)
void(__thiscall * cfgDtor_ptr)(CUtlConfigFile *cfg)
void(__thiscall * cfgSetString_ptr)(CUtlConfigFile *cfg, char *section, char *key, SF_String *value, SF_String *dflt)
void(__thiscall * giSetStr_ptr)(SF_GameInfo *gi, SF_String *s)
void(__thiscall * giSetU32_ptr)(SF_GameInfo *gi, uint32_t v)
void(__thiscall * gameInfoReset_ptr)(SF_GameInfo *gi, uint32_t p1)
GdAvatarInternal *(__thiscall * InitAvatarInternal_ptr)(void *buffer)
void(__thiscall * gameInfoSetAvatar_ptr)(SF_GameInfo *gi, void *avatar, uint16_t first_elem_u16)
uint32_t(__thiscall * preloadGetU32_ptr)(void *preload)
MemoryRegion is used for rewriting code in a given memory block.
Definition sf_asi.h:17
GdAvatarData avatarData
CAppSession * CAppSession
CAppMenu_data CAppMenu_data
CUiMenuPreLoad_data CUiMenuPreLoad_data
GdAvatarInternal internal