From 4fda8c869f6f5912d4c4607f8f4f051f8cdfa861 Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Fri, 10 Nov 2023 09:41:36 -0800 Subject: [PATCH 1/7] ahhhhhbomination --- src/hyperlib/version.hpp | 2 +- src/hyperlinked/dllmain.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hyperlib/version.hpp b/src/hyperlib/version.hpp index 8ba4bf9..e4899fd 100644 --- a/src/hyperlib/version.hpp +++ b/src/hyperlib/version.hpp @@ -1 +1 @@ -#define __VERSION__ 64 +#define __VERSION__ 67 diff --git a/src/hyperlinked/dllmain.cpp b/src/hyperlinked/dllmain.cpp index cf1c237..bd6ab28 100644 --- a/src/hyperlinked/dllmain.cpp +++ b/src/hyperlinked/dllmain.cpp @@ -8,8 +8,10 @@ #pragma warning (disable : 6031) -#undef CONSOLEON -#undef RUN_TESTS +#ifndef ABOMINATOR +#define CONSOLEON +#define RUN_TESTS +#endif #if defined(RUN_TESTS) #include From 3be21a945d3c8ac6d865c91075a5f6ec6eaae4c2 Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Fri, 10 Nov 2023 09:56:10 -0800 Subject: [PATCH 2/7] render state init --- src/hyperlib/assets/textures.cpp | 44 +++++++++++--------- src/hyperlib/version.hpp | 2 +- src/hyperlinked/patches.cpp | 2 + src/hyperlinked/patches/assets/textures.cpp | 46 +++++++++++++++++++++ src/hyperlinked/patches/assets/textures.hpp | 10 +++++ 5 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 src/hyperlinked/patches/assets/textures.cpp create mode 100644 src/hyperlinked/patches/assets/textures.hpp diff --git a/src/hyperlib/assets/textures.cpp b/src/hyperlib/assets/textures.cpp index 030368b..d4a02fb 100644 --- a/src/hyperlib/assets/textures.cpp +++ b/src/hyperlib/assets/textures.cpp @@ -26,43 +26,43 @@ namespace hyper switch (texture->blend_type) { case texture::alpha_blend_type::blend: - this->alpha_blend_src = D3DBLEND_SRCALPHA; - this->alpha_blend_dest = D3DBLEND_INVSRCALPHA; + this->alpha_blend_src = ::D3DBLEND_SRCALPHA; + this->alpha_blend_dest = ::D3DBLEND_INVSRCALPHA; break; case texture::alpha_blend_type::additive: - this->alpha_blend_src = D3DBLEND_SRCALPHA; - this->alpha_blend_dest = D3DBLEND_ONE; + this->alpha_blend_src = ::D3DBLEND_SRCALPHA; + this->alpha_blend_dest = ::D3DBLEND_ONE; this->is_additive_blend = true; this->colour_write_alpha = true; break; case texture::alpha_blend_type::subtractive: - this->alpha_blend_src = D3DBLEND_ZERO; - this->alpha_blend_dest = D3DBLEND_INVSRCCOLOR; + this->alpha_blend_src = ::D3DBLEND_ZERO; + this->alpha_blend_dest = ::D3DBLEND_INVSRCCOLOR; break; case texture::alpha_blend_type::overbright: - this->alpha_blend_src = D3DBLEND_SRCALPHA; - this->alpha_blend_dest = D3DBLEND_INVSRCALPHA; + this->alpha_blend_src = ::D3DBLEND_SRCALPHA; + this->alpha_blend_dest = ::D3DBLEND_INVSRCALPHA; break; case texture::alpha_blend_type::dest_blend: - this->alpha_blend_src = D3DBLEND_DESTALPHA; - this->alpha_blend_dest = D3DBLEND_INVDESTALPHA; + this->alpha_blend_src = ::D3DBLEND_DESTALPHA; + this->alpha_blend_dest = ::D3DBLEND_INVDESTALPHA; break; case texture::alpha_blend_type::dest_additive: - this->alpha_blend_src = D3DBLEND_DESTALPHA; - this->alpha_blend_dest = D3DBLEND_ONE; + this->alpha_blend_src = ::D3DBLEND_DESTALPHA; + this->alpha_blend_dest = ::D3DBLEND_ONE; break; } } else { this->z_write_enabled = true; - this->alpha_blend_src = D3DBLEND_ONE; - this->alpha_blend_dest = D3DBLEND_ZERO; + this->alpha_blend_src = ::D3DBLEND_ONE; + this->alpha_blend_dest = ::D3DBLEND_ZERO; if (!this->alpha_test_enabled && (texture->flags & texture::bit_flags::disable_culling) != texture::bit_flags::disable_culling) { @@ -72,24 +72,28 @@ namespace hyper if ((texture->tilable_uv & texture::tileable_type::u_mirror) == texture::tileable_type::u_mirror) { - this->texture_address_u = D3DTADDRESS_MIRROR; + this->texture_address_u = ::D3DTADDRESS_MIRROR; } else { - this->texture_address_u = (texture->tilable_uv & texture::tileable_type::u_repeat) == texture::tileable_type::u_repeat ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP; + this->texture_address_u = (texture->tilable_uv & texture::tileable_type::u_repeat) == texture::tileable_type::u_repeat + ? ::D3DTADDRESS_WRAP + : ::D3DTADDRESS_CLAMP; } if ((texture->tilable_uv & texture::tileable_type::v_mirror) == texture::tileable_type::v_mirror) { - this->texture_address_v = D3DTADDRESS_MIRROR; + this->texture_address_v = ::D3DTADDRESS_MIRROR; } else { - this->texture_address_v = (texture->tilable_uv & texture::tileable_type::v_repeat) == texture::tileable_type::v_repeat ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP; + this->texture_address_v = (texture->tilable_uv & texture::tileable_type::v_repeat) == texture::tileable_type::v_repeat + ? ::D3DTADDRESS_WRAP + : ::D3DTADDRESS_CLAMP; } this->bias_level = texture->bias_level & 3; - this->alpha_test_ref = 11u; // #TODO + this->alpha_test_ref = 11u; // #TODO ? if (class_key == hashing::bin_const("Tree Leaves") || class_key == hashing::bin_const("Tree Cards") || class_key == hashing::bin_const("MultiPass Blend")) { @@ -99,7 +103,7 @@ namespace hyper bool is_barrier = class_key == hashing::bin_const("Barrier Mask") #if defined(CHECK_BARRIER_STRINGS) - || ::strncmp(reinterpret_cast(texture->name), "SFX_TRACKBARRIER", 16u) + || !::strncmp(reinterpret_cast(texture->name), "SFX_TRACKBARRIER", 16u) #endif ; diff --git a/src/hyperlib/version.hpp b/src/hyperlib/version.hpp index 3ace722..75068ae 100644 --- a/src/hyperlib/version.hpp +++ b/src/hyperlib/version.hpp @@ -1 +1 @@ -#define __VERSION__ 54 +#define __VERSION__ 55 diff --git a/src/hyperlinked/patches.cpp b/src/hyperlinked/patches.cpp index 1e6aea3..72dc2d1 100644 --- a/src/hyperlinked/patches.cpp +++ b/src/hyperlinked/patches.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ namespace hyper loader_patches::init(); scenery_patches::init(); + texture_patches::init(); world_anim_patches::init(); camera_patches::init(); diff --git a/src/hyperlinked/patches/assets/textures.cpp b/src/hyperlinked/patches/assets/textures.cpp new file mode 100644 index 0000000..e008608 --- /dev/null +++ b/src/hyperlinked/patches/assets/textures.cpp @@ -0,0 +1,46 @@ +#include +#include + +namespace hyper +{ + __declspec(naked) void detour_render_state_init() + { + __asm + { + // [esp + 0x00] is 'return address' + // [esp + 0x04] is 'texture' + // ecx contains pointer to texture::render_state + + // esp is auto-managed, non-incremental + // ebp is auto-managed, restored on function return + + push eax; // 'texture' is now at [esp + 0x08] + push ebx; // 'texture' is now at [esp + 0x0C] + push ecx; // 'texture' is now at [esp + 0x10] + push edx; // 'texture' is now at [esp + 0x14] + push esi; // 'texture' is now at [esp + 0x18] + push edi; // 'texture' is now at [esp + 0x1C] + + push [esp + 0x1C]; // repush 'texture' + + call texture::render_state::initialize; // call custom initialize + + // no need to restore esp since 'initialize' is a __thiscall + + pop edi; // restore saved register + pop esi; // restore saved register + pop edx; // restore saved register + pop ecx; // restore saved register + pop ebx; // restore saved register + pop eax; // restore saved register + + retn 4; // return immediately to caller function, not back to RenderState::Init; note that this is a __thiscall + } + } + + void texture_patches::init() + { + // RenderState::Init + hook::jump(0x0073B9E0, &detour_render_state_init); + } +} diff --git a/src/hyperlinked/patches/assets/textures.hpp b/src/hyperlinked/patches/assets/textures.hpp new file mode 100644 index 0000000..e0e7260 --- /dev/null +++ b/src/hyperlinked/patches/assets/textures.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace hyper +{ + class texture_patches final + { + public: + static void init(); + }; +} From 710204b4f45f30fb9a15bc288e3aadc2fbc18644 Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Fri, 10 Nov 2023 10:09:38 -0800 Subject: [PATCH 3/7] vers --- src/hyperlib/version.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hyperlib/version.hpp b/src/hyperlib/version.hpp index e4899fd..0e84fee 100644 --- a/src/hyperlib/version.hpp +++ b/src/hyperlib/version.hpp @@ -1 +1 @@ -#define __VERSION__ 67 +#define __VERSION__ 70 From 6ede831cac156c2a617074db7153fe9affe9e7df Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Sat, 11 Nov 2023 09:07:32 -0800 Subject: [PATCH 4/7] flare pool expand --- src/hyperlib/renderer/flare_pool.cpp | 2 +- src/hyperlinked/dllmain.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hyperlib/renderer/flare_pool.cpp b/src/hyperlib/renderer/flare_pool.cpp index 9633089..7992f78 100644 --- a/src/hyperlib/renderer/flare_pool.cpp +++ b/src/hyperlib/renderer/flare_pool.cpp @@ -117,7 +117,7 @@ namespace hyper void flare_pool::ctor(flare_pool* pool) { - new (pool) flare_pool(0x80u); // by default, flare pool is initialized to 0x80 flares + new (pool) flare_pool(0x200u); } void flare_pool::dtor(flare_pool* pool) diff --git a/src/hyperlinked/dllmain.cpp b/src/hyperlinked/dllmain.cpp index bd6ab28..1a5c32e 100644 --- a/src/hyperlinked/dllmain.cpp +++ b/src/hyperlinked/dllmain.cpp @@ -8,7 +8,7 @@ #pragma warning (disable : 6031) -#ifndef ABOMINATOR +#if defined(_DEBUG) && !defined(ABOMINATOR) #define CONSOLEON #define RUN_TESTS #endif From 44b5185c3eaf2a7a699e38a67411e1af0f78b148 Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Sat, 11 Nov 2023 10:32:15 -0800 Subject: [PATCH 5/7] redo topologia grouppe --- src/hyperlib/streamer/sections.cpp | 22 +++++++++++++ src/hyperlib/streamer/sections.hpp | 6 ++++ src/hyperlib/streamer/track_path.cpp | 13 ++++++++ src/hyperlib/streamer/track_path.hpp | 4 +++ src/hyperlib/version.hpp | 2 +- src/hyperlib/world/world.cpp | 44 +++++++++++++++++++++++++ src/hyperlib/world/world.hpp | 6 ++++ src/hyperlinked/dllmain.cpp | 2 ++ src/hyperlinked/patches.cpp | 2 ++ src/hyperlinked/patches/world/world.cpp | 40 ++++++++++++++++++++++ src/hyperlinked/patches/world/world.hpp | 10 ++++++ 11 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 src/hyperlinked/patches/world/world.cpp create mode 100644 src/hyperlinked/patches/world/world.hpp diff --git a/src/hyperlib/streamer/sections.cpp b/src/hyperlib/streamer/sections.cpp index 284248c..923d193 100644 --- a/src/hyperlib/streamer/sections.cpp +++ b/src/hyperlib/streamer/sections.cpp @@ -306,6 +306,11 @@ namespace hyper } } + void visible_section::manager::disable_all_groups() + { + ::memset(this->enabled_groups, 0, sizeof(this->enabled_groups)); + } + bool visible_section::manager::loader(chunk* block) { if (block->id() == block_id::visible_section_manager) @@ -480,4 +485,21 @@ namespace hyper return extra_width; } + + auto visible_section::manager::get_group_info(const char* group_name) -> const group_info* + { + size_t length = string::length(group_name); + + for (size_t i = 0u; i < visible_section::manager::group_info_table.length(); ++i) + { + const group_info& info = visible_section::manager::group_info_table[i]; + + if (string::length(info.selection_set_name) == length && !::_strnicmp(info.selection_set_name, group_name, length)) + { + return &info; + } + } + + return nullptr; + } } diff --git a/src/hyperlib/streamer/sections.hpp b/src/hyperlib/streamer/sections.hpp index 9d71f2a..053b6d6 100644 --- a/src/hyperlib/streamer/sections.hpp +++ b/src/hyperlib/streamer/sections.hpp @@ -286,6 +286,8 @@ namespace hyper void disable_group(std::uint32_t key); + void disable_all_groups(); + bool loader(chunk* block); bool unloader(chunk* block); @@ -298,6 +300,8 @@ namespace hyper public: static auto get_distance_outside(const boundary* bound, const vector2& position, float extra_width) -> float; + static auto get_group_info(const char* group_name) -> const group_info*; + public: linked_list drivable_boundary_list; linked_list non_drivable_boundary_list; @@ -335,6 +339,8 @@ namespace hyper static inline std::uint32_t& current_zone_number = *reinterpret_cast(0x00A71C1C); static inline geometry::model*& zone_boundary_model = *reinterpret_cast(0x00B69BE8); + + static inline array group_info_table = array(0x00A72C30); }; }; diff --git a/src/hyperlib/streamer/track_path.cpp b/src/hyperlib/streamer/track_path.cpp index 01a41ff..b9c80e7 100644 --- a/src/hyperlib/streamer/track_path.cpp +++ b/src/hyperlib/streamer/track_path.cpp @@ -2,6 +2,19 @@ namespace hyper { + void track_path::manager::disable_all_barriers() + { + for (std::uint32_t i = 0u; i < this->barrier_count; ++i) + { + this->barriers[i].enabled = false; + } + } + + void track_path::manager::enable_barriers(const char* barrier_name) + { + call_function(0x007A2390)(this, barrier_name); + } + auto track_path::manager::find_zone(const vector2* position, zone::type type, const zone* prev) -> zone* { if (position == nullptr) diff --git a/src/hyperlib/streamer/track_path.hpp b/src/hyperlib/streamer/track_path.hpp index 40c7b10..cc6f94c 100644 --- a/src/hyperlib/streamer/track_path.hpp +++ b/src/hyperlib/streamer/track_path.hpp @@ -76,6 +76,10 @@ namespace hyper struct manager { public: + void disable_all_barriers(); + + void enable_barriers(const char* barrier_name); + auto find_zone(const vector2* position, zone::type type, const zone* prev) -> zone*; public: diff --git a/src/hyperlib/version.hpp b/src/hyperlib/version.hpp index 75068ae..7d7480d 100644 --- a/src/hyperlib/version.hpp +++ b/src/hyperlib/version.hpp @@ -1 +1 @@ -#define __VERSION__ 55 +#define __VERSION__ 56 diff --git a/src/hyperlib/world/world.cpp b/src/hyperlib/world/world.cpp index af19225..01bd399 100644 --- a/src/hyperlib/world/world.cpp +++ b/src/hyperlib/world/world.cpp @@ -1,3 +1,6 @@ +#include +#include +#include #include namespace hyper @@ -19,4 +22,45 @@ namespace hyper { call_function(0x007AF8F0)(); } + + void world::enable_barrier_scenery_group(const char* name, bool flip_artwork) + { + if (visible_section::manager::get_group_info(name) != nullptr) + { + std::uint32_t key = hashing::bin(name); + + visible_section::manager::instance.enable_group(key); + + scenery::group::enable(key, flip_artwork); + + track_path::manager::instance.enable_barriers(name); + } + } + + void world::disable_all_scenery_groups() + { + for (const scenery::group* i = scenery::group::list.begin(); i != scenery::group::list.end(); i = i->next()) + { + if (scenery::group::enabled_table[i->group_number]) + { + i->disable_rendering(); + + scenery::group::enabled_table[i->group_number] = 0; + } + } + } + + void world::redo_topology_and_scenery_groups() + { + track_path::manager::instance.disable_all_barriers(); + + visible_section::manager::instance.disable_all_groups(); + + world::disable_all_scenery_groups(); + + if (scenery::group::find(hashing::bin_const("SCENERY_GROUP_DOOR")) != nullptr) + { + world::enable_barrier_scenery_group("SCENERY_GROUP_DOOR", false); + } + } } diff --git a/src/hyperlib/world/world.hpp b/src/hyperlib/world/world.hpp index 148e9af..f93978b 100644 --- a/src/hyperlib/world/world.hpp +++ b/src/hyperlib/world/world.hpp @@ -13,5 +13,11 @@ namespace hyper static void init_visible_zones(geometry::model*& boundary_model); static void notify_sky_loader(); + + static void enable_barrier_scenery_group(const char* name, bool flip_artwork); + + static void disable_all_scenery_groups(); + + static void redo_topology_and_scenery_groups(); }; } diff --git a/src/hyperlinked/dllmain.cpp b/src/hyperlinked/dllmain.cpp index a0c6547..445da99 100644 --- a/src/hyperlinked/dllmain.cpp +++ b/src/hyperlinked/dllmain.cpp @@ -8,8 +8,10 @@ #pragma warning (disable : 6031) +#if defined(_DEBUG) #define CONSOLEON #define RUN_TESTS +#endif #if defined(RUN_TESTS) #include diff --git a/src/hyperlinked/patches.cpp b/src/hyperlinked/patches.cpp index 72dc2d1..df4751d 100644 --- a/src/hyperlinked/patches.cpp +++ b/src/hyperlinked/patches.cpp @@ -22,6 +22,7 @@ #include #include +#include namespace hyper { @@ -49,5 +50,6 @@ namespace hyper streamer_patches::init(); collision_patches::init(); + world_patches::init(); } } diff --git a/src/hyperlinked/patches/world/world.cpp b/src/hyperlinked/patches/world/world.cpp new file mode 100644 index 0000000..e06df47 --- /dev/null +++ b/src/hyperlinked/patches/world/world.cpp @@ -0,0 +1,40 @@ +#include +#include + +namespace hyper +{ + __declspec(naked) void detour_redo_topology_and_scenery_groups() + { + __asm + { + // [esp + 0x00] is 'return address' + + // esp is auto-managed, non-incremental + // ebp is auto-managed, restored on function return + + push eax; // 'return address' is now at [esp + 0x04] + push ebx; // 'return address' is now at [esp + 0x08] + push ecx; // 'return address' is now at [esp + 0x0C] + push edx; // 'return address' is now at [esp + 0x10] + push esi; // 'return address' is now at [esp + 0x14] + push edi; // 'return address' is now at [esp + 0x18] + + call world::redo_topology_and_scenery_groups; // call custom redo_topology_and_scenery_groups + + pop edi; // restore saved register + pop esi; // restore saved register + pop edx; // restore saved register + pop ecx; // restore saved register + pop ebx; // restore saved register + pop eax; // restore saved register + + retn; // return immediately to caller function, not back to RedoTopologyAndSceneryGroups + } + } + + void world_patches::init() + { + // RedoTopologyAndSceneryGroups + hook::jump(0x006A8AD0, &detour_redo_topology_and_scenery_groups); + } +} diff --git a/src/hyperlinked/patches/world/world.hpp b/src/hyperlinked/patches/world/world.hpp new file mode 100644 index 0000000..7dd818f --- /dev/null +++ b/src/hyperlinked/patches/world/world.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace hyper +{ + class world_patches final + { + public: + static void init(); + }; +} From f5cca4523f73d8100fbfcb3d8eeb1a4fb2b0caef Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Sat, 11 Nov 2023 11:51:15 -0800 Subject: [PATCH 6/7] permanent scenery groups --- .gitignore | 3 ++ src/hyperlib/streamer/sections.cpp | 4 +- src/hyperlib/version.hpp | 1 - src/hyperlib/world/world.cpp | 16 +++++-- src/hyperlib/world/world.hpp | 8 ++++ src/hyperlinked/patches/world/world.cpp | 64 +++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 6 deletions(-) delete mode 100644 src/hyperlib/version.hpp diff --git a/.gitignore b/.gitignore index aaaa588..e071d76 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,9 @@ nunit-*.xml [Rr]eleasePS/ dlldata.c +# Version Files +version.hpp + # Benchmark Results BenchmarkDotNet.Artifacts/ diff --git a/src/hyperlib/streamer/sections.cpp b/src/hyperlib/streamer/sections.cpp index 923d193..d860552 100644 --- a/src/hyperlib/streamer/sections.cpp +++ b/src/hyperlib/streamer/sections.cpp @@ -494,7 +494,9 @@ namespace hyper { const group_info& info = visible_section::manager::group_info_table[i]; - if (string::length(info.selection_set_name) == length && !::_strnicmp(info.selection_set_name, group_name, length)) + size_t namesz = string::length(info.selection_set_name); + + if (namesz <= length && !::_strnicmp(info.selection_set_name, group_name, namesz)) { return &info; } diff --git a/src/hyperlib/version.hpp b/src/hyperlib/version.hpp deleted file mode 100644 index 7d7480d..0000000 --- a/src/hyperlib/version.hpp +++ /dev/null @@ -1 +0,0 @@ -#define __VERSION__ 56 diff --git a/src/hyperlib/world/world.cpp b/src/hyperlib/world/world.cpp index 01bd399..0d46213 100644 --- a/src/hyperlib/world/world.cpp +++ b/src/hyperlib/world/world.cpp @@ -50,6 +50,17 @@ namespace hyper } } + void world::init_topology_and_scenery_groups() + { + for (const char* group : world::permanent_scenery_groups) + { + if (scenery::group::find(hashing::bin(group)) != nullptr) + { + world::enable_barrier_scenery_group(group, false); + } + } + } + void world::redo_topology_and_scenery_groups() { track_path::manager::instance.disable_all_barriers(); @@ -58,9 +69,6 @@ namespace hyper world::disable_all_scenery_groups(); - if (scenery::group::find(hashing::bin_const("SCENERY_GROUP_DOOR")) != nullptr) - { - world::enable_barrier_scenery_group("SCENERY_GROUP_DOOR", false); - } + world::init_topology_and_scenery_groups(); } } diff --git a/src/hyperlib/world/world.hpp b/src/hyperlib/world/world.hpp index f93978b..27bf1b0 100644 --- a/src/hyperlib/world/world.hpp +++ b/src/hyperlib/world/world.hpp @@ -18,6 +18,14 @@ namespace hyper static void disable_all_scenery_groups(); + static void init_topology_and_scenery_groups(); + static void redo_topology_and_scenery_groups(); + + private: + static inline const char* permanent_scenery_groups[] = + { + "SCENERY_GROUP_DOOR", + }; }; } diff --git a/src/hyperlinked/patches/world/world.cpp b/src/hyperlinked/patches/world/world.cpp index e06df47..4e064ad 100644 --- a/src/hyperlinked/patches/world/world.cpp +++ b/src/hyperlinked/patches/world/world.cpp @@ -3,6 +3,64 @@ namespace hyper { + __declspec(naked) void detour_setup_topology_and_scenery() + { + __asm + { + // [esp + 0x00] is 'return address' + + // esp is auto-managed, non-incremental + // ebp is auto-managed, restored on function return + + push eax; // 'return address' is now at [esp + 0x04] + push ebx; // 'return address' is now at [esp + 0x08] + push ecx; // 'return address' is now at [esp + 0x0C] + push edx; // 'return address' is now at [esp + 0x10] + push esi; // 'return address' is now at [esp + 0x14] + push edi; // 'return address' is now at [esp + 0x18] + + call world::init_topology_and_scenery_groups; // call custom init_topology_and_scenery_groups + + pop edi; // restore saved register + pop esi; // restore saved register + pop edx; // restore saved register + pop ecx; // restore saved register + pop ebx; // restore saved register + pop eax; // restore saved register + + retn; // return immediately to caller function, not back to SetupTopologyAndScenery + } + } + + __declspec(naked) void detour_init_topology_and_scenery_groups() + { + __asm + { + // [esp + 0x00] is 'return address' + + // esp is auto-managed, non-incremental + // ebp is auto-managed, restored on function return + + push eax; // 'return address' is now at [esp + 0x04] + push ebx; // 'return address' is now at [esp + 0x08] + push ecx; // 'return address' is now at [esp + 0x0C] + push edx; // 'return address' is now at [esp + 0x10] + push esi; // 'return address' is now at [esp + 0x14] + push edi; // 'return address' is now at [esp + 0x18] + + call world::init_topology_and_scenery_groups; // call custom init_topology_and_scenery_groups + + pop edi; // restore saved register + pop esi; // restore saved register + pop edx; // restore saved register + pop ecx; // restore saved register + pop ebx; // restore saved register + pop eax; // restore saved register + + retn; // return immediately to caller function, not back to InitTopologyAndSceneryGroups + } + } + __declspec(naked) void detour_redo_topology_and_scenery_groups() { __asm @@ -34,6 +92,12 @@ namespace hyper void world_patches::init() { + // SetupTopologyAndScenery + hook::jump(0x007990A0, &detour_setup_topology_and_scenery); + + // InitTopologyAndSceneryGroups + hook::jump(0x006A8A80, &detour_init_topology_and_scenery_groups); + // RedoTopologyAndSceneryGroups hook::jump(0x006A8AD0, &detour_redo_topology_and_scenery_groups); } From 2ad4669cb49578fd2cbb28bf401a14fab6be9bdf Mon Sep 17 00:00:00 2001 From: MaxHwoy Date: Sat, 11 Nov 2023 11:52:22 -0800 Subject: [PATCH 7/7] w2c scenery groups --- src/hyperlib/world/world.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hyperlib/world/world.hpp b/src/hyperlib/world/world.hpp index 27bf1b0..d29bceb 100644 --- a/src/hyperlib/world/world.hpp +++ b/src/hyperlib/world/world.hpp @@ -26,6 +26,8 @@ namespace hyper static inline const char* permanent_scenery_groups[] = { "SCENERY_GROUP_DOOR", + "SCENERY_GROUP_CHRISTMAS", + "SCENERY_GROUP_HALLOWEEN_DISABLE", }; }; }