|
3 | 3 |
|
4 | 4 | namespace hyper |
5 | 5 | { |
| 6 | + __declspec(naked) void detour_setup_topology_and_scenery() |
| 7 | + { |
| 8 | + __asm |
| 9 | + { |
| 10 | + // [esp + 0x00] is 'return address' |
| 11 | + |
| 12 | + // esp is auto-managed, non-incremental |
| 13 | + // ebp is auto-managed, restored on function return |
| 14 | + |
| 15 | + push eax; // 'return address' is now at [esp + 0x04] |
| 16 | + push ebx; // 'return address' is now at [esp + 0x08] |
| 17 | + push ecx; // 'return address' is now at [esp + 0x0C] |
| 18 | + push edx; // 'return address' is now at [esp + 0x10] |
| 19 | + push esi; // 'return address' is now at [esp + 0x14] |
| 20 | + push edi; // 'return address' is now at [esp + 0x18] |
| 21 | + |
| 22 | + call world::init_topology_and_scenery_groups; // call custom init_topology_and_scenery_groups |
| 23 | + |
| 24 | + pop edi; // restore saved register |
| 25 | + pop esi; // restore saved register |
| 26 | + pop edx; // restore saved register |
| 27 | + pop ecx; // restore saved register |
| 28 | + pop ebx; // restore saved register |
| 29 | + pop eax; // restore saved register |
| 30 | + |
| 31 | + retn; // return immediately to caller function, not back to SetupTopologyAndScenery |
| 32 | + } |
| 33 | + } |
| 34 | + |
| 35 | + __declspec(naked) void detour_init_topology_and_scenery_groups() |
| 36 | + { |
| 37 | + __asm |
| 38 | + { |
| 39 | + // [esp + 0x00] is 'return address' |
| 40 | + |
| 41 | + // esp is auto-managed, non-incremental |
| 42 | + // ebp is auto-managed, restored on function return |
| 43 | + |
| 44 | + push eax; // 'return address' is now at [esp + 0x04] |
| 45 | + push ebx; // 'return address' is now at [esp + 0x08] |
| 46 | + push ecx; // 'return address' is now at [esp + 0x0C] |
| 47 | + push edx; // 'return address' is now at [esp + 0x10] |
| 48 | + push esi; // 'return address' is now at [esp + 0x14] |
| 49 | + push edi; // 'return address' is now at [esp + 0x18] |
| 50 | + |
| 51 | + call world::init_topology_and_scenery_groups; // call custom init_topology_and_scenery_groups |
| 52 | + |
| 53 | + pop edi; // restore saved register |
| 54 | + pop esi; // restore saved register |
| 55 | + pop edx; // restore saved register |
| 56 | + pop ecx; // restore saved register |
| 57 | + pop ebx; // restore saved register |
| 58 | + pop eax; // restore saved register |
| 59 | + |
| 60 | + retn; // return immediately to caller function, not back to InitTopologyAndSceneryGroups |
| 61 | + } |
| 62 | + } |
| 63 | + |
6 | 64 | __declspec(naked) void detour_redo_topology_and_scenery_groups() |
7 | 65 | { |
8 | 66 | __asm |
@@ -34,6 +92,12 @@ namespace hyper |
34 | 92 |
|
35 | 93 | void world_patches::init() |
36 | 94 | { |
| 95 | + // SetupTopologyAndScenery |
| 96 | + hook::jump(0x007990A0, &detour_setup_topology_and_scenery); |
| 97 | + |
| 98 | + // InitTopologyAndSceneryGroups |
| 99 | + hook::jump(0x006A8A80, &detour_init_topology_and_scenery_groups); |
| 100 | + |
37 | 101 | // RedoTopologyAndSceneryGroups |
38 | 102 | hook::jump(0x006A8AD0, &detour_redo_topology_and_scenery_groups); |
39 | 103 | } |
|
0 commit comments