Skip to content

Commit 2ea0085

Browse files
Enderclem0enderclemclaude
authored
Add draw Lua bindings + raise static GPU buffer pool sizes (#31)
* Raise static GPU buffer pool sizes (configurable) Adds two user-configurable pool-size patches applied at DLL attach: "Pool Sizes" / "Static Vertex Pool (MB)" default 128 (game: 64) "Pool Sizes" / "Static Index Pool (MB)" default 64 (game: 32) Both bound via big::config::general->bind(...) so users can tune them from the H2M config UI. Applied at my_main() time, so changes require a game restart to take effect. The patches rewrite the `mov qword [rsp+X], imm32` instructions that push the pool-size argument in sgg::addShaderEffect (vertex pool, per shader effect) and sgg::addStaticVertexBuffers (index pool, single global). Writing the full imm32 (not just the high byte) lets any size up to 2 GB be set from config; the operand is sign-extended to 64 bits by the mov. Both pools live in the DX12 upload heap (system RAM, not VRAM), so the extra capacity costs system memory only. Default values were picked to be generous without being wasteful; users with many mods installed can raise further in the UI. Each patch logs [OK ] or [SKIP] at attach with the reason: SKIP if the configured value matches the game default (no-op) SKIP if the configured value is below the game default (refused) SKIP if the scan pattern didn't match (game update?) SKIP if the expected imm32 isn't at the site (game update?) OK on successful write, with from->to MB shown This surfaces post-game-update regressions immediately instead of letting mods silently degrade. Without these patches, mods that add many character mesh entries overflow the default budgets and later-loaded meshes (weapons, enemies) fall back to the placeholder "blank mesh" prop. * Add draw-path hooks + rom.data.set_draw_visible + rom.data.dump_pool_stats Creates src/lua_extensions/bindings/hades/draw.cpp under the lua::hades::draw namespace. The file holds: - Detour hooks on DoDraw3D / DoDrawShadow3D / DoDraw3DThumbnail (all three share the PDB signature `static void(const vector<RenderMesh*>&, uint, int, HashGuid)`). - A code cave for DoDrawShadowCast3D (different signature, no HashGuid parameter). All four hooks check a shared hidden-set and skip the draw iteration when the entry's name hash is in it. - SEH-protected pointer-read helpers used by later bindings that walk the game's mModelData hash-bucket structure. New Lua bindings: rom.data.set_draw_visible(entry_name, visible) Entry-level visibility gate. Instant toggle, no mModelData mutation. State: one static std::unordered_set<uint32_t> guarded by a single std::shared_mutex. rom.data.dump_pool_stats() Diagnostic companion to the static-pool-size patches from the previous commit. Walks sgg::gStaticDrawBuffers + the single sgg::gStaticIndexBuffers and logs each pool's cursor and capacity, plus an estimated %-used at 40 B/vert (the character- mesh stride). * Add rom.data.set_mesh_visible — per-mesh visibility inside an entry set_draw_visible (previous commit) hides an entire entry — useful for whole-character toggles but too coarse when a mod merged a new mesh into a stock entry and wants to hide just that one mesh without hiding the body. set_mesh_visible walks the entry's GrannyMeshData vector, finds the target mesh by name hash, and flips its mesh_type byte (GMD+0x4C) between its original value and 2 (shadow). DoDraw3D's per-mesh switch treats type 2 as "skip to next iteration", so no cmdDrawIndexed fires for that mesh while other meshes in the same entry continue to render. The binding saves the original mesh_type on first hide so a later show-call can restore the precise value rather than blindly writing 0 (some meshes ship with type=1 for outline, etc.). The saved state lives in a function-scope std::map keyed by (entry_hash, mesh_hash, mesh_index) guarded by its own mutex. * Add variant-switching Lua APIs: swap_to_variant, restore_stock, populate_entry_textures Extends draw.cpp with three bindings that redirect a stock entry's draw calls to a variant entry — outfit switching without reload. rom.data.swap_to_variant(stock_entry, variant_entry) Pre-populates the variant's texture handles via sgg::GameAssetManager::GetTexture (mirrors what ModelAnimation::PrepDraw does for the stock entry) then installs a hash remap so hook_DoDraw3D reads the variant's GrannyMeshData whenever a draw command queues the stock entry. rom.data.restore_stock(stock_entry) Removes the remap entry for the stock hash. rom.data.populate_entry_textures(entry_name) Standalone version of the texture pre-populate step, for callers who want to resolve an entry's textures without installing a remap (e.g. warming up variants at startup). State: one std::unordered_map<uint32_t, uint32_t> guarded by the file's shared mutex. hook_DoDraw3D learns to consult this map before the hidden-set check and rewrite the draw command's hash in-place when a remap exists; the hash is read under a shared lock and the map is written under unique lock. check_draw_entry (used by the shadow-cast code cave) gains a matching remap branch and now returns 2 + *out_hash to the cave when a remap applies. Shadow and thumbnail paths continue to honour only the hidden-set — remapping them while ShadowCast stays on stock (its signature has no HashGuid, so it can't participate cleanly) produces inconsistent per-entry state that wedges the render thread. The main DoDraw3D swap carries the visual change on its own. Header doc comment extended to list the new bindings. * Review pass: structs, shared helpers, draw_ prefix, cleanups Addresses the review feedback on PR #31 in one commit. Game structs with static_assert offsets --------------------------------------- - ModelDataHashTable / ModelDataNode / GrannyMeshData: partial layouts covering exactly the fields we touch; unnamed regions stay `char pad[]` so sizeof + offsetof match the engine. - ForgeBuffer / ForgeGeometryBuffers / EastlVector<T>: same treatment for draw_dump_pool_stats' ForgeRenderer reads. - Every scattered `mdata + 0x08` / `node + 0x10` / `gmd + 0x4C` style read is now struct field access. Shared hashtable walker ----------------------- - `find_model_data_node(entry_hash)` replaces the EASTL mix + bucket walk that populate_entry_textures, set_mesh_visible, and swap_to_variant each inlined separately. - `get_entry_meshes(node, ...)` factors out the vector-range resolve. - Named the mixing constants (kEastlHashMix1/2) and annotated the multiply-xor-shift finalizer pattern they come from. - `0x50` is now `sizeof(GrannyMeshData)`, the `0x7feb352d` / `0x846ca68b` and `128` / `32` / `0x100000` bounds are named. LUA_DOC blocks -------------- - Trimmed engine-internal prose out of every binding's LUA_DOC block (set_mesh_visible's GMD hash flip, swap_to_variant's PrepDraw reasoning, populate_entry_textures' walk explanation, dump_pool_stats' +0x38 / +0x40 layout). The RE notes live inline in the function body where they matter. - Dropped the top-of-file @file doxygen block entirely. If a binding ever needs a "why this exists" comment it goes right above that binding. Type-safe return ---------------- - check_draw_entry now returns `enum class DrawEntryDecision : int { PassThrough = 0, Hidden = 1, Remapped = 2 }`. Backing type and numeric values are preserved because the manual code cave compares the returned eax against 1 and 2 directly. Lua naming ---------- - All new rom.data.* draw bindings prefixed with draw_: set_draw_visible -> draw_set_visible set_mesh_visible -> draw_set_mesh_visible swap_to_variant -> draw_swap_to_variant restore_stock -> draw_restore_stock populate_entry_textures -> draw_populate_entry_textures dump_pool_stats -> draw_dump_pool_stats User-facing messages -------------------- - draw_set_visible's "hash=0" warning now names the two concrete causes (engine hash table not yet populated, or the entry name isn't registered) and tells the user what to do. - draw_set_visible's LUA_DOC one-liner trimmed to "Takes effect immediately." per reviewer preference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: enderclem <enderclem@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 26512ed commit 2ea0085

5 files changed

Lines changed: 914 additions & 0 deletions

File tree

src/lua_extensions/bindings/hades/data.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <lua_extensions/lua_manager_extension.hpp>
99
#include <lua_extensions/lua_module_ext.hpp>
1010
#include <memory/gm_address.hpp>
11+
#include <mutex>
1112
#include <string/string.hpp>
1213

1314
namespace sgg

0 commit comments

Comments
 (0)