Build RE baseline and initial Rust workspace

This commit is contained in:
Jan Petykiewicz 2026-04-02 23:11:15 -07:00
commit ffaf155ef0
39 changed files with 5974 additions and 8 deletions

2
.cargo/config.toml Normal file
View file

@ -0,0 +1,2 @@
[target.i686-pc-windows-gnu]
linker = "i686-w64-mingw32-gcc"

16
.gitignore vendored
View file

@ -1 +1,17 @@
/target /target
/.venv/
/.ghidra/
/ghidra_projects/
/rt3_wineprefix/
/rt3_wineprefix2/
/tools/py/__pycache__/
/.codex
/\ %s
*.gpr
*.rep
*.rzdb
*.rzproj
*.r2
*.dmp
*.core
*.tmp

230
Cargo.lock generated Normal file
View file

@ -0,0 +1,230 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "csv"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938"
dependencies = [
"csv-core",
"itoa",
"ryu",
"serde_core",
]
[[package]]
name = "csv-core"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782"
dependencies = [
"memchr",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "libc"
version = "0.2.184"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rrt-cli"
version = "0.1.0"
dependencies = [
"rrt-model",
"sha2",
]
[[package]]
name = "rrt-hook"
version = "0.1.0"
[[package]]
name = "rrt-model"
version = "0.1.0"
dependencies = [
"csv",
"serde",
"serde_json",
]
[[package]]
name = "ryu"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

View file

@ -1,6 +1,18 @@
[package] [workspace]
name = "rrt" members = [
version = "0.1.0" "crates/rrt-model",
edition = "2024" "crates/rrt-cli",
"crates/rrt-hook",
]
resolver = "3"
[dependencies] [workspace.package]
edition = "2024"
license = "MIT"
version = "0.1.0"
[workspace.dependencies]
csv = "1.4.0"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.145"
sha2 = "0.10.9"

View file

@ -3,9 +3,35 @@ Analysis and reimplementation of Railroad Tycoon 3
The old executable is at ./rt3_wineprefix/drive_c/rt3/RT3.exe The old executable is at ./rt3_wineprefix/drive_c/rt3/RT3.exe
Our task is to understand the executable's structure and build a function-by-function rewrite in Rust. Our first task is to understand the executable's high-level control loops and subsystem boundaries well
As we go, we will document the file formats and functions and write unit and integration tests. enough to choose good rewrite targets. As we go, we document evidence, keep a curated function map,
and stand up Rust tooling that can validate artifacts and later host replacement code.
We will build a dll which we can inject into the original exe, patching in individual functions as The long-term direction is still a DLL we can inject into the original executable, patching in
we build them out. individual functions as we build them out. The current implementation milestone is smaller: a
minimal PE32 Rust hook that can load into RT3 under Wine without changing behavior.
## Project Docs
Bootstrap design and workflow documents live in `docs/`.
- `docs/README.md`: handbook index and target hashes
- `docs/control-loop-atlas.md`: high-level loop and subsystem atlas
- `docs/setup-workstation.md`: toolchain baseline and local setup
- `docs/re-workflow.md`: repeatable reverse-engineering workflow
- `docs/function-map.md`: canonical function-map schema and conventions
The first committed exports for the canonical 1.06 executable live in `artifacts/exports/rt3-1.06/`.
## Rust Workspace
The Rust workspace is split into focused crates:
- `rrt-model`: shared types for addresses, function-map rows, and control-loop concepts
- `rrt-cli`: validation and repo-health checks for the reverse-engineering baseline
- `rrt-hook`: minimal Windows DLL scaffold that currently builds a `dinput8.dll` proxy for
low-risk in-process loading experiments under Wine
For the current runtime smoke test, run `tools/run_hook_smoke_test.sh`. It builds the PE32 proxy,
copies it into the local RT3 install, launches the game briefly under Wine with
`WINEDLLOVERRIDES=dinput8=n,b`, and expects `rrt_hook_attach.log` to appear.

View file

@ -0,0 +1,7 @@
query_address,function_address,name,size,calling_convention,signature,caller_count,callers,callee_count,callees,data_ref_count,data_refs,entry_excerpt
0x00595440,0x00595440,multiplayer_transport_init_selector_slot,100,cdecl,"fcn.00595440(int32_t arg_4h, int32_t arg_39ch, int32_t arg_59bh);",2,0x00593841@0x00593790:multiplayer_transport_handle_names_query_response; 0x00593b25@0x00593b00:multiplayer_transport_handle_selector_update_response,3,0x00595490->0x005951f0:multiplayer_transport_service_status_pump; 0x00595499->0x00596fc0:multiplayer_transport_submit_profile_key_query_bundle_default; 0x0059547f->0x005a18a0:string_copy_bounded_zerofill,1,0x0059544f->0x005c87a8," 595420: movl $0x89ffff98, %esp # imm = 0x89FFFF98 | 595425: movl $0x9a4, %esi # imm = 0x9A4 | 59542a: popl %edi | 59542b: popl %esi | 59542c: addl $0x190, %esp # imm = 0x190 | 595432: retl | 595433: nop | 595434: nop | 595435: nop | 595436: nop | 595437: nop | 595438: nop | 595439: nop | 59543a: nop | 59543b: nop | 59543c: nop | 59543d: nop | 59543e: nop | 59543f: nop | 595440: movl 0x4(%esp), %eax | 595444: testl %eax, %eax | 595446: pushl %ebp | 595447: pushl %esi | 595448: pushl %edi | 595449: movl %edx, %edi | 59544b: movl %ecx, %esi | 59544d: jne 0x595454 <.text+0x194454> | 59544f: movl $0x5c87a8, %eax # imm = 0x5C87A8 | 595454: movl %edi, %ecx | 595456: shll $0x9, %ecx | 595459: leal (%ecx,%esi), %ebp | 59545c: pushl $0x200 # imm = 0x200"
0x00596da0,0x00596da0,multiplayer_transport_submit_profile_key_query_bundle,497,cdecl,fcn.00596da0(uint_least32_t arg_4h);,2,0x00596faa@0x00596fa0:multiplayer_transport_submit_profile_key_query_bundle_with_context; 0x00596fc7@0x00596fc0:multiplayer_transport_submit_profile_key_query_bundle_default,13,0x00596eb6->0x0058ec50:multiplayer_transport_submit_getkey_command_and_wait; 0x00596f7a->0x0058ef20:multiplayer_transport_submit_setchankey_pair_list_command_and_wait; 0x00596e68->0x0058f380:tracked_heap_alloc_with_header; 0x00596f03->0x0058f380:tracked_heap_alloc_with_header; 0x00596ebf->0x0058f3c0:tracked_heap_free_with_header; 0x00596f83->0x0058f3c0:tracked_heap_free_with_header; 0x00596e56->0x0058f8f0:fcn.0058f8f0; 0x00596edf->0x0058f8f0:fcn.0058f8f0; 0x00596df0->0x0058f9c0:hashed_entry_table_lookup; 0x00596e22->0x0058f9c0:hashed_entry_table_lookup; 0x00596e36->0x0058f9c0:hashed_entry_table_lookup; 0x00596e8a->0x0058fa00:generic_callback_list_for_each; 0x00596f21->0x0058fa00:generic_callback_list_for_each,9,"0x00596e85->0x00596c80; 0x00596f1c->0x00596c80; 0x00596eaf->0x00596c90; 0x00596f67->0x00596ce0; 0x00596f6e->0x005e1e1c; 0x00596e1a->0x005e2260:""b_flags""; 0x00596f4d->0x005e2260:""b_flags""; 0x00596de8->0x005e22e8:""username""; 0x00596f32->0x005e22e8:""username"""," 596d80: calll 0x596b90 <.text+0x195b90> | 596d85: addl $0x4, %esi | 596d88: decl %ebx | 596d89: jne 0x596d70 <.text+0x195d70> | 596d8b: popl %edi | 596d8c: popl %esi | 596d8d: popl %ebp | 596d8e: popl %ebx | 596d8f: retl $0x18 | 596d92: nop | 596d93: nop | 596d94: nop | 596d95: nop | 596d96: nop | 596d97: nop | 596d98: nop | 596d99: nop | 596d9a: nop | 596d9b: nop | 596d9c: nop | 596d9d: nop | 596d9e: nop | 596d9f: nop | 596da0: subl $0x10, %esp | 596da3: pushl %ebp | 596da4: pushl %edi | 596da5: movl %eax, %edi | 596da7: movl 0x390(%esi,%edi,4), %eax | 596dae: xorl %ebp, %ebp | 596db0: cmpl %ebp, %eax | 596db2: jne 0x596dc1 <.text+0x195dc1> | 596db4: cmpl %ebp, 0x384(%esi,%edi,4) | 596dbb: je 0x596f89 <.text+0x195f89>"
0x00596fa0,0x00596fa0,multiplayer_transport_submit_profile_key_query_bundle_with_context,19,cdecl,fcn.00596fa0(int32_t arg_4h);,1,0x0059f935,1,0x00596faa->0x00596da0:multiplayer_transport_submit_profile_key_query_bundle,0,," 596f80: decl %esp | 596f81: andb $0x18, %al | 596f83: calll 0x58f3c0 <.text+0x18e3c0> | 596f88: popl %ebx | 596f89: popl %edi | 596f8a: popl %ebp | 596f8b: addl $0x10, %esp | 596f8e: retl $0x4 | 596f91: nop | 596f92: nop | 596f93: nop | 596f94: nop | 596f95: nop | 596f96: nop | 596f97: nop | 596f98: nop | 596f99: nop | 596f9a: nop | 596f9b: nop | 596f9c: nop | 596f9d: nop | 596f9e: nop | 596f9f: nop | 596fa0: pushl %esi | 596fa1: movl %edx, %eax | 596fa3: movl 0x8(%esp), %edx | 596fa7: pushl %edx | 596fa8: movl %ecx, %esi | 596faa: calll 0x596da0 <.text+0x195da0> | 596faf: popl %esi | 596fb0: retl $0x4 | 596fb3: nop | 596fb4: nop | 596fb5: nop | 596fb6: nop | 596fb7: nop | 596fb8: nop | 596fb9: nop | 596fba: nop | 596fbb: nop | 596fbc: nop | 596fbd: nop | 596fbe: nop | 596fbf: nop"
0x00596fc0,0x00596fc0,multiplayer_transport_submit_profile_key_query_bundle_default,14,cdecl,fcn.00596fc0();,2,0x00595499@0x00595440:multiplayer_transport_init_selector_slot; 0x0059fbb5,1,0x00596fc7->0x00596da0:multiplayer_transport_submit_profile_key_query_bundle,0,," 596fa0: pushl %esi | 596fa1: movl %edx, %eax | 596fa3: movl 0x8(%esp), %edx | 596fa7: pushl %edx | 596fa8: movl %ecx, %esi | 596faa: calll 0x596da0 <.text+0x195da0> | 596faf: popl %esi | 596fb0: retl $0x4 | 596fb3: nop | 596fb4: nop | 596fb5: nop | 596fb6: nop | 596fb7: nop | 596fb8: nop | 596fb9: nop | 596fba: nop | 596fbb: nop | 596fbc: nop | 596fbd: nop | 596fbe: nop | 596fbf: nop | 596fc0: pushl %esi | 596fc1: movl %edx, %eax | 596fc3: pushl $0x0 | 596fc5: movl %ecx, %esi | 596fc7: calll 0x596da0 <.text+0x195da0> | 596fcc: popl %esi | 596fcd: retl | 596fce: nop | 596fcf: nop | 596fd0: movl 0x4(%esp), %eax | 596fd4: pushl %esi | 596fd5: movl %edx, %esi | 596fd7: movl 0x398(%eax), %edx | 596fdd: testl %edx, %edx | 596fdf: pushl %edi"
0x00596fd0,0x00596fd0,multiplayer_transport_dispatch_status_route_event,219,cdecl,data.00596fd0(int32_t arg_4h);,0,,6,0x00597017->0x0058bce0:fcn.0058bce0; 0x00597054->0x0058bce0:fcn.0058bce0; 0x00597029->0x0058cd40:fcn.0058cd40; 0x0059703f->0x0058cd40:fcn.0058cd40; 0x0059706d->0x0058cd40:fcn.0058cd40; 0x00597084->0x0058cd40:fcn.0058cd40,3,"0x00597008->0x005970ac; 0x00597001->0x005970c4; 0x0059704d->0x005ce1c8:""openstaging"""," 596fb0: retl $0x4 | 596fb3: nop | 596fb4: nop | 596fb5: nop | 596fb6: nop | 596fb7: nop | 596fb8: nop | 596fb9: nop | 596fba: nop | 596fbb: nop | 596fbc: nop | 596fbd: nop | 596fbe: nop | 596fbf: nop | 596fc0: pushl %esi | 596fc1: movl %edx, %eax | 596fc3: pushl $0x0 | 596fc5: movl %ecx, %esi | 596fc7: calll 0x596da0 <.text+0x195da0> | 596fcc: popl %esi | 596fcd: retl | 596fce: nop | 596fcf: nop | 596fd0: movl 0x4(%esp), %eax | 596fd4: pushl %esi | 596fd5: movl %edx, %esi | 596fd7: movl 0x398(%eax), %edx | 596fdd: testl %edx, %edx | 596fdf: pushl %edi | 596fe0: je 0x597077 <.text+0x196077> | 596fe6: movl 0xb44(%eax), %edx | 596fec: testl %edx, %edx | 596fee: je 0x596ff9 <.text+0x195ff9>"
0x005973d0,0x005973d0,multiplayer_transport_try_connect_status_route,170,cdecl,fcn.005973d0(int32_t arg_4h);,2,0x0058daf1@0x0058dae0:fcn.0058dae0; 0x005965be@0x005965a0:multiplayer_transport_try_connect_status_route_once,4,0x00597460->0x0058bc90:fcn.0058bc90; 0x0059743c->0x0058c9b0:fcn.0058c9b0; 0x0059742d->0x0058cc40:fcn.0058cc40; 0x005973e7->0x00597350:multiplayer_transport_release_status_route,7,0x0059740f->0x00596fd0; 0x0059740a->0x005970e0; 0x00597405->0x00597180; 0x00597400->0x005971b0; 0x005973fb->0x00597270; 0x005973f6->0x005972c0; 0x0059745b->0x00597330," 5973b0: pushl %esi | 5973b1: movl %ecx, %esi | 5973b3: movl 0x1ecc(%esi), %ecx | 5973b9: testl %ecx, %ecx | 5973bb: je 0x5973cc <.text+0x1963cc> | 5973bd: calll 0x58cfd0 <.text+0x18bfd0> | 5973c2: movl $0x0, 0x1ecc(%esi) | 5973cc: popl %esi | 5973cd: retl | 5973ce: nop | 5973cf: nop | 5973d0: pushl %ebx | 5973d1: pushl %esi | 5973d2: movl %ecx, %esi | 5973d4: movl 0xaf0(%esi), %eax | 5973da: testl %eax, %eax | 5973dc: pushl %edi | 5973dd: leal 0xaf0(%esi), %edi | 5973e3: movl %edx, %ebx | 5973e5: je 0x5973ec <.text+0x1963ec> | 5973e7: calll 0x597350 <.text+0x196350> | 5973ec: cmpl $-0x1, %ebx | 5973ef: movl 0xb34(%esi), %eax"
1 query_address function_address name size calling_convention signature caller_count callers callee_count callees data_ref_count data_refs entry_excerpt
2 0x00595440 0x00595440 multiplayer_transport_init_selector_slot 100 cdecl fcn.00595440(int32_t arg_4h, int32_t arg_39ch, int32_t arg_59bh); 2 0x00593841@0x00593790:multiplayer_transport_handle_names_query_response; 0x00593b25@0x00593b00:multiplayer_transport_handle_selector_update_response 3 0x00595490->0x005951f0:multiplayer_transport_service_status_pump; 0x00595499->0x00596fc0:multiplayer_transport_submit_profile_key_query_bundle_default; 0x0059547f->0x005a18a0:string_copy_bounded_zerofill 1 0x0059544f->0x005c87a8 595420: movl $0x89ffff98, %esp # imm = 0x89FFFF98 | 595425: movl $0x9a4, %esi # imm = 0x9A4 | 59542a: popl %edi | 59542b: popl %esi | 59542c: addl $0x190, %esp # imm = 0x190 | 595432: retl | 595433: nop | 595434: nop | 595435: nop | 595436: nop | 595437: nop | 595438: nop | 595439: nop | 59543a: nop | 59543b: nop | 59543c: nop | 59543d: nop | 59543e: nop | 59543f: nop | 595440: movl 0x4(%esp), %eax | 595444: testl %eax, %eax | 595446: pushl %ebp | 595447: pushl %esi | 595448: pushl %edi | 595449: movl %edx, %edi | 59544b: movl %ecx, %esi | 59544d: jne 0x595454 <.text+0x194454> | 59544f: movl $0x5c87a8, %eax # imm = 0x5C87A8 | 595454: movl %edi, %ecx | 595456: shll $0x9, %ecx | 595459: leal (%ecx,%esi), %ebp | 59545c: pushl $0x200 # imm = 0x200
3 0x00596da0 0x00596da0 multiplayer_transport_submit_profile_key_query_bundle 497 cdecl fcn.00596da0(uint_least32_t arg_4h); 2 0x00596faa@0x00596fa0:multiplayer_transport_submit_profile_key_query_bundle_with_context; 0x00596fc7@0x00596fc0:multiplayer_transport_submit_profile_key_query_bundle_default 13 0x00596eb6->0x0058ec50:multiplayer_transport_submit_getkey_command_and_wait; 0x00596f7a->0x0058ef20:multiplayer_transport_submit_setchankey_pair_list_command_and_wait; 0x00596e68->0x0058f380:tracked_heap_alloc_with_header; 0x00596f03->0x0058f380:tracked_heap_alloc_with_header; 0x00596ebf->0x0058f3c0:tracked_heap_free_with_header; 0x00596f83->0x0058f3c0:tracked_heap_free_with_header; 0x00596e56->0x0058f8f0:fcn.0058f8f0; 0x00596edf->0x0058f8f0:fcn.0058f8f0; 0x00596df0->0x0058f9c0:hashed_entry_table_lookup; 0x00596e22->0x0058f9c0:hashed_entry_table_lookup; 0x00596e36->0x0058f9c0:hashed_entry_table_lookup; 0x00596e8a->0x0058fa00:generic_callback_list_for_each; 0x00596f21->0x0058fa00:generic_callback_list_for_each 9 0x00596e85->0x00596c80; 0x00596f1c->0x00596c80; 0x00596eaf->0x00596c90; 0x00596f67->0x00596ce0; 0x00596f6e->0x005e1e1c; 0x00596e1a->0x005e2260:"b_flags"; 0x00596f4d->0x005e2260:"b_flags"; 0x00596de8->0x005e22e8:"username"; 0x00596f32->0x005e22e8:"username" 596d80: calll 0x596b90 <.text+0x195b90> | 596d85: addl $0x4, %esi | 596d88: decl %ebx | 596d89: jne 0x596d70 <.text+0x195d70> | 596d8b: popl %edi | 596d8c: popl %esi | 596d8d: popl %ebp | 596d8e: popl %ebx | 596d8f: retl $0x18 | 596d92: nop | 596d93: nop | 596d94: nop | 596d95: nop | 596d96: nop | 596d97: nop | 596d98: nop | 596d99: nop | 596d9a: nop | 596d9b: nop | 596d9c: nop | 596d9d: nop | 596d9e: nop | 596d9f: nop | 596da0: subl $0x10, %esp | 596da3: pushl %ebp | 596da4: pushl %edi | 596da5: movl %eax, %edi | 596da7: movl 0x390(%esi,%edi,4), %eax | 596dae: xorl %ebp, %ebp | 596db0: cmpl %ebp, %eax | 596db2: jne 0x596dc1 <.text+0x195dc1> | 596db4: cmpl %ebp, 0x384(%esi,%edi,4) | 596dbb: je 0x596f89 <.text+0x195f89>
4 0x00596fa0 0x00596fa0 multiplayer_transport_submit_profile_key_query_bundle_with_context 19 cdecl fcn.00596fa0(int32_t arg_4h); 1 0x0059f935 1 0x00596faa->0x00596da0:multiplayer_transport_submit_profile_key_query_bundle 0 596f80: decl %esp | 596f81: andb $0x18, %al | 596f83: calll 0x58f3c0 <.text+0x18e3c0> | 596f88: popl %ebx | 596f89: popl %edi | 596f8a: popl %ebp | 596f8b: addl $0x10, %esp | 596f8e: retl $0x4 | 596f91: nop | 596f92: nop | 596f93: nop | 596f94: nop | 596f95: nop | 596f96: nop | 596f97: nop | 596f98: nop | 596f99: nop | 596f9a: nop | 596f9b: nop | 596f9c: nop | 596f9d: nop | 596f9e: nop | 596f9f: nop | 596fa0: pushl %esi | 596fa1: movl %edx, %eax | 596fa3: movl 0x8(%esp), %edx | 596fa7: pushl %edx | 596fa8: movl %ecx, %esi | 596faa: calll 0x596da0 <.text+0x195da0> | 596faf: popl %esi | 596fb0: retl $0x4 | 596fb3: nop | 596fb4: nop | 596fb5: nop | 596fb6: nop | 596fb7: nop | 596fb8: nop | 596fb9: nop | 596fba: nop | 596fbb: nop | 596fbc: nop | 596fbd: nop | 596fbe: nop | 596fbf: nop
5 0x00596fc0 0x00596fc0 multiplayer_transport_submit_profile_key_query_bundle_default 14 cdecl fcn.00596fc0(); 2 0x00595499@0x00595440:multiplayer_transport_init_selector_slot; 0x0059fbb5 1 0x00596fc7->0x00596da0:multiplayer_transport_submit_profile_key_query_bundle 0 596fa0: pushl %esi | 596fa1: movl %edx, %eax | 596fa3: movl 0x8(%esp), %edx | 596fa7: pushl %edx | 596fa8: movl %ecx, %esi | 596faa: calll 0x596da0 <.text+0x195da0> | 596faf: popl %esi | 596fb0: retl $0x4 | 596fb3: nop | 596fb4: nop | 596fb5: nop | 596fb6: nop | 596fb7: nop | 596fb8: nop | 596fb9: nop | 596fba: nop | 596fbb: nop | 596fbc: nop | 596fbd: nop | 596fbe: nop | 596fbf: nop | 596fc0: pushl %esi | 596fc1: movl %edx, %eax | 596fc3: pushl $0x0 | 596fc5: movl %ecx, %esi | 596fc7: calll 0x596da0 <.text+0x195da0> | 596fcc: popl %esi | 596fcd: retl | 596fce: nop | 596fcf: nop | 596fd0: movl 0x4(%esp), %eax | 596fd4: pushl %esi | 596fd5: movl %edx, %esi | 596fd7: movl 0x398(%eax), %edx | 596fdd: testl %edx, %edx | 596fdf: pushl %edi
6 0x00596fd0 0x00596fd0 multiplayer_transport_dispatch_status_route_event 219 cdecl data.00596fd0(int32_t arg_4h); 0 6 0x00597017->0x0058bce0:fcn.0058bce0; 0x00597054->0x0058bce0:fcn.0058bce0; 0x00597029->0x0058cd40:fcn.0058cd40; 0x0059703f->0x0058cd40:fcn.0058cd40; 0x0059706d->0x0058cd40:fcn.0058cd40; 0x00597084->0x0058cd40:fcn.0058cd40 3 0x00597008->0x005970ac; 0x00597001->0x005970c4; 0x0059704d->0x005ce1c8:"openstaging" 596fb0: retl $0x4 | 596fb3: nop | 596fb4: nop | 596fb5: nop | 596fb6: nop | 596fb7: nop | 596fb8: nop | 596fb9: nop | 596fba: nop | 596fbb: nop | 596fbc: nop | 596fbd: nop | 596fbe: nop | 596fbf: nop | 596fc0: pushl %esi | 596fc1: movl %edx, %eax | 596fc3: pushl $0x0 | 596fc5: movl %ecx, %esi | 596fc7: calll 0x596da0 <.text+0x195da0> | 596fcc: popl %esi | 596fcd: retl | 596fce: nop | 596fcf: nop | 596fd0: movl 0x4(%esp), %eax | 596fd4: pushl %esi | 596fd5: movl %edx, %esi | 596fd7: movl 0x398(%eax), %edx | 596fdd: testl %edx, %edx | 596fdf: pushl %edi | 596fe0: je 0x597077 <.text+0x196077> | 596fe6: movl 0xb44(%eax), %edx | 596fec: testl %edx, %edx | 596fee: je 0x596ff9 <.text+0x195ff9>
7 0x005973d0 0x005973d0 multiplayer_transport_try_connect_status_route 170 cdecl fcn.005973d0(int32_t arg_4h); 2 0x0058daf1@0x0058dae0:fcn.0058dae0; 0x005965be@0x005965a0:multiplayer_transport_try_connect_status_route_once 4 0x00597460->0x0058bc90:fcn.0058bc90; 0x0059743c->0x0058c9b0:fcn.0058c9b0; 0x0059742d->0x0058cc40:fcn.0058cc40; 0x005973e7->0x00597350:multiplayer_transport_release_status_route 7 0x0059740f->0x00596fd0; 0x0059740a->0x005970e0; 0x00597405->0x00597180; 0x00597400->0x005971b0; 0x005973fb->0x00597270; 0x005973f6->0x005972c0; 0x0059745b->0x00597330 5973b0: pushl %esi | 5973b1: movl %ecx, %esi | 5973b3: movl 0x1ecc(%esi), %ecx | 5973b9: testl %ecx, %ecx | 5973bb: je 0x5973cc <.text+0x1963cc> | 5973bd: calll 0x58cfd0 <.text+0x18bfd0> | 5973c2: movl $0x0, 0x1ecc(%esi) | 5973cc: popl %esi | 5973cd: retl | 5973ce: nop | 5973cf: nop | 5973d0: pushl %ebx | 5973d1: pushl %esi | 5973d2: movl %ecx, %esi | 5973d4: movl 0xaf0(%esi), %eax | 5973da: testl %eax, %eax | 5973dc: pushl %edi | 5973dd: leal 0xaf0(%esi), %edi | 5973e3: movl %edx, %ebx | 5973e5: je 0x5973ec <.text+0x1963ec> | 5973e7: calll 0x597350 <.text+0x196350> | 5973ec: cmpl $-0x1, %ebx | 5973ef: movl 0xb34(%esi), %eax

View file

@ -0,0 +1,5 @@
query_text,match_kind,string_address,string_text,xref_count,xrefs
Direct3DCreate8,exact,0x005ebfc6,Direct3DCreate8,0,
Texture SRAM: %4 Kb,substring,0x005dd028,Total SRAM: %1 Mb\nTotal VRAM: %2 Kb\n(D3D) Used VRAM: %3 Kb\nTexture SRAM: %4 Kb\nTexture VRAM: %5 Kb,1,0x00527b0e@0x00527650:shell_publish_texture_budget_report:DATA
Texture VRAM: %5 Kb,substring,0x005dd028,Total SRAM: %1 Mb\nTotal VRAM: %2 Kb\n(D3D) Used VRAM: %3 Kb\nTexture SRAM: %4 Kb\nTexture VRAM: %5 Kb,1,0x00527b0e@0x00527650:shell_publish_texture_budget_report:DATA
Texture changes per frame: %1,substring,0x005dd002,9CTexture changes per frame: %1,0,
1 query_text match_kind string_address string_text xref_count xrefs
2 Direct3DCreate8 exact 0x005ebfc6 Direct3DCreate8 0
3 Texture SRAM: %4 Kb substring 0x005dd028 Total SRAM: %1 Mb\nTotal VRAM: %2 Kb\n(D3D) Used VRAM: %3 Kb\nTexture SRAM: %4 Kb\nTexture VRAM: %5 Kb 1 0x00527b0e@0x00527650:shell_publish_texture_budget_report:DATA
4 Texture VRAM: %5 Kb substring 0x005dd028 Total SRAM: %1 Mb\nTotal VRAM: %2 Kb\n(D3D) Used VRAM: %3 Kb\nTexture SRAM: %4 Kb\nTexture VRAM: %5 Kb 1 0x00527b0e@0x00527650:shell_publish_texture_budget_report:DATA
5 Texture changes per frame: %1 substring 0x005dd002 9CTexture changes per frame: %1 0

View file

@ -0,0 +1,689 @@
# Analysis Context
- Target binary: `/home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3/RT3.exe`
- Function names prefer the curated ledger when a committed mapping exists.
## Function Targets
### `0x00595440` -> `0x00595440` `multiplayer_transport_init_selector_slot`
- Size: `100`
- Calling convention: `cdecl`
- Signature: `fcn.00595440(int32_t arg_4h, int32_t arg_39ch, int32_t arg_59bh);`
Entry excerpt:
```asm
595420: movl $0x89ffff98, %esp # imm = 0x89FFFF98
595425: movl $0x9a4, %esi # imm = 0x9A4
59542a: popl %edi
59542b: popl %esi
59542c: addl $0x190, %esp # imm = 0x190
595432: retl
595433: nop
595434: nop
595435: nop
595436: nop
595437: nop
595438: nop
595439: nop
59543a: nop
59543b: nop
59543c: nop
59543d: nop
59543e: nop
59543f: nop
595440: movl 0x4(%esp), %eax
595444: testl %eax, %eax
595446: pushl %ebp
595447: pushl %esi
595448: pushl %edi
595449: movl %edx, %edi
59544b: movl %ecx, %esi
59544d: jne 0x595454 <.text+0x194454>
59544f: movl $0x5c87a8, %eax # imm = 0x5C87A8
595454: movl %edi, %ecx
595456: shll $0x9, %ecx
595459: leal (%ecx,%esi), %ebp
59545c: pushl $0x200 # imm = 0x200
```
Callers:
- `0x00593841` in `0x00593790` `multiplayer_transport_handle_names_query_response`
- `0x00593b25` in `0x00593b00` `multiplayer_transport_handle_selector_update_response`
Caller xref excerpts:
#### `0x00593841`
```asm
593821: movl $0x1000000, %esp # imm = 0x1000000
593826: addb %al, (%eax)
593828: addb %ch, %bl
59382a: orb %bh, %al
59382c: xchgb %al, 0xb(%eax)
59382f: addb %al, (%eax)
593831: addl %eax, (%eax)
593833: addb %al, (%eax)
593835: movl 0x20(%edi), %edx
593838: pushl %ebx
593839: pushl %edx
59383a: movl $0x2, %edx
59383f: movl %esi, %ecx
593841: calll 0x595440 <.text+0x194440>
593846: movl 0x1c(%esp), %eax
59384a: cmpl %ebp, %eax
59384c: jle 0x59387f <.text+0x19287f>
59384e: movl 0x20(%esp), %ebx
593852: movl 0x24(%esp), %ebp
593856: subl %ebx, %ebp
593858: movl %eax, 0x28(%esp)
59385c: leal (%esp), %esp
593860: movl (%ebx,%ebp), %eax
```
#### `0x00593b25`
```asm
593b05: andb $0x20, %al
593b07: movl 0x38(%esi), %eax
593b0a: testl %eax, %eax
593b0c: movl (%esi), %ebx
593b0e: pushl %edi
593b0f: movl %edx, %edi
593b11: movl %edi, 0xc(%esp)
593b15: jne 0x593b93 <.text+0x192b93>
593b17: testl %edi, %edi
593b19: movl 0x1c(%esi), %edx
593b1c: movl %ebx, %ecx
593b1e: je 0x593b67 <.text+0x192b67>
593b20: pushl $0x5c87a8 # imm = 0x5C87A8
593b25: calll 0x595440 <.text+0x194440>
593b2a: movl 0x18(%esp), %eax
593b2e: testl %eax, %eax
593b30: jle 0x593b6e <.text+0x192b6e>
593b32: movl 0x1c(%esp), %edi
593b36: pushl %ebp
593b37: movl 0x24(%esp), %ebp
593b3b: subl %edi, %ebp
593b3d: movl %eax, 0x28(%esp)
593b41: movl (%edi,%ebp), %eax
593b44: movl 0x1c(%esi), %ecx
```
Direct internal callees:
- `0x00595490` -> `0x005951f0` `multiplayer_transport_service_status_pump`
- `0x00595499` -> `0x00596fc0` `multiplayer_transport_submit_profile_key_query_bundle_default`
- `0x0059547f` -> `0x005a18a0` `string_copy_bounded_zerofill`
Data refs:
- `0x0059544f` -> `0x005c87a8`
### `0x00596da0` -> `0x00596da0` `multiplayer_transport_submit_profile_key_query_bundle`
- Size: `497`
- Calling convention: `cdecl`
- Signature: `fcn.00596da0(uint_least32_t arg_4h);`
Entry excerpt:
```asm
596d80: calll 0x596b90 <.text+0x195b90>
596d85: addl $0x4, %esi
596d88: decl %ebx
596d89: jne 0x596d70 <.text+0x195d70>
596d8b: popl %edi
596d8c: popl %esi
596d8d: popl %ebp
596d8e: popl %ebx
596d8f: retl $0x18
596d92: nop
596d93: nop
596d94: nop
596d95: nop
596d96: nop
596d97: nop
596d98: nop
596d99: nop
596d9a: nop
596d9b: nop
596d9c: nop
596d9d: nop
596d9e: nop
596d9f: nop
596da0: subl $0x10, %esp
596da3: pushl %ebp
596da4: pushl %edi
596da5: movl %eax, %edi
596da7: movl 0x390(%esi,%edi,4), %eax
596dae: xorl %ebp, %ebp
596db0: cmpl %ebp, %eax
596db2: jne 0x596dc1 <.text+0x195dc1>
596db4: cmpl %ebp, 0x384(%esi,%edi,4)
596dbb: je 0x596f89 <.text+0x195f89>
```
Callers:
- `0x00596faa` in `0x00596fa0` `multiplayer_transport_submit_profile_key_query_bundle_with_context`
- `0x00596fc7` in `0x00596fc0` `multiplayer_transport_submit_profile_key_query_bundle_default`
Caller xref excerpts:
#### `0x00596faa`
```asm
596f8a: popl %ebp
596f8b: addl $0x10, %esp
596f8e: retl $0x4
596f91: nop
596f92: nop
596f93: nop
596f94: nop
596f95: nop
596f96: nop
596f97: nop
596f98: nop
596f99: nop
596f9a: nop
596f9b: nop
596f9c: nop
596f9d: nop
596f9e: nop
596f9f: nop
596fa0: pushl %esi
596fa1: movl %edx, %eax
596fa3: movl 0x8(%esp), %edx
596fa7: pushl %edx
596fa8: movl %ecx, %esi
596faa: calll 0x596da0 <.text+0x195da0>
596faf: popl %esi
596fb0: retl $0x4
596fb3: nop
596fb4: nop
596fb5: nop
596fb6: nop
596fb7: nop
596fb8: nop
596fb9: nop
596fba: nop
596fbb: nop
596fbc: nop
596fbd: nop
596fbe: nop
596fbf: nop
596fc0: pushl %esi
596fc1: movl %edx, %eax
596fc3: pushl $0x0
596fc5: movl %ecx, %esi
596fc7: calll 0x596da0 <.text+0x195da0>
```
#### `0x00596fc7`
```asm
596fa7: pushl %edx
596fa8: movl %ecx, %esi
596faa: calll 0x596da0 <.text+0x195da0>
596faf: popl %esi
596fb0: retl $0x4
596fb3: nop
596fb4: nop
596fb5: nop
596fb6: nop
596fb7: nop
596fb8: nop
596fb9: nop
596fba: nop
596fbb: nop
596fbc: nop
596fbd: nop
596fbe: nop
596fbf: nop
596fc0: pushl %esi
596fc1: movl %edx, %eax
596fc3: pushl $0x0
596fc5: movl %ecx, %esi
596fc7: calll 0x596da0 <.text+0x195da0>
596fcc: popl %esi
596fcd: retl
596fce: nop
596fcf: nop
596fd0: movl 0x4(%esp), %eax
596fd4: pushl %esi
596fd5: movl %edx, %esi
596fd7: movl 0x398(%eax), %edx
596fdd: testl %edx, %edx
596fdf: pushl %edi
596fe0: je 0x597077 <.text+0x196077>
596fe6: movl 0xb44(%eax), %edx
```
Direct internal callees:
- `0x00596eb6` -> `0x0058ec50` `multiplayer_transport_submit_getkey_command_and_wait`
- `0x00596f7a` -> `0x0058ef20` `multiplayer_transport_submit_setchankey_pair_list_command_and_wait`
- `0x00596e68` -> `0x0058f380` `tracked_heap_alloc_with_header`
- `0x00596f03` -> `0x0058f380` `tracked_heap_alloc_with_header`
- `0x00596ebf` -> `0x0058f3c0` `tracked_heap_free_with_header`
- `0x00596f83` -> `0x0058f3c0` `tracked_heap_free_with_header`
- `0x00596e56` -> `0x0058f8f0` `fcn.0058f8f0`
- `0x00596edf` -> `0x0058f8f0` `fcn.0058f8f0`
- `0x00596df0` -> `0x0058f9c0` `hashed_entry_table_lookup`
- `0x00596e22` -> `0x0058f9c0` `hashed_entry_table_lookup`
- `0x00596e36` -> `0x0058f9c0` `hashed_entry_table_lookup`
- `0x00596e8a` -> `0x0058fa00` `generic_callback_list_for_each`
- `0x00596f21` -> `0x0058fa00` `generic_callback_list_for_each`
Data refs:
- `0x00596e85` -> `0x00596c80`
- `0x00596f1c` -> `0x00596c80`
- `0x00596eaf` -> `0x00596c90`
- `0x00596f67` -> `0x00596ce0`
- `0x00596f6e` -> `0x005e1e1c`
- `0x00596e1a` -> `0x005e2260` "b_flags"
- `0x00596f4d` -> `0x005e2260` "b_flags"
- `0x00596de8` -> `0x005e22e8` "username"
- `0x00596f32` -> `0x005e22e8` "username"
### `0x00596fa0` -> `0x00596fa0` `multiplayer_transport_submit_profile_key_query_bundle_with_context`
- Size: `19`
- Calling convention: `cdecl`
- Signature: `fcn.00596fa0(int32_t arg_4h);`
Entry excerpt:
```asm
596f80: decl %esp
596f81: andb $0x18, %al
596f83: calll 0x58f3c0 <.text+0x18e3c0>
596f88: popl %ebx
596f89: popl %edi
596f8a: popl %ebp
596f8b: addl $0x10, %esp
596f8e: retl $0x4
596f91: nop
596f92: nop
596f93: nop
596f94: nop
596f95: nop
596f96: nop
596f97: nop
596f98: nop
596f99: nop
596f9a: nop
596f9b: nop
596f9c: nop
596f9d: nop
596f9e: nop
596f9f: nop
596fa0: pushl %esi
596fa1: movl %edx, %eax
596fa3: movl 0x8(%esp), %edx
596fa7: pushl %edx
596fa8: movl %ecx, %esi
596faa: calll 0x596da0 <.text+0x195da0>
596faf: popl %esi
596fb0: retl $0x4
596fb3: nop
596fb4: nop
596fb5: nop
596fb6: nop
596fb7: nop
596fb8: nop
596fb9: nop
596fba: nop
596fbb: nop
596fbc: nop
596fbd: nop
596fbe: nop
596fbf: nop
```
Callers:
- `0x0059f935`
Caller xref excerpts:
#### `0x0059f935`
```asm
59f915: <unknown>
59f917: testl %eax, %eax
59f919: je 0x59f92e <.text+0x19e92e>
59f91b: movl 0x10(%esp), %edx
59f91f: movl 0x8(%esp), %eax
59f923: pushl %edx
59f924: pushl %eax
59f925: movl %edi, %edx
59f927: movl %esi, %ecx
59f929: calll 0x594b60 <.text+0x193b60>
59f92e: movl 0x18(%esp), %edx
59f932: pushl %edi
59f933: movl %esi, %ecx
59f935: calll 0x596fa0 <.text+0x195fa0>
59f93a: movl 0x18(%esp), %edx
59f93e: pushl %edi
59f93f: movl %esi, %ecx
59f941: calll 0x592ee0 <.text+0x191ee0>
59f946: cmpl $0x2, 0x18(%esp)
59f94b: jne 0x59f9b1 <.text+0x19e9b1>
59f94d: movl 0xb54(%esi), %eax
59f953: testl %eax, %eax
```
Direct internal callees:
- `0x00596faa` -> `0x00596da0` `multiplayer_transport_submit_profile_key_query_bundle`
Data refs:
- none
### `0x00596fc0` -> `0x00596fc0` `multiplayer_transport_submit_profile_key_query_bundle_default`
- Size: `14`
- Calling convention: `cdecl`
- Signature: `fcn.00596fc0();`
Entry excerpt:
```asm
596fa0: pushl %esi
596fa1: movl %edx, %eax
596fa3: movl 0x8(%esp), %edx
596fa7: pushl %edx
596fa8: movl %ecx, %esi
596faa: calll 0x596da0 <.text+0x195da0>
596faf: popl %esi
596fb0: retl $0x4
596fb3: nop
596fb4: nop
596fb5: nop
596fb6: nop
596fb7: nop
596fb8: nop
596fb9: nop
596fba: nop
596fbb: nop
596fbc: nop
596fbd: nop
596fbe: nop
596fbf: nop
596fc0: pushl %esi
596fc1: movl %edx, %eax
596fc3: pushl $0x0
596fc5: movl %ecx, %esi
596fc7: calll 0x596da0 <.text+0x195da0>
596fcc: popl %esi
596fcd: retl
596fce: nop
596fcf: nop
596fd0: movl 0x4(%esp), %eax
596fd4: pushl %esi
596fd5: movl %edx, %esi
596fd7: movl 0x398(%eax), %edx
596fdd: testl %edx, %edx
596fdf: pushl %edi
```
Callers:
- `0x00595499` in `0x00595440` `multiplayer_transport_init_selector_slot`
- `0x0059fbb5`
Caller xref excerpts:
#### `0x00595499`
```asm
595479: addb %al, (%eax)
59547b: addb %al, (%eax)
59547d: addb %al, (%eax)
59547f: calll 0x5a18a0 <.text+0x1a08a0>
595484: addl $0xc, %esp
595487: movl %esi, %ecx
595489: movb $0x0, 0x59b(%ebp)
595490: calll 0x5951f0 <.text+0x1941f0>
595495: movl %edi, %edx
595497: movl %esi, %ecx
595499: calll 0x596fc0 <.text+0x195fc0>
59549e: popl %edi
59549f: popl %esi
5954a0: popl %ebp
5954a1: retl $0x4
5954a4: nop
5954a5: nop
5954a6: nop
5954a7: nop
5954a8: nop
5954a9: nop
5954aa: nop
5954ab: nop
5954ac: nop
5954ad: nop
5954ae: nop
5954af: nop
5954b0: pushl %ebx
5954b1: pushl %esi
5954b2: pushl %edi
5954b3: movl %edx, %edi
5954b5: movl %ecx, %esi
5954b7: movl 0x384(%esi,%edi,4), %eax
```
#### `0x0059fbb5`
```asm
59fb95: movl (%edi,%esi), %ecx
59fb98: movl 0x20(%esp), %edx
59fb9c: pushl %ecx
59fb9d: pushl %edx
59fb9e: movl (%esi), %edx
59fba0: movl %ebp, %ecx
59fba2: calll 0x594f20 <.text+0x193f20>
59fba7: addl $0x4, %esi
59fbaa: decl %ebx
59fbab: jne 0x59fb95 <.text+0x19eb95>
59fbad: popl %edi
59fbae: popl %esi
59fbaf: movl 0x18(%esp), %edx
59fbb3: movl %ebp, %ecx
59fbb5: calll 0x596fc0 <.text+0x195fc0>
59fbba: movl 0x18(%esp), %edx
59fbbe: movl %ebp, %ecx
59fbc0: calll 0x592fc0 <.text+0x191fc0>
59fbc5: popl %ebx
59fbc6: popl %ebp
59fbc7: retl $0x10
59fbca: nop
59fbcb: nop
59fbcc: nop
59fbcd: nop
59fbce: nop
59fbcf: nop
59fbd0: pushl %esi
59fbd1: movl 0x14(%esp), %esi
```
Direct internal callees:
- `0x00596fc7` -> `0x00596da0` `multiplayer_transport_submit_profile_key_query_bundle`
Data refs:
- none
### `0x00596fd0` -> `0x00596fd0` `multiplayer_transport_dispatch_status_route_event`
- Size: `219`
- Calling convention: `cdecl`
- Signature: `data.00596fd0(int32_t arg_4h);`
Entry excerpt:
```asm
596fb0: retl $0x4
596fb3: nop
596fb4: nop
596fb5: nop
596fb6: nop
596fb7: nop
596fb8: nop
596fb9: nop
596fba: nop
596fbb: nop
596fbc: nop
596fbd: nop
596fbe: nop
596fbf: nop
596fc0: pushl %esi
596fc1: movl %edx, %eax
596fc3: pushl $0x0
596fc5: movl %ecx, %esi
596fc7: calll 0x596da0 <.text+0x195da0>
596fcc: popl %esi
596fcd: retl
596fce: nop
596fcf: nop
596fd0: movl 0x4(%esp), %eax
596fd4: pushl %esi
596fd5: movl %edx, %esi
596fd7: movl 0x398(%eax), %edx
596fdd: testl %edx, %edx
596fdf: pushl %edi
596fe0: je 0x597077 <.text+0x196077>
596fe6: movl 0xb44(%eax), %edx
596fec: testl %edx, %edx
596fee: je 0x596ff9 <.text+0x195ff9>
```
Callers:
- none
Direct internal callees:
- `0x00597017` -> `0x0058bce0` `fcn.0058bce0`
- `0x00597054` -> `0x0058bce0` `fcn.0058bce0`
- `0x00597029` -> `0x0058cd40` `fcn.0058cd40`
- `0x0059703f` -> `0x0058cd40` `fcn.0058cd40`
- `0x0059706d` -> `0x0058cd40` `fcn.0058cd40`
- `0x00597084` -> `0x0058cd40` `fcn.0058cd40`
Data refs:
- `0x00597008` -> `0x005970ac`
- `0x00597001` -> `0x005970c4`
- `0x0059704d` -> `0x005ce1c8` "openstaging"
### `0x005973d0` -> `0x005973d0` `multiplayer_transport_try_connect_status_route`
- Size: `170`
- Calling convention: `cdecl`
- Signature: `fcn.005973d0(int32_t arg_4h);`
Entry excerpt:
```asm
5973b0: pushl %esi
5973b1: movl %ecx, %esi
5973b3: movl 0x1ecc(%esi), %ecx
5973b9: testl %ecx, %ecx
5973bb: je 0x5973cc <.text+0x1963cc>
5973bd: calll 0x58cfd0 <.text+0x18bfd0>
5973c2: movl $0x0, 0x1ecc(%esi)
5973cc: popl %esi
5973cd: retl
5973ce: nop
5973cf: nop
5973d0: pushl %ebx
5973d1: pushl %esi
5973d2: movl %ecx, %esi
5973d4: movl 0xaf0(%esi), %eax
5973da: testl %eax, %eax
5973dc: pushl %edi
5973dd: leal 0xaf0(%esi), %edi
5973e3: movl %edx, %ebx
5973e5: je 0x5973ec <.text+0x1963ec>
5973e7: calll 0x597350 <.text+0x196350>
5973ec: cmpl $-0x1, %ebx
5973ef: movl 0xb34(%esi), %eax
```
Callers:
- `0x0058daf1` in `0x0058dae0` `fcn.0058dae0`
- `0x005965be` in `0x005965a0` `multiplayer_transport_try_connect_status_route_once`
Caller xref excerpts:
#### `0x0058daf1`
```asm
58dad1: addb %bl, -0x3e(%esi)
58dad4: orb %al, (%eax)
58dad6: nop
58dad7: nop
58dad8: nop
58dad9: nop
58dada: nop
58dadb: nop
58dadc: nop
58dadd: nop
58dade: nop
58dadf: nop
58dae0: movb 0x60(%ecx), %al
58dae3: testb %al, %al
58dae5: jne 0x58daec <.text+0x18caec>
58dae7: xorl %eax, %eax
58dae9: retl $0x4
58daec: movl 0x4(%esp), %eax
58daf0: pushl %eax
58daf1: calll 0x5973d0 <.text+0x1963d0>
58daf6: negl %eax
58daf8: sbbl %eax, %eax
58dafa: negl %eax
58dafc: retl $0x4
58daff: nop
58db00: movb 0x60(%ecx), %al
58db03: testb %al, %al
58db05: je 0x58db16 <.text+0x18cb16>
58db07: movl $0x1, 0xb44(%ecx)
```
#### `0x005965be`
```asm
59659e: nop
59659f: nop
5965a0: movl 0xb40(%ecx), %eax
5965a6: testl %eax, %eax
5965a8: je 0x5965af <.text+0x1955af>
5965aa: xorl %eax, %eax
5965ac: retl $0x4
5965af: movl 0x4(%esp), %eax
5965b3: pushl %eax
5965b4: movl $0x1, 0xb40(%ecx)
5965be: calll 0x5973d0 <.text+0x1963d0>
5965c3: negl %eax
5965c5: sbbl %eax, %eax
5965c7: negl %eax
5965c9: retl $0x4
5965cc: nop
5965cd: nop
5965ce: nop
5965cf: nop
5965d0: testl %edx, %edx
5965d2: pushl %esi
5965d3: movl %ecx, %esi
5965d5: je 0x5965dc <.text+0x1955dc>
5965d7: calll 0x597350 <.text+0x196350>
5965dc: movl 0xb40(%esi), %eax
```
Direct internal callees:
- `0x00597460` -> `0x0058bc90` `fcn.0058bc90`
- `0x0059743c` -> `0x0058c9b0` `fcn.0058c9b0`
- `0x0059742d` -> `0x0058cc40` `fcn.0058cc40`
- `0x005973e7` -> `0x00597350` `multiplayer_transport_release_status_route`
Data refs:
- `0x0059740f` -> `0x00596fd0`
- `0x0059740a` -> `0x005970e0`
- `0x00597405` -> `0x00597180`
- `0x00597400` -> `0x005971b0`
- `0x005973fb` -> `0x00597270`
- `0x005973f6` -> `0x005972c0`
- `0x0059745b` -> `0x00597330`

View file

@ -0,0 +1,20 @@
{
"file": "/home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3/RT3.exe: PE32 executable for MS Windows 4.00 (GUI), Intel i386, 5 sections",
"imported_dll_count": 14,
"imported_function_count": 256,
"path": "/home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3/RT3.exe",
"sha256": "01b0d2496cddefd80e7e8678930e00b13eb8607dd4960096f527564f02af36d4",
"size_bytes": 2330624,
"summary": {
"AddressOfEntryPoint": "001a313b",
"BaseOfCode": "00001000",
"BaseOfData": "00292000",
"ImageBase": "00400000",
"Magic": "010b\t(PE32)",
"SizeOfCode": "00291000",
"SizeOfImage": "009c8260",
"SizeOfInitializedData": "00175000",
"Subsystem": "00000002\t(Windows GUI)",
"Time/Date": "Wed Sep 8 07:27:02 2004"
}
}

View file

@ -0,0 +1,440 @@
address,size,name,subsystem,calling_convention,prototype_status,source_tool,confidence,notes,verified_against
0x00444dd0,3301,map_bundle_open_reference_databases,map,cdecl,inferred,ghidra-headless,3,Opens and registers a broad reference-database bundle for the active map path. The routine formats %1\\%2 paths allocates bundle state through 0x00530c80 and wires many global datasets including gpdLabelDB gpdCityDB and related city geographic and map reference tables before later shell and map loaders continue.,ghidra + rizin + llvm-objdump + strings
0x00456920,3247,unit_visual_init_weapon_airframe_and_exhaust_effects,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes one armed-unit visual bundle spanning turret and cannon hardware exhaust emitters and aircraft airframe attachments. The routine creates static Turret Mantlet Cannon and MuzzleFlash assets at [this+0x31a] through [this+0x326] direct JetExhaust and PropExhaust sprite emitters at [this+0x2f6] and [this+0x2fa] a cannon-audio attachment at [this+0x32a] indexed WingL and WingR assets plus plane-audio state at [this+0x32e] through [this+0x346] and cached Aileron Elevator Rudder and Thrust vectors at [this+0x2d1] [this+0x2c5] [this+0x2b9] and [this+0x2dd].,ghidra + rizin + llvm-objdump + strings
0x00461650,120,map_load_geographic_label_database,map,cdecl,inferred,ghidra-headless,3,Loads the geographic-label database branch inside the broader reference-bundle setup. It stages resource ids 0x5209 through 0x520b binds the selected bundle through 0x517d90 iterates the loaded collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44 using the current map path context.,ghidra + rizin + llvm-objdump + strings
0x00464410,12679,shell_dispatch_ui_command,shell,cdecl,inferred,ghidra-headless,4,Large shell UI command dispatcher reached from shell-side event callbacks and direct command pushes. It switches over many command ids including 0x7530 through 0x7532 graphics-preset commands that route into 0x0051ebc0 0x00484590 and 0x004853c0; 0x7533 through 0x7534 TigerTank viewer actions; and 0x7540 through 0x7543 scenario-text report build and batch-processing commands that route into 0x00489830 0x004886e0 and 0x00489a20.,ghidra + rizin + llvm-objdump + strings
0x00474610,120,map_load_city_database,map,cdecl,inferred,ghidra-headless,3,Loads the city database branch in the same pattern as the geographic-label loader. It stages resource ids 0x61a9 through 0x61ab binds the selected bundle through 0x517d90 iterates the collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44.,ghidra + rizin + llvm-objdump + strings
0x00474e20,336,effect_slot_create_attached_sprite_emitter,bootstrap,thiscall,inferred,ghidra-headless,3,Creates or clones one attached sprite emitter for an effect slot on the owning object. Depending on flag bit 0x400 it either clones through 0x00556ce0 or allocates a fresh 0x1fd template through 0x00556920 then attaches the emitter to the owner at [emitter+0x60] and optionally sets persistent flag [emitter+0xbc].,ghidra + rizin + llvm-objdump
0x00474f70,97,effect_slot_update_attached_sprite_emitters,bootstrap,thiscall,inferred,ghidra-headless,3,Advances every sprite emitter stored in one effect-slot container by iterating its pointer list and calling 0x00555e50 with update mode zero. When the caller passes null it instead walks the global linked slot list rooted at 0x006cea74.,ghidra + rizin + llvm-objdump
0x00478200,291,shell_queue_single_world_anchor_overlay,shell,cdecl,inferred,ghidra-headless,3,Builds one world-anchor overlay packet for the current owner object. It samples the owner transform through 0x00455800 and 0x00455810 derives projected half-height and half-width through 0x00477a10 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and then enqueues the finished marker through shell_queue_world_anchor_marker.,ghidra + rizin + llvm-objdump
0x00478330,2432,shell_queue_world_anchor_overlay_list,shell,cdecl,inferred,ghidra-headless,3,Builds and queues a repeated world-anchor overlay list for one owner-managed collection. The routine iterates several owner sublists and state branches repeatedly derives projected extents through 0x00477a10 0x004779c0 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and emits one shell_queue_world_anchor_marker packet per accepted overlay entry.,ghidra + rizin + llvm-objdump
0x00485750,14,shell_has_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,4,Returns whether the dedicated TigerTank shell viewer object at 0x006cfc8c is currently active. The 0x7533 open and 0x7534 close commands both gate on this global before showing status text or mutating viewer state.,ghidra + rizin + llvm-objdump + strings
0x004840e0,863,bootstrap_init_shell_window_services,bootstrap,cdecl,inferred,ghidra-headless,4,Consumes the early bootstrap object then allocates the shell service bundle rooted at 0x006d4024 seeds a 640x480 fallback and drives the main window focus path before later startup continues.,ghidra + rizin
0x00484440,323,app_bootstrap_main,bootstrap,cdecl,inferred,ghidra-headless,4,Primary post-CRT bootstrap coordinator; initializes COM and branding strings then probes host state and hands off into the main application bootstrap chain.,ghidra + rizin
0x00484590,887,shell_init_graphics_preset_state,shell,cdecl,inferred,ghidra-headless,3,Initializes the shell graphics-preset state block rooted at [this+0x70]. It clears a large option buffer seeds many default fields and applies one of three coarse mode layouts from its integer argument before later preset application or config-save helpers continue.,ghidra + rizin + llvm-objdump
0x00484910,105,shell_save_graphics_config,shell,cdecl,inferred,ghidra-headless,4,Persistently writes the current shell graphics configuration to data\\configuration\\game.cfg. It optionally syncs the global display runtime through 0x0051eea0 then writes config keys 0x429 and 0x48d from the shell state block before closing the file.,ghidra + rizin + llvm-objdump + strings
0x00484980,212,shell_load_graphics_config_or_init_defaults,shell,cdecl,inferred,ghidra-headless,4,Loads the shell graphics configuration from data\\configuration\\game.cfg during early shell setup. It optionally pulls the larger display-runtime blob through 0x0051ef20 validates key 0x429 reads key 0x48d into the shell state block at [this+0x70] and falls back to 0x00484590 plus 0x00484910 when the file is missing or invalid.,ghidra + rizin + llvm-objdump + strings
0x00484a60,125,shell_match_legacy_gpu_profile_token,shell,cdecl,inferred,ghidra-headless,4,Collects the current display-adapter descriptor string then scans the legacy GPU-profile table at 0x0062142c for the first matching token. The table contains vendor and chipset strings such as geforce radeon Voodoo matrox i810 sis savage and 3dfx; the returned index or -1 then drives the preset-tier tables in 0x004853c0.,ghidra + rizin + llvm-objdump + strings
0x00484d70,700,shell_apply_graphics_option_runtime_effects,shell,thiscall,inferred,ghidra-headless,3,Walks the pending graphics-option array rooted at [this+0x1c] and applies runtime side effects for the dirty entries selected by the caller mask. The cases fan into the active engine object at 0x0062c120 and shell globals under 0x006d4024 and 0x006d4030 updating several float scaled thresholds integer quality values and display capability bytes before clearing the dirty array and notifying the active shell object at 0x0062be68.,ghidra + rizin + llvm-objdump
0x004852e0,210,shell_apply_default_graphics_master_profile,shell,thiscall,inferred,ghidra-headless,4,Reads the default master graphics profile value from 0x006211dc currently 6 and broadcasts it across option ids 1 through 16 in the shell settings block. Special option ids 10 11 12 and 13 are remapped through the preset tables at 0x00621250 through 0x00621358 before the function refreshes runtime side effects through 0x00484d70 updates shell display-profile flags under 0x006d4024 and persists game.cfg through 0x00484910.,ghidra + rizin + llvm-objdump
0x004853c0,740,shell_apply_graphics_preset_bundle,shell,cdecl,inferred,ghidra-headless,4,Applies one table-driven graphics preset bundle to the shell settings object. It derives a preset tier from shell state and runtime capability probes then writes per-setting values through repeated 0x00485060 calls refreshes dependent runtime state through 0x00484d70 optionally saves game.cfg through 0x00484910 and updates several display capability flags under 0x006d4024.,ghidra + rizin + llvm-objdump
0x00485060,635,shell_set_graphics_option_with_fanout,shell,thiscall,inferred,ghidra-headless,4,Writes one graphics option value into the shell settings arrays at [this+0xac] and coordinates grouped fanout updates. Primary preset selectors recursively expand into dependent option ids 1 through 16 using preset remap tables at 0x00621250 through 0x00621358. The function compares the new normalized value against the previous setting invokes 0x00484d70 when a runtime refresh is needed and persists game.cfg through 0x00484910 once the update batch completes.,ghidra + rizin + llvm-objdump
0x00485760,2746,vehicle_visual_init_running_gear_and_smoke_effects,bootstrap,thiscall,inferred,ghidra-headless,4,Builds a larger vehicle visual bundle covering running-gear assets smoke effects and attachment-audio objects. The routine fills indexed road-wheel visual arrays from RoadWheelR and RoadWheelL asset strings creates direct MuzzleSmoke and ExhaustSmoke sprite emitters at [this+0x216] and [this+0x21a] and then creates five fixed attachment objects at [this+0x3cc] through [this+0x3dc] for diesel1 tracks german88 turret and mantlet audio assets before registering them on the owner.,ghidra + rizin + llvm-objdump + strings
0x004883f0,325,scenario_text_export_append_numbered_entry,scenario,cdecl,inferred,ghidra-headless,4,Formats and appends one numbered translation entry into the scenario-text export buffer. It duplicates the source text applies the export wrapper template through helper formatters and appends the finished block through 0x531030 while updating the running non-comment word count at 0x006cfca0.,ghidra + rizin + llvm-objdump + strings
0x004886e0,3796,scenario_text_export_build_language_file,scenario,cdecl,inferred,ghidra-headless,4,Builds one MAPS\\%s.lng scenario-text export for the active map and returns the non-comment word count. It writes translator guidance and section headers then walks map briefing territory city geographic-label station company and event collections appending numbered entries through 0x004883f0 before finalizing the output buffer.,ghidra + rizin + llvm-objdump + strings
0x00487450,153,shell_open_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,3,Allocates and shows the dedicated TigerTank shell viewer object when no viewer is active. It samples shell-owned placement data allocates a 0x434-byte object initializes it through 0x00485760 with the TigerTank title and stores the resulting viewer pointer in 0x006cfc8c.,ghidra + rizin + llvm-objdump + strings
0x004874f0,70,shell_close_tiger_tank_viewer,shell,cdecl,inferred,ghidra-headless,4,Closes and frees the dedicated TigerTank shell viewer rooted at 0x006cfc8c. It detaches the viewer if currently selected in the shell owner at 0x0062be68 destroys its internal resources through 0x00530680 frees the object and clears the global viewer slot.,ghidra + rizin + llvm-objdump + strings
0x00489830,496,scenario_text_export_report_language_file,scenario,cdecl,inferred,ghidra-headless,3,Opens one existing MAPS\\%s.lng file for the selected map and reports on its parsed contents without rebuilding it. The routine loads the file into memory iterates numbered entries through 0x00488540 formats summary strings through 0x004895c0 and presents success or failure dialogs when interactive mode is enabled.,ghidra + rizin + llvm-objdump + strings
0x00489a20,1085,scenario_text_export_batch_process_maps,scenario,cdecl,inferred,ghidra-headless,4,Enumerates maps\\*.gmp and batch-processes every scenario through the scenario-text export branch. Command 0x7542 runs the build path through 0x004886e0 while command 0x7543 runs the report path through 0x00489830; the wrapper tracks progress formats per-map status strings and emits a final summary dialog.,ghidra + rizin + llvm-objdump + strings
0x00468d00,222,multiplayer_update_semicolon_name_list,shell,cdecl,inferred,ghidra-headless,4,Adds or removes one player-name token in the semicolon-delimited moderation list rooted at `[ecx+0x905c]`. With mode `1` it appends the supplied token only when not already present writing `;` as the delimiter; with mode `0` it removes the matched token collapses the remainder left and skips an adjacent delimiter when present.,ghidra + rizin + llvm-objdump + strings
0x00468de0,14,multiplayer_session_event_forward_action1_request,shell,unknown,inferred,ghidra-headless,2,Session-event callback wrapper that always forwards request id `1` through multiplayer_set_pending_session_substate with a zero auxiliary payload. The callback clears EDX before the shared setter call and currently lands on a request id that does not yet map to a visible pending substate so this row remains structural.,ghidra + rizin + llvm-objdump
0x00468e00,188,multiplayer_session_event_publish_pair_chat_template,shell,unknown,inferred,ghidra-headless,3,Session-event callback that formats one two-string chat/status line through multiplayer_route_chat_line when the callback status in EDX is zero and the current live session count is not positive. A selector near `[esp+0x214]` chooses the template `%s* %s` `%s %s` or `%s > %s`; the helper length-checks both inputs against the local 0x1f4-byte buffer before formatting and returns without publishing when either string is null or too long.,ghidra + rizin + llvm-objdump + strings
0x00468ec0,144,multiplayer_session_event_publish_action2_single_name,shell,unknown,inferred,ghidra-headless,3,Session-event callback wrapper for the one-name action-2 status path. When the callback status in EDX is zero and the current session count is positive it length-checks the supplied name formats localized text id `0xb73` routes the resulting line through multiplayer_route_chat_line and then forwards request id `2` through multiplayer_set_pending_session_substate with that same name payload. The currently grounded setter does not visibly store a pending substate for id `2` so this row stays partly structural.,ghidra + rizin + llvm-objdump
0x00468f50,192,multiplayer_session_event_publish_action2_pair,shell,unknown,inferred,ghidra-headless,3,Session-event callback wrapper for the two-string action-2 status path. When the callback status in EDX is zero and the supplied name lengths fit within the local buffer it formats localized text id `0xb74` or `0xe34` depending on whether the first string is present routes the resulting line through multiplayer_route_chat_line and then forwards request id `2` through multiplayer_set_pending_session_substate with the second string as the target payload and the first string as the auxiliary payload. The currently grounded setter does not visibly store a pending substate for id `2` so this row stays partly structural.,ghidra + rizin + llvm-objdump
0x00469010,30,multiplayer_session_event_forward_action4_request,shell,unknown,inferred,ghidra-headless,3,Session-event callback wrapper that forwards request id `4` only when both supplied payload pointers are non-null. It passes the second stack argument as the action payload and a zero auxiliary argument through multiplayer_set_pending_session_substate. The currently grounded setter does not visibly store a pending substate for id `4` so this row remains structural.,ghidra + rizin + llvm-objdump
0x00469030,30,multiplayer_session_event_forward_action7_request,shell,unknown,inferred,ghidra-headless,2,Session-event callback wrapper that forwards one payload pointer through multiplayer_set_pending_session_substate with request id `7` when the callback status in EDX is nonzero. The wrapper normalizes its incoming pointer into the second stack slot before tail-calling the shared setter but the currently grounded setter does not map request id `7` to a visible pending substate so this row remains structural.,ghidra + rizin + llvm-objdump
0x00469060,3,multiplayer_session_event_noop_12byte_stub,shell,unknown,inferred,ghidra-headless,4,Three-byte no-op callback stub in the Multiplayer.win session-event registration table. It returns immediately with `ret 0xc` and does not touch any state.,ghidra + rizin + llvm-objdump
0x00469070,87,multiplayer_session_event_publish_status_value,shell,unknown,inferred,ghidra-headless,3,Session-event callback that publishes one status value into the destination text builder passed in the third stack argument. It first compares the supplied index against the live session count from `0x006d40d0`; out-of-range entries publish the fixed fallback text at `0x005c87a8`; in-range entries publish integer `100` through 0x0058cd40 when event code EDX is `0x18`; publish the string at `0x00521d40+0x08` when EDX is `0x15`; and otherwise fall back to the same fixed text token.,ghidra + rizin + llvm-objdump + strings
0x004690d0,15,multiplayer_session_event_publish_fixed_status_text,shell,unknown,inferred,ghidra-headless,3,Session-event callback that appends the fixed status text token at `0x005c87a8` into the destination text builder passed in the second stack argument. This is the smallest text-publisher sibling in the same callback family and shares the same append helper 0x0058bce0 used by 0x00469070.,ghidra + rizin + llvm-objdump
0x004690f0,106,multiplayer_session_event_seed_control_id_list,shell,unknown,inferred,ghidra-headless,3,Session-event callback that seeds a byte-list builder with the fixed control-id set `3 1 8 10 11 19 4 5` when the callback status in EDX is zero. It appends each id through 0x0058bcb0 into the destination builder passed in the first stack argument and returns immediately when the callback status is nonzero.,ghidra + rizin + llvm-objdump
0x00469160,26,multiplayer_session_event_query_session_count,shell,unknown,inferred,ghidra-headless,4,Session-event callback helper that returns the live session count from `0x006d40d0` through 0x00521670 only when the callback mode in EDX equals `1`; all other modes return zero. This looks like the count-query slot in the same registration table.,ghidra + rizin + llvm-objdump
0x00469180,3,multiplayer_session_event_noop_8byte_stub,shell,unknown,inferred,ghidra-headless,4,Three-byte no-op callback stub in the Multiplayer.win session-event registration table. It returns immediately with `ret 8` and does not touch any state.,ghidra + rizin + llvm-objdump
0x00469190,8,multiplayer_session_event_latch_status_code,shell,unknown,inferred,ghidra-headless,4,Small session-event callback helper that stores the incoming status code from EDX into `0x006cd974` and returns. The registration branch later clears the same global before transport teardown or retry reset.,ghidra + rizin + llvm-objdump
0x004691a0,45,multiplayer_session_event_notify_owner_and_queue_action8,shell,unknown,inferred,ghidra-headless,3,Session-event callback wrapper that first notifies the current Multiplayer.win owner through multiplayer_notify_window_owner. When the callback status in EDX is zero it then queues request id `8` through multiplayer_set_pending_session_substate with the same payload pointer; otherwise it returns after the owner notification only.,ghidra + rizin + llvm-objdump
0x004691d0,39,multiplayer_find_session_event_capacity_entry,shell,unknown,inferred,ghidra-headless,4,Scans the fixed 0x80-entry session-event capacity array for a live record owned by the supplied key pointer in EDX. Each 0x11c-byte record is live when [entry+0x104] is nonzero and a match requires [entry+0x10c] to equal the incoming key. The helper returns the matched entry pointer or null.,ghidra + rizin + llvm-objdump
0x00469200,428,multiplayer_sync_session_event_capacity_entry,shell,unknown,inferred,ghidra-headless,3,Session-event cache-field callback that creates updates or clears one cached capacity record for the supplied owner key. Mode `0` creates the first free 0x11c-byte record when none exists mode `1` updates an existing record and mode `2` clears an existing record by zeroing [entry+0x104]. The create and update paths store the owner key at [entry+0x10c] seed [entry+0x104] with 0x2328 resolve `numplayers` and `maxplayers` handles through 0x0058d6d0 and copy the current display string into [entry+0x84].,ghidra + rizin + llvm-objdump + strings
0x004693b0,80,multiplayer_session_event_cache_line_callback,shell,unknown,inferred,ghidra-headless,4,Transport-side callback that appends one incoming status line into the cached session-event line store at `0x006ae4d8`. When the callback status in EDX is nonzero and the incoming line pointer is valid it copies the string from the third stack argument into slot `0x006cd97c << 8` subject to the `0x1f4` entry cap and a small flag filter on the fourth stack argument then increments `0x006cd97c` for later iteration.,ghidra + rizin + llvm-objdump
0x00469410,56,multiplayer_init_session_event_transport_state,shell,unknown,inferred,ghidra-headless,3,Initializes the Multiplayer.win session-event transport state rooted at `0x006cd970`. The helper latches the incoming mode or state into `0x006cd978`; when that value is nonzero it zeroes the large scratch block at `0x006ae4d8` resets `0x006cd97c` and registers the cached-line callback block rooted at `0x004693b0` through multiplayer_transport_register_selector_callback before returning.,ghidra + rizin + llvm-objdump
0x00469450,97,multiplayer_teardown_session_event_transport,shell,unknown,inferred,ghidra-headless,3,Tears down the active session-event transport object at `0x006cd970`. When the latched mode at `0x006cd978` is nonzero and the multiplayer session object at `0x006cd920` exists it first switches the transport back to status route `0` through multiplayer_transport_select_status_route clears the status pump through multiplayer_transport_clear_status_pump disconnects through multiplayer_transport_disconnect shuts the object down through multiplayer_transport_shutdown and finally clears `0x006cd970`.,ghidra + rizin + llvm-objdump
0x004694c0,57,multiplayer_publish_session_event_fixed_token,shell,unknown,inferred,ghidra-headless,3,Small session-event transport helper that publishes one fixed token through the active transport object when the latched mode and multiplayer session object are both present. It first switches the transport to status route `1` through multiplayer_transport_select_status_route and then sends the fixed token at `0x005c87a8` plus flag `1` through multiplayer_transport_publish_fixed_token_message. The current grounded caller is the Multiplayer.win branch at `0x0046c3c0`.,ghidra + rizin + llvm-objdump + strings
0x00469500,27,multiplayer_flush_session_event_transport,shell,unknown,inferred,ghidra-headless,3,Lightweight session-event transport flush wrapper. When the active transport object at `0x006cd970` exists it first forces a status flush through multiplayer_transport_force_status_flush and then tail-calls multiplayer_transport_flush_and_maybe_shutdown on that same object.,ghidra + rizin + llvm-objdump
0x00469520,94,multiplayer_register_session_event_cache_fields,shell,unknown,inferred,ghidra-headless,3,Registers the session-event cache-field subscription set for the active Multiplayer.win object. When no multiplayer session object is present it marks `[this+0x8f18]` armed and subscribes callback `0x00469200` through multiplayer_transport_subscribe_field_callback_set with the fixed field-id list `3 1 4 8 10 11 19 5` rooted at `[this+0x10]`.,ghidra + rizin + llvm-objdump
0x00469580,65,multiplayer_begin_session_event_line_iteration,shell,unknown,inferred,ghidra-headless,4,Primes iteration over the cached session-event line store at `0x006ae4d8`. When the multiplayer session object at `0x006cd920` is absent it sets `[this+0x9874]` armed clears the cached line slots and line index at `0x006cd97c` and re-registers the line callback `0x004693b0` through multiplayer_transport_register_selector_callback before returning.,ghidra + rizin + llvm-objdump
0x004695d0,66,multiplayer_next_session_event_cached_line,shell,unknown,inferred,ghidra-headless,4,Returns the next non-empty cached session-event line from the fixed store at `0x006ae4d8`. On first use after multiplayer_begin_session_event_line_iteration it resets `0x006cd97c` and clears `[this+0x9874]`; afterwards it returns the current 0x100-byte slot pointer when the first byte is nonzero and advances `0x006cd97c` or returns null when no further cached lines remain.,ghidra + rizin + llvm-objdump
0x00469620,52,multiplayer_submit_owner_notified_session_event_text,shell,unknown,inferred,ghidra-headless,3,Submits one caller-supplied text buffer through the active session-event transport using callback multiplayer_session_event_notify_owner_and_queue_action8. The helper first sanitizes the input string into a local 0x100-byte transport record through multiplayer_transport_sanitize_identifier and then forwards that record through multiplayer_transport_submit_text_record with fixed mode arguments `0` and `1`.,ghidra + rizin + llvm-objdump
0x00469660,27,multiplayer_send_session_event_text_selector0,shell,unknown,inferred,ghidra-headless,3,Thin session-event transport wrapper that sends one caller-supplied text pointer through multiplayer_transport_send_selector_text with selector `0` when the pointer is non-null. The current grounded caller is the Multiplayer.win control dispatcher around `0x00469d30`.,ghidra + rizin + llvm-objdump
0x00469680,14,multiplayer_pump_session_event_status,shell,unknown,inferred,ghidra-headless,3,Thin session-event transport wrapper that immediately requests a status pump through multiplayer_transport_request_status_pump on the active transport object at `0x006cd970` and discards one stack argument. Current grounded callers use it after updating Multiplayer.win status text ids `0xe60` and `0xe61`.,ghidra + rizin + llvm-objdump
0x0046a6c0,307,multiplayer_session_event_publish_registration_field,shell,unknown,inferred,ghidra-headless,3,Switch-driven session-event callback that publishes one Multiplayer.win registration/status field into the destination builder passed on the stack. Depending on selector EDX it emits the local session name from `0x006cec74` the profile text at `0x006cd8d8+0x8e10` the constant `0x2328` the live session count from `0x006d40d0` the field at `[0x006d1270+0x3b6]` the active profile string at `[0x006cec7c+0x44]` or fixed strings such as `Initializing...` `openstaging` and `closedplaying`; unsupported selectors fall back to the fixed token at `0x005c87a8`.,ghidra + rizin + llvm-objdump + strings
0x0046a830,194,multiplayer_session_event_retry_with_random_player_name,shell,unknown,inferred,ghidra-headless,3,Registration-side callback that increments the retry counter at `0x006cd984` and on early retries formats a randomized `RT3Player%d` name into `0x006ae0c0` sanitizes it into a local notification object notifies the current Multiplayer.win owner and forwards that object through multiplayer_transport_set_local_name. On the first retry it also routes request id `5` or `6` through multiplayer_set_pending_session_substate depending on the incoming status flag; after 25 retries it resets `0x006cd984` and `0x006cd974` and calls multiplayer_transport_reset_and_maybe_shutdown instead.,ghidra + rizin + llvm-objdump + strings
0x0046a900,522,multiplayer_register_session_event_callbacks,shell,thiscall,inferred,ghidra-headless,4,Builds and registers the Multiplayer.win session-event callback table rooted at the local block on `[esp+0x28]`. The function seeds slots with multiplayer_session_event_forward_action1_request multiplayer_session_event_publish_pair_chat_template multiplayer_session_event_publish_action2_single_name multiplayer_session_event_publish_action2_pair multiplayer_session_event_forward_action4_request multiplayer_session_event_forward_action7_request multiplayer_session_event_noop_12byte_stub multiplayer_session_event_publish_registration_field multiplayer_session_event_publish_status_value multiplayer_session_event_publish_fixed_status_text multiplayer_session_event_seed_control_id_list multiplayer_session_event_query_session_count multiplayer_session_event_noop_8byte_stub multiplayer_session_event_latch_status_code multiplayer_session_event_notify_owner_and_queue_action8 multiplayer_init_session_event_transport_state and multiplayer_session_event_retry_with_random_player_name. It allocates the transport callback object under `0x006cd970` stages the session name into the local descriptor block and then finishes registration through multiplayer_transport_register_callback_table which in turn routes through multiplayer_transport_attach_callback_table_descriptor multiplayer_transport_enqueue_descriptor_block_record and multiplayer_transport_dispatch_callback_table_binding.,ghidra + rizin + llvm-objdump + strings
0x0046c360,32,multiplayer_route_chat_line,shell,cdecl,inferred,ghidra-headless,3,Routes one multiplayer chat line through the active transport object at `0x006cec78` when present or falls back to the local Multiplayer.win chat publisher otherwise. The transport path forwards the supplied text into 0x4554e0 with fixed mode arguments `5 1 0`; the local fallback tail-calls multiplayer_publish_wrapped_chat_message.,ghidra + rizin + llvm-objdump
0x0046f960,2209,multiplayer_dispatch_chat_command,shell,cdecl,inferred,ghidra-headless,4,Parses and dispatches one slash-prefixed Multiplayer.win chat command line from `[eax+0x08]`. The parser normalizes `/` to `\\` and handles the grounded command family `\\kick` `\\clear` `\\whois` `\\me` `\\unban` `\\ban` `\\snore` `\\sneeze` `\\hurry` `\\trackisfree` `\\loadgame` and `\\sendgame`. The strongest branches are now clear: `\\kick` resolves a typed peer name through the active session tables and forwards the resulting peer object through multiplayer_request_peer_session_control when the target is neither null nor the local player; `\\clear` clears the local chat pane through multiplayer_publish_wrapped_chat_message(null); `\\whois` finds a named peer and emits multi-line `%s Ip = %s` `Cpu` `Game` and `Build Time` diagnostics through multiplayer_route_chat_line; `\\ban` and `\\unban` resolve either a dotted player name or the selected peer name then update the semicolon-delimited moderation list through multiplayer_update_semicolon_name_list with add/remove modes while `\\unban` can also forward a live peer object through multiplayer_request_peer_session_control; `\\snore` `\\sneeze` and `\\hurry` build transient presentation objects then broadcast text ids `0xb79` `0xb7a` and `0xb7b`; `\\loadgame` copies the requested filename into `0x006ce630` and arms flag `0x006ce9bc`; `\\trackisfree` arms flag `0x006ce9b4`; and `\\sendgame` allocates one 0x5c-byte transfer record under `0x006ce290` for the chosen player slot. The parser returns `1` only when a command branch handled the line and otherwise leaves the caller to treat it as ordinary chat text.,ghidra + rizin + llvm-objdump + strings
0x00470210,119,multiplayer_submit_chat_or_command_line,shell,cdecl,inferred,ghidra-headless,4,Submits one Multiplayer.win chat-entry line. The wrapper first calls multiplayer_dispatch_chat_command on the raw line buffer; when the parser returns zero it formats a normal `%s > %s` named chat line from the sender object at `[edi+0x08]` and the message payload; then either publishes it locally through multiplayer_publish_wrapped_chat_message or routes it through the active transport object at `0x006cec78`. When the parser returns nonzero the wrapper skips normal chat formatting because the slash-command branch already consumed the line.,ghidra + rizin + llvm-objdump + strings
0x004ecc90,52,multiplayer_set_pending_session_substate,shell,unknown,inferred,ghidra-headless,2,Small pending-session-substate setter used by the multiplayer session-event callback family. The grounded stores are request id `5` to substate `5` request id `6` to substate `6` and request id `8` to substate `8` at `0x006d1288`. Other current callback-family callers still pass ids `1` `2` `4` and `7` without a visible store in this helper so this row stays structural for now.,ghidra + rizin + llvm-objdump
0x004edce0,19,multiplayer_notify_window_owner,shell,unknown,inferred,ghidra-headless,3,Thin Multiplayer.win owner-notification wrapper. It loads the current window owner singleton from `0x006d1268` and when present forwards the supplied payload pointer into 0x004eccd0 for owner-side handling; current grounded callers are the session-event callback family around 0x004691a0 and the related registration path near 0x0046a8b3.,ghidra + rizin + llvm-objdump
0x004ecb20,101,multiplayer_reset_local_session_slot_state,shell,cdecl,inferred,ghidra-headless,4,Resets the local Multiplayer.win session-slot state before window init or add-open-slot flows. The helper marks the local state at `0x006cec7c+0x97` initialized clears the local slot counters at `+0x79` and `+0x7b` zeroes the slot-marker bytes at `+0x87` clears the local summary block at `+0x44` and zero-fills the large session backing block at `0x006d1270` when present.,ghidra + rizin + llvm-objdump
0x004ecb90,191,multiplayer_probe_or_allocate_open_player_slot,shell,cdecl,inferred,ghidra-headless,3,Probes or allocates one open local player-slot marker against the active Multiplayer.win session block at 0x006d1270. In probe mode `ecx=1` the helper checks that the local open-slot count and slot-marker bytes at `0x006cec7c+0x87` still fit within the remote slot counts and occupancy bytes rooted at `session+0x31b` and `session+0x3a3` and returns nonzero only when one additional slot can be claimed. In allocate mode `ecx=0` it finds the first locally empty slot whose remote occupancy byte is nonzero writes marker `0x64+index` into the local slot array increments `0x006cec7c+0x7b` and returns `0xff` on success.,ghidra + rizin + llvm-objdump
0x004ed590,224,multiplayer_sync_staged_text_controls,shell,cdecl,inferred,ghidra-headless,3,Synchronizes the shared Multiplayer.win staged-text buffer into the two mirrored text controls at ids 0xe48 and 0xe5d and then copies the same string back into the active selection buffer at 0x006cec74+0x1ef when it changed. The helper reallocates each control-owned backing string as needed and is used from the larger window initializer pending-status service and one delayed service-loop recovery branch.,ghidra + rizin + llvm-objdump
0x004ed890,164,multiplayer_schedule_requested_action,shell,cdecl,inferred,ghidra-headless,3,Initializes one requested Multiplayer.win action and resets the shared action globals before later dispatch. The helper writes the requested action id from EDI into 0x006d127c marks the action-active bit at 0x006d1274 clears the pending-step and substate fields at 0x006d1278 0x006d1280 and 0x006d1288 tears down the prior helper object at 0x006d1294 and allocates a fresh 0x10-byte helper. The currently named action writers above it queue action ids 1 and 4 from preview-dataset reset 2 from staged text-entry dialog setup 3 from staged text-entry commit and 5 or 6 from selected-preview follow-up branches.,ghidra + rizin + llvm-objdump
0x004ed940,235,multiplayer_rebuild_open_player_slot_markers,shell,cdecl,inferred,ghidra-headless,3,Rebuilds the local Multiplayer.win open-player slot markers from the active session slot table and republishes the resulting count. The helper clears any existing local slot bytes above `0x64` from `0x006cec7c+0x87` while decrementing `0x006cec7c+0x7b` then walks the remote slot records at `session+0x31b` with count `session+0x3ae`. For each remotely open record it uses multiplayer_probe_or_allocate_open_player_slot to claim the next local marker when capacity remains and then formats the updated open-slot count into shell control `0x6f` with resource id `0xe36`.,ghidra + rizin + llvm-objdump
0x004edc40,145,multiplayer_reset_preview_dataset_and_request_action,shell,cdecl,inferred,ghidra-headless,3,Resets the active Multiplayer.win preview dataset object at 0x006cd8d8 and immediately schedules the next requested action. The helper destroys any existing 0x9898-byte dataset object allocates and constructs a fresh one through 0x004ed800 clears the text control at id 0xe47 and the staged entry buffer at 0x006d11a8 and then queues action id 1 when the caller passes zero or action id 4 when the caller passes a nonzero dataset-related value.,ghidra + rizin + llvm-objdump
0x004ee0e0,225,multiplayer_open_staged_text_entry_dialog,shell,cdecl,inferred,ghidra-headless,3,Opens the small Multiplayer.win staged text-entry dialog and queues requested action 2. The helper chooses one of two prompt ids from the current preview mode copies the current profile text from 0x006cec74+0x1ef into the staging buffer at 0x006d1128 persists the profile state through 0x00484910 builds a formatted prompt string through 0x00518de0 and opens the modal shell dialog through 0x004c98a0 with the local callbacks at 0x004ed100 and 0x004ed4c0 before queuing action 2.,ghidra + rizin + llvm-objdump
0x004ee1d0,456,multiplayer_commit_staged_text_entry,shell,cdecl,inferred,ghidra-headless,3,Commits one staged Multiplayer.win text entry and queues requested action 3 when validation succeeds. The helper refreshes the mode-dependent prompt text saves the shared profile state through 0x00484910 copies either the caller-provided string or the text control 0xe47 into the staging buffer at 0x006d11a8 derives the companion buffer at 0x006d1228 from the current preview object or fallback globals and when the staged text exceeds five bytes schedules action 3 through multiplayer_schedule_requested_action; otherwise it clears the staged buffer and text control.,ghidra + rizin + llvm-objdump
0x004ee3a0,244,multiplayer_reset_tool_globals,shell,thiscall,inferred,ghidra-headless,3,Resets the smaller multiplayer-tool singleton state rooted around 0x006d1268 through 0x006d1270 for one shell mode created from 0x00482ec0. The helper seeds the shared vtable clears or rebinds the active singleton pointers and performs the same early shell-service notifications used by the larger Multiplayer.win initializer before later selection or preview code runs.,ghidra + rizin + llvm-objdump + strings
0x004ee430,141,multiplayer_update_preview_mode_labels,shell,cdecl,inferred,ghidra-headless,3,Updates the small mode-dependent label widget pair used by the Multiplayer.win preview branch. The helper chooses one of two label-id pairs anchored by string ids 0xe12 0xe18 and 0xe73 then writes them through 0x00540120 into shell controls such as ids 0x65 0x6d 0x86 and 0x87. It is called from multiplayer_load_selected_map_preview_surface the larger multiplayer initializer and the restore-from-globals callback.,ghidra + rizin + llvm-objdump + strings
0x004ee4c0,49,multiplayer_publish_control_0x69_mode,shell,cdecl,inferred,ghidra-headless,2,Publishes the current mode for Multiplayer.win control 0x69 from the presence of the session-related singleton at 0x006d40dc. The helper pushes mode 3 when that object exists or mode 1 otherwise through 0x00469d30 and is used after preview and count-setting branches to keep that control in sync with session state.,ghidra + rizin + llvm-objdump
0x004ee500,50,multiplayer_are_all_peer_ready,shell,cdecl,inferred,ghidra-headless,4,Returns true only when every element in the shell-owned multiplayer peer list exposed through 0x00521680 has ready flag bit 0x01 set at offset +0x5c. The service loop uses this gate before committing the larger multiplayer launch or transition branch.,ghidra + rizin + llvm-objdump
0x004ee540,352,multiplayer_refresh_peer_roster_list,shell,cdecl,inferred,ghidra-headless,3,Refreshes the Multiplayer.win peer-roster list for preview modes 0xe12 and 0xe13. The helper chooses one of two mode-dependent text ids updates control 0x8b when the current roster selection is valid enumerates either the direct peer list at 0x006d40d0 or the fallback dataset-backed names from 0x006cd8d8 into repeated control-0x88 entries and when no roster entries remain forces a preview-dataset reset through multiplayer_reset_preview_dataset_and_request_action. It also republishes one session-state byte into shell control 9 before returning.,ghidra + rizin + llvm-objdump
0x004ee6a0,359,multiplayer_refresh_map_entry_list,shell,cdecl,inferred,ghidra-headless,3,Refreshes the Multiplayer.win map-entry list for preview modes 0xe11 and 0xe13. The helper chooses one of two mode-dependent text ids writes the active selection header into control 0x8b walks up to 0x80 0x11c-byte records from the list object exposed by control 0xe47 publishes each entry into repeated control-0x88 rows and mirrors the currently selected matching row into control 0x66. The comparison path uses the current staged selection text copied into a local buffer before the list walk.,ghidra + rizin + llvm-objdump
0x004ee810,308,multiplayer_publish_wrapped_chat_message,shell,cdecl,inferred,ghidra-headless,4,Publishes one Multiplayer.win chat or status message into the mode-dependent chat pane. The helper chooses text resource `0xe32` or `0xe5c` from the current preview mode at `[window+0x7c]`; resolves the corresponding text list object through `0x0053f830`; word-wraps the supplied string to width `0x3e`; emits each wrapped row into control `0x88` through `0x00540120`; stores per-row metadata back into the list object; and finally updates the summary row in control `0x66` or clears the pane when the caller passes a null string. It is used by the local chat transport fallback; the named `%s > %s` message publisher; and the Multiplayer.win launch-side action wrappers.,ghidra + rizin + llvm-objdump + strings
0x004eed30,208,multiplayer_sync_selected_map_entry,shell,cdecl,inferred,ghidra-headless,3,Selection wrapper above 0x004ee950 for the multiplayer map-preview branch. It walks the current 0x25a-byte multiplayer entry table compares the selected record string against the shell selection buffer near 0x006cec7c and then calls 0x004ee950 with either the matching strings or null inputs to refresh the active preview state.,ghidra + rizin + llvm-objdump
0x004ee950,982,multiplayer_load_selected_map_preview_surface,shell,cdecl,inferred,ghidra-headless,4,Loads or refreshes the currently selected .gmt-backed preview surface for the multiplayer window family rooted at 0x006d1270. The routine validates the selected filename suffix copies selected strings into the active record updates preview or status values under offsets such as +0x3b2 and +0x3b6 formats several shell text fields through 0x00540120 and finishes by decoding a 256x256 image through 0x0053f830 and surface_init_rgba_pixel_buffer. The branch is anchored by the larger Multiplayer.win initializer at 0x004efe80.,ghidra + rizin + llvm-objdump + strings
0x004eee00,649,multiplayer_refresh_map_preview_panel,shell,cdecl,inferred,ghidra-headless,3,Refreshes the multiplayer map-preview panel for one requested preview state or sentinel value. The helper stores the requested state at [this+0x78] updates several shell text fields through 0x00540120 handles the special active state 0xe15 and the fallback -1 case copies the selected entry strings out of the multiplayer entry table at 0x006d126c into the shell selection buffer near 0x006cec7c and then routes through multiplayer_sync_selected_map_entry or multiplayer_load_selected_map_preview_surface before returning.,ghidra + rizin + llvm-objdump + strings
0x004ef090,365,multiplayer_select_preview_mode_and_refresh,shell,cdecl,inferred,ghidra-headless,3,Selects one of the top-level multiplayer preview modes identified by command ids 0xe10 through 0xe13 then refreshes the preview panel. The helper stores the requested mode at [this+0x7c] updates the four mode-button states through 0x00540120 handles the special 0xe12 branch with extra multiplayer refresh helpers and a direct multiplayer_refresh_map_preview_panel call for state 0xe15 emits a summary status field at 0xe55 falls back through multiplayer_refresh_map_preview_panel(-1) and finally refreshes the panel timestamp at [this+0x80] through 0x0051d890.,ghidra + rizin + llvm-objdump + strings
0x004ef200,1786,multiplayer_service_pending_status_state_machine,shell,cdecl,inferred,ghidra-headless,4,Services the pending Multiplayer.win status or transition state machine when the global flag at `0x006d1278` is set. The routine clears the pending flag switches over the queued step id at `0x006d1280` and now has several grounded branches: step `1` builds modal status `0xe4f` optionally appends owner text from `0x006d4118/0x006d411c` tears down the preview dataset at `0x006cd8d8` and refreshes control `0xcc`; step `2` clears `0x006cd920` destroys the preview dataset and opens status `0xe50`; step `3` gates on latch byte `0x006d1292` and warns with `0xe51`; step `4` requires `0x006cd920 != 0` and `0x006ae3c8 >= 3` or warns with `0xe52` otherwise it seeds a random `RT3Player%d` name into the staged-text controls through multiplayer_sync_staged_text_controls and sets `0x006ae3c4 = 2`; step `5` opens status `0xe54` then rebuilds the preview dataset through multiplayer_reset_preview_dataset_and_request_action. A second substate switch on `0x006d1284` formats statuses `0xe55..0xe5f` `0xe92` and `0xf53`; its `0x5` and `0x8` families either force preview mode `0xe13` or reseed the default player-name path before syncing the staged-text controls.,ghidra + rizin + llvm-objdump + strings
0x004ef960,1260,multiplayer_dispatch_requested_action,shell,cdecl,inferred,ghidra-headless,4,Dispatches the current requested Multiplayer.win action stored in `0x006d127c`. The switch drives six higher-level action cases that combine immediate mode changes through multiplayer_select_preview_mode_and_refresh with deferred pending-step writes into `0x006d1278` and `0x006d1280`. The grounded wrappers are now broader than before: action `1` either enters preview mode `0xe11` immediately or schedules pending step `1`; action `2` resets the local session-slot state through multiplayer_reset_local_session_slot_state copies the staged text buffers into the active dataset seeds one local open-slot marker refreshes the local player rows enters preview mode `0xe12` and rebuilds the open-slot markers; action `3` copies the staged text buffers back into the active multiplayer object and then uses the dataset mode at `[0x006cd8d8+0x0c]` to schedule pending steps `0xa` `0xb` `0xc` `0xe` or fallback `0x2` while its resolved-mode branch re-enters preview mode `0xe12` clears latches `0x006d1291/0x006d1292` and seeds the local player panel; action `4` promotes the committed staged text into preview mode `0xe13` or schedules pending step `5` or `6` from the launcher substate at `0x006d1288`; action `5` pumps the selected-map follow-up callback then either rebuilds the open-slot markers and refreshes status control `0x109` or schedules pending step `1` with control `0x11` updates depending on the current launch-side state; action `6` validates the staged text against the active dataset and schedules pending step `6` when the launcher substate remains armed.,ghidra + rizin + llvm-objdump
0x004efe80,1388,multiplayer_window_init_globals,shell,thiscall,inferred,ghidra-headless,4,Initializes the Multiplayer.win shell window family and its large backing state block. The constructor seeds the shared vtable at 0x005d12ac clears multiplayer globals under 0x006d1274 through 0x006d1288 allocates and zeroes a 0x100f2-byte data block stored at 0x006d1270 registers the active singleton at 0x006d1268 pushes the Multiplayer.win resource into the standard shell window setup helper and then continues with multiplayer-specific list and status initialization.,ghidra + rizin + llvm-objdump + strings
0x004f03f0,3612,multiplayer_window_service_loop,shell,cdecl,inferred,ghidra-headless,3,Top-level Multiplayer.win service loop. The function performs an early startup countdown through `0x006cd90c` calls multiplayer_service_pending_status_state_machine processes the special pending-step-10 gate with latch byte `0x006d1292` clears one text field when pending step 2 completes and then continues into the broader multiplayer update loop with timed retries staged-text synchronization peer-roster and map-entry list refresh helpers object-state checks and several mode-specific update branches. It queues requested action 5 after rebuilding one selected-map preview follow-up path and requested action 6 after the validated staged-text follow-up dialog branch. The launch-side inline wrappers now separate into three behaviors: a peers-not-ready warning dialog on resource `0xf15`; an add-open-slot path that seeds `0x006cec7c+0x83` stores the callback owner in `0x006d4110` and refreshes status control `0x109`; and a missing-session or slot-capacity warning path that opens modal dialogs on resources `0x2cf` `0x2b8` or `0x2b9`.,ghidra + rizin + llvm-objdump
0x004f13e0,167,multiplayer_restore_preview_state_from_globals,shell,thiscall,inferred,ghidra-headless,3,Restores the Multiplayer.win preview UI from the current global mode and preview-state fields. The callback refreshes the mode-dependent labels through multiplayer_update_preview_mode_labels mirrors selection presence into the active shell object toggles the 0x006d1291 recursion guard replays multiplayer_select_preview_mode_and_refresh and multiplayer_refresh_map_preview_panel using the saved fields at [this+0x7c] and [this+0x78] and if the active preview resources are missing schedules pending status step 7 by writing 0x006d1278 and 0x006d1280 instead of forcing an immediate redraw.,ghidra + rizin + llvm-objdump + strings
0x00502220,813,paint_terrain_load_selected_gmt_surface,shell,cdecl,inferred,ghidra-headless,4,Loads or refreshes the currently selected .gmt-backed preview surface for the PaintTerrain tool family rooted at 0x006d14bc and tied to the PaintTerrain.win or GroundTerrain.tga branch. The routine validates the selected filename suffix copies selected strings into the active record updates tool status bytes and counters formats several shell text fields through 0x00540120 and finishes by decoding a 256x256 image through 0x0053f830 and surface_init_rgba_pixel_buffer.,ghidra + rizin + llvm-objdump + strings
0x00502550,456,paint_terrain_refresh_status_panel,shell,cdecl,inferred,ghidra-headless,3,Refreshes the PaintTerrain tool status or selection panel after the active .gmt surface changes. The helper reads the PaintTerrain singleton at 0x006d14bc consults shell selection globals and lookup tables formats several text or numeric fields through 0x00540120 and toggles the side flag at 0x006d14a8 before returning.,ghidra + rizin + llvm-objdump + strings
0x00502720,144,paint_terrain_tool_init_globals,shell,thiscall,inferred,ghidra-headless,4,Initializes the PaintTerrain shell tool singleton rooted at 0x006d14bc. The constructor seeds the tool vtable and default fields registers the active instance globally and is selected directly from shell_transition_mode alongside the neighboring terrain-edit tool constructor at 0x004ee3a0.,ghidra + rizin + llvm-objdump + strings
0x00481d00,612,bootstrap_parse_command_line_flags,bootstrap,cdecl,inferred,ghidra-headless,4,Parses the startup command line from ECX handling slash and dash switches and writes multiple bootstrap globals and option buffers before shell service init.,ghidra + rizin
0x00481fd0,348,bootstrap_scan_autorun_media,bootstrap,cdecl,inferred,ghidra-headless,4,Scans drive letters for RT3 autorun marker files rt3d1.txt and rt3d2.txt using GetDriveTypeA and open or close helpers before deeper shell init.,ghidra + rizin
0x004821d0,1019,shell_recompute_layout_slots,bootstrap,thiscall,inferred,ghidra-headless,4,Recomputes the shell layout-slot table after resolution or related display selectors change; derives normalized coordinates from static float tables updates 144 slot entries through the shell bundle child at [0x006d4024+0x18] and then commits the refreshed state.,ghidra + rizin
0x00482ec0,1359,shell_transition_mode,bootstrap,thiscall,inferred,ghidra-headless,4,Switches the shell state's active mode at [this+0x08] tearing down any prior mode object selecting one of seven mode-specific handlers and updating globals like 0x006cec78 before notifying the shell bundle through 0x00538e50.,ghidra + rizin
0x005a2d64,101,crt_init_exit_handlers,startup,cdecl,inferred,ghidra-headless,3,Initializes on-exit tables and registers atexit handling before control reaches application startup.,ghidra + rizin
0x005a30f2,34,__amsg_exit,startup,cdecl,inferred,ghidra-headless,4,CRT fatal-exit helper that forwards startup failures into __exit.,ghidra + rizin
0x005a3117,36,crt_fast_error_exit,startup,cdecl,inferred,ghidra-headless,4,Startup error path that optionally emits the CRT banner then formats the failure and terminates through ___crtExitProcess.,ghidra + rizin
0x005a313b,423,crt_startup_entrypoint,startup,cdecl,inferred,ghidra-headless,4,PE entrypoint for patch 1.06; performs CRT and environment setup then validates early state before handing off to application bootstrap.,sha256:01b0d2496cddefd80e7e8678930e00b13eb8607dd4960096f527564f02af36d4 + ghidra + rizin + llvm-objdump
0x0053b020,70,bootstrap_reset_locale_state,bootstrap,unknown,inferred,ghidra-headless,2,Calls the locale helper at 0x0053ae70 then frees and clears related global pointers before later shell setup continues.,ghidra + rizin
0x0053b010,11,bootstrap_mark_runtime_started,bootstrap,cdecl,inferred,ghidra-headless,2,Single-purpose bootstrap helper that flips a process-global started flag to one before branding and shell setup continue.,ghidra + rizin
0x0054e6d0,42,bootstrap_capture_keyboard_state,bootstrap,cdecl,inferred,ghidra-headless,4,Single-purpose bootstrap probe that snapshots the host keyboard state through GetKeyboardState.,ghidra + rizin
0x0055da40,424,bootstrap_probe_system_profile,bootstrap,cdecl,inferred,ghidra-headless,4,Collects GlobalMemoryStatus and CPUID feature bits then stores coarse machine capability flags used by later bootstrap decisions.,ghidra + rizin
0x00507b90,346,geography_info_refresh_category_controls,map,cdecl,inferred,ghidra-headless,3,Refreshes the geography info category controls for the current panel mode stored at 0x00622af4. It emits the six-entry mode selector plus dependent label fields through 0x00540120 and in mode 5 it can seed [this+0x8c] from the current selection path before preview formatting continues.,ghidra + rizin + llvm-objdump
0x00508550,363,geography_info_format_selected_record_summary,map,cdecl,inferred,ghidra-headless,3,Formats the selected geography record summary for the info panel. It looks up the active record index [this+0x8c] in 0x0062b2fc follows secondary data through field +0x173 into 0x0062b268 computes scaled values against current shell state and emits the localized summary block through 0x00540120.,ghidra + rizin + llvm-objdump + strings
0x00508730,292,geography_info_format_preview_panel,map,cdecl,inferred,ghidra-headless,3,Formats the geography info preview panel for the currently selected record stored at [arg_4h+0x8c]. It chooses preview assets like 2DLabel.imb 2DCity.imb 2DVent.imb 2DMist.imb and 2DVolcano.imb and emits localized text blocks through repeated 0x00540120 calls using geography tables rooted at 0x0062b2fc and 0x0062b268.,ghidra + rizin + llvm-objdump + strings
0x00508880,727,geography_info_select_record_and_refresh,map,cdecl,inferred,ghidra-headless,3,Selects one geography record or category then refreshes the preview panel. It stores the requested mode at 0x00622af4 resolves a matching record from the geography tables formats localized headings and detail text calls 0x00508730 and then triggers the surrounding panel refresh path.,ghidra + rizin + llvm-objdump + strings
0x0051d900,155,string_find_substring_ex,support,cdecl,inferred,ghidra-headless,3,Reusable substring finder that returns a pointer to the first matching window in the haystack or null. It precomputes both string lengths then slides across the haystack calling one of two compare helpers depending on the mode flag pushed on the stack; the graphics branch uses it to probe adapter strings for legacy GPU-profile tokens and bootstrap code uses it for startup media or compatibility string checks.,ghidra + rizin + llvm-objdump
0x0051d870,21,bootstrap_seed_tick_count,bootstrap,cdecl,inferred,ghidra-headless,4,Lazily snapshots GetTickCount into a bootstrap-global cache so later subsystems start from a nonzero host tick baseline.,ghidra + rizin
0x0051ebc0,731,shell_reset_display_runtime_defaults,shell,cdecl,inferred,ghidra-headless,3,Resets the global display runtime defaults rooted at 0x006d4024. It clears the large display-settings block under offsets 0x11468a and above seeds default resolution and capability flags from mode 0x006d4028 and reinitializes several shell display toggles before later preset application continues.,ghidra + rizin + llvm-objdump
0x0051eea0,128,shell_save_display_runtime_config,shell,cdecl,inferred,ghidra-headless,4,Writes the larger display-runtime blob to data\\configuration\\engine.cfg. It stores version key 0x41b serializes the 0x1e4-byte runtime block rooted at [this+0x11468a] and writes an additional 0x1ec-byte companion block before closing the file.,ghidra + rizin + llvm-objdump + strings
0x0051ef20,194,shell_load_display_runtime_config_or_init_defaults,shell,cdecl,inferred,ghidra-headless,4,Loads the larger display-runtime blob from data\\configuration\\engine.cfg. When the file is missing invalid or already superseded by mode state at 0x006d4028 it falls back to 0x0051ebc0 and 0x0051eea0; otherwise it validates key 0x41b restores the 0x1e4-byte and 0x1ec-byte blocks and clears one shell display flag when [this+0x11474a] is set.,ghidra + rizin + llvm-objdump + strings
0x0051f1d0,90,shell_signal_deferred_work_item_shutdown,shell,thiscall,inferred,ghidra-headless,3,Walks the shell deferred-work item queue at [this+0x1136a5] and inspects each queued payload object's nested message queue at [item+0xe4]. When intrusive_queue_peek_tail_payload finds a nonnull tail payload it clears the outer queued-handle slot at [item+0xe8] and appends a null sentinel into the nested queue through intrusive_queue_push_back before continuing iteration.,ghidra + rizin + llvm-objdump
0x0051f230,128,shell_enqueue_deferred_work_message,shell,thiscall,inferred,ghidra-headless,4,Routes one deferred-work message through the shell queue system. When the global routing gate at 0x006d4034 and shell flag [this+0x11369c] are both set it feeds the special queue at [this+0x11369d]; otherwise a nonnull payload object is queued once in [this+0x1136a5] with the returned queue-node handle cached at [item+0xe8] and the message is appended to the payload-owned nested queue at [item+0xe4] while a null payload appends directly into the fallback queue at [this+0x1136a1].,ghidra + rizin + llvm-objdump
0x0051f2b0,104,shell_post_deferred_message_type5,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the shell-owned slab rooted at [this+0x5c] using count [this+0x58] tags it as type 0x05 stores four caller dwords at offsets +0x01 +0x05 +0x09 and +0x0d and then posts the record directly into the shell deferred queue roots through [this+0x11369d] or [this+0x1136a1].,ghidra + rizin + llvm-objdump
0x0051f320,72,shell_post_deferred_message_type6,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the same shell slab and tags it as type 0x06 before posting it directly into the shell deferred queue roots. This is the minimal direct-post sibling of the type-0x05 builder and uses the same count field at [this+0x58] and slab base at [this+0x5c].,ghidra + rizin + llvm-objdump
0x0051f370,229,shell_enqueue_deferred_message_type4,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the shell-local slab at [this+0x5c] populates the larger multi-field payload tags it as type 0x04 mixes the shell byte [this+0x114227] into record byte +0x5d and routes the finished record through shell_enqueue_deferred_work_message.,ghidra + rizin + llvm-objdump
0x0051f460,173,shell_enqueue_deferred_message_type1,shell,thiscall,inferred,ghidra-headless,4,Allocates one 0x5e-byte deferred-message record from the same shell-local slab fills the smaller type-0x01 payload subset mixes the shell byte [this+0x114227] into record byte +0x5d and routes the finished record through shell_enqueue_deferred_work_message.,ghidra + rizin + llvm-objdump
0x0051f510,48,shell_set_gamma_ramp_scalar,shell,thiscall,inferred,ghidra-headless,4,Applies one shell gamma-ramp scalar to the active display runtime state. When the presentation service pointer at [this+0x0c] is live it forwards the scalar into 0x00547f20 for an immediate hardware upload; otherwise it only caches the requested value at [this+0x1146b9] until the service is ready.,ghidra + rizin + llvm-objdump
0x0051fd70,516,shell_update_frame_time_history,shell,thiscall,inferred,ghidra-headless,4,Updates a 256-sample frame-time history from successive GetTickCount deltas. The helper advances the ring index in 0x006d403c stores each delta under [this+0x11428a] and derives a smoothed frame scalar at [this+0x114282] for later shell frame consumers such as 0x0051ff80 and the presentation-frame path.,ghidra + rizin + llvm-objdump
0x00521d10,38,multiplayer_request_peer_session_control,shell,cdecl,inferred,ghidra-headless,3,Requests one direct session-control action for a resolved multiplayer peer object. When the live session transport at `0x006d40dc` is present it follows the transport-owned interface at `[ecx+0x18e]->+0x08` and invokes vtable slot `+0x68` with the target peer object and three zero trailing arguments; the current grounded callers are the `\\kick` branch and the online-peer `\\unban` follow-up path.,ghidra + rizin + llvm-objdump
0x0051fa00,56,shell_get_memory_budget_ceiling_bytes,shell,thiscall,inferred,ghidra-headless,3,Returns the current upper memory-budget bucket in bytes for the shell display runtime. When override field [this+0x1146ca] is set it maps that tier through the shared table at 0x00624c34 containing 0 1MB 2MB and 4MB entries; otherwise it starts from baseline field [this+0x1136ad] and adjusts it by the active lower-tier delta derived from [this+0x1146c6] and [this+0x1136a9] before clamping negative results to zero.,ghidra + rizin + llvm-objdump
0x0051fa40,25,shell_get_memory_budget_floor_bytes,shell,thiscall,inferred,ghidra-headless,3,Returns the current lower memory-budget bucket in bytes for the shell display runtime. When field [this+0x1146c6] is nonzero it maps that tier through the shared 0 1MB 2MB 4MB table at 0x00624c34; otherwise it falls back to baseline field [this+0x1136a9].,ghidra + rizin + llvm-objdump
0x0051fa60,63,shell_get_nonnegative_memory_budget_floor_bytes,shell,thiscall,inferred,ghidra-headless,3,Returns a nonnegative lower memory-budget value for float consumers in the shell and presentation paths. It prefers explicit tier field [this+0x1146ce] then the active floor bucket behind [this+0x1146c6] and finally baseline field [this+0x1136a9] using the shared 0 1MB 2MB 4MB table at 0x00624c34 and clamping negative results to zero.,ghidra + rizin + llvm-objdump
0x005204b0,128,shell_flush_deferred_work_queues,shell,thiscall,inferred,ghidra-headless,3,Flushes the shell controller's three deferred-work queue roots at [this+0x1136a1] [this+0x11369d] and [this+0x1136a5]. The helper clears the first two containers through intrusive_queue_clear_and_release then rewinds the deferred-item queue through intrusive_queue_rewind_iterator repeatedly pops each queued payload through intrusive_queue_next_iterator_node clears its outer queued-handle slot at [item+0xe8] and finally releases the remaining queue storage before returning. It is used at the end of the shell frame cycle and from the broader shell-mode helper at 0x00443a50.,ghidra + rizin + llvm-objdump
0x00520620,141,shell_service_frame_cycle,shell,thiscall,inferred,ghidra-headless,3,Services one shell frame cycle for the active controller. When pending-frame state is armed through [this+0x56] and the controller pointers at [this+0x18] [this+0x1c] and [this+0x28] are live it runs the main presentation refresh through 0x0052b990 then updates frame timing through 0x0051fd70 runs the mouse-cursor frame updater 0x0053f4e0 requests the deeper layout-state rebuild path through 0x00565110 performs a one-time ShowWindow on [this] drains deferred work through 0x005204b0 and clears the pending flags at [this+0x56] and [this+0x58].,ghidra + rizin + llvm-objdump
0x00521060,805,bootstrap_init_shell_service_bundle,bootstrap,cdecl,inferred,ghidra-headless,4,Builds the shell-facing singleton bundle stored through globals like 0x006d4024 0x006d402c and 0x006d4030 wiring startup width and height state and an rt3_ prefixed service path.,ghidra + rizin
0x00521390,486,bootstrap_destroy_shell_service_bundle,bootstrap,cdecl,inferred,ghidra-headless,4,Destroys the shell service bundle created by 0x00521060 releasing each global singleton and clearing 0x006d4024 0x006d402c 0x006d4030 0x006d4020 and 0x006d4018.,ghidra + rizin
0x00523d90,65,shell_commit_layout_updates,bootstrap,thiscall,inferred,ghidra-headless,3,Applies pending layout-slot changes from the shell controller into its subordinate layout-state object at [this+0x2d] by walking embedded service pointers and issuing the follow-on rebuild or refresh calls that make the updated slot table live.,ghidra + rizin
0x00523e40,51,shell_invalidate_layout_state,bootstrap,thiscall,inferred,ghidra-headless,4,Marks the shell controller's layout-state path dirty by setting flags [this+0x3747] [this+0x3748] and [this+0x3749] then forwarding two state parameters into the subordinate object at [this+0x2d].,ghidra + rizin
0x005270d0,8,shell_mark_layout_dirty,bootstrap,thiscall,inferred,ghidra-headless,2,Marks the shell layout child dirty by setting byte flag [this+0x3749] before later code forces a commit pass.,ghidra + rizin
0x00527650,1476,shell_publish_texture_budget_report,shell,thiscall,inferred,ghidra-headless,4,Builds and publishes a shell-side texture budget report through the current layout state at [this+0x2d]. The routine formats the current memory-budget floor and ceiling buckets from 0x0051fa40 and 0x0051fa00 converts them to kilobytes adds the current texture-change counter through 0x0055d390 appends labels like Texture changes per frame Texture SRAM and Texture VRAM and forwards the assembled text into 0x00566980.,ghidra + rizin + llvm-objdump + strings
0x00527e10,868,shell_update_layout_tracking_sample,bootstrap,thiscall,inferred,ghidra-headless,4,Samples a tracked shell target from the object argument computes distance heading and orientation deltas against cached values at [this+0x36b8..0x36cc] consults the dirty flags and index helper at 0x00526590 and returns whether the controller should drive a fresh layout-state apply; on success it updates the cached sample fields and the global tick at 0x00cc3b4c.,ghidra + rizin
0x0052b990,4993,shell_refresh_presentation_frame,shell,thiscall,inferred,ghidra-headless,3,Main shell frame-style refresh pass for the active controller and layout-state path. It handles mode-sensitive layout-state rebuilds and dirties updates tracked shell samples through 0x00527e10 runs the nearby geographic-label static-cell animated-quad ranked-overlay and ranked-billboard sweeps applies presentation-node properties and cached vertex spans optionally publishes the texture budget report through 0x00527650 may request a deeper rebuild through 0x00565110 and can recurse once for a follow-up presentation pass before downstream timing or present helpers run.,ghidra + rizin + llvm-objdump
0x0052da00,102,vehicle_visual_register_attachment_object,bootstrap,thiscall,inferred,ghidra-headless,3,Registers one prebuilt attachment object on the owning vehicle visual. The helper lazily allocates a small attachment list at [this+0x81] pushes the object through 0x00556e10 copies the owner tint triple from [this+0x1e2] [this+0x1e6] and [this+0x1ea] into the object through 0x005545d0 and links the owner back through 0x005540a0.,ghidra + rizin + llvm-objdump
0x00529840,400,shell_build_static_cell_triangle_sweep,bootstrap,thiscall,inferred,ghidra-headless,4,Builds the fixed-cell triangle sweep over the grid returned by 0x00533cd0. It samples shell brightness to derive one grayscale packed color binds the layout-state vertex24 table once and then expands each accepted 0x24-byte cell record into six vertex24 records by emitting the same three-point face twice before committing the span and restoring presentation state.,ghidra + rizin + llvm-objdump
0x00529b50,1149,shell_build_geographic_label_vertex24_sweep,bootstrap,thiscall,inferred,ghidra-headless,4,Builds the geographic-label vertex24 sweep over the grid returned by 0x00533db0. It gates on config byte [this+0x29+0x63] primes one vertex24 span and text presentation state samples shell brightness and the 0x006d9098 priority map to derive per-item alpha rejects items through virtual check +0x0c emits per-item geographic-label frame geometry through 0x00539fb0 optionally emits geographic-label text through 0x0053a960 and commits buffered spans through the layout-state presentation helpers. The naming matches the dedicated geographic-label asset family backed by gpdLabelDB and 2DLabel.imb.,ghidra + rizin + llvm-objdump
0x00528d90,1824,shell_process_nearby_presentation_item,bootstrap,thiscall,inferred,ghidra-headless,3,Processes one candidate item for the nearby-presentation sweep. It rejects disabled entries and mode-mismatched flags optionally gates by forward-range tests around the caller origin lazily assigns the item's segment-record window from the layout-state tables stores accepted nearest-candidate distances in the side buffer at [this+0xa9] and [this+0xad] and forwards the item plus eligible child collections into the active presentation lists.,ghidra + rizin + llvm-objdump
0x005294b0,912,shell_update_nearby_presentation_sweep,bootstrap,thiscall,inferred,ghidra-headless,3,Performs the higher-level nearby-presentation sweep for the current shell state. It scans candidate cells from the offset table at [this+0x374f] using the priority map at 0x006d9098 enumerates item lists for each accepted cell normalizes the first accepted direction vector binds the segment-record presentation table through 0x0054bab0 calls 0x00528d90 for each candidate and then selects the nearest buffered item into [this+0x366e] before refreshing presentation batches through 0x00548da0.,ghidra + rizin + llvm-objdump
0x00529fd0,793,shell_build_cell_vertex24_sweep,bootstrap,thiscall,inferred,ghidra-headless,4,Builds the animated-quad cell sweep over the grid returned by 0x00533e30 depending on the boolean mode argument. It gates on configuration bytes [this+0x29+0x5f] or [this+0x29+0x60] walks candidate-cell offsets from [this+0x374f] selects the primary list at [cell+0x1c] or alternate list at [cell+0x20] initializes the layout-state vertex24 table once through 0x0054bb70 streams each list through 0x00567c70 or 0x00567ce0 and then commits the accumulated span through 0x00545c50 before restoring presentation state.,ghidra + rizin + llvm-objdump
0x0052a2f0,736,shell_build_ranked_overlay_vertex24_sweep,bootstrap,thiscall,inferred,ghidra-headless,3,Builds a ranked secondary vertex24 overlay pass over the cell grid returned by 0x00533e50 and two object collections at [this+0x85] and [this+0x81]. It computes a per-frame packed tint from the current shell brightness gathers and sorts candidate items by priority field [item+0x1d9] binds the layout-state vertex24 table and emits accepted items through 0x00524780 and 0x00554e70 before committing the span.,ghidra + rizin + llvm-objdump
0x0052a5d0,1784,shell_build_ranked_object_billboard_sweep,bootstrap,thiscall,inferred,ghidra-headless,3,Builds the sibling ranked object-overlay pass gated by config byte [this+0x29+0x5e]. It merges candidates from the object collections at [this+0x85] and [this+0x81] sorts them by priority field [item+0x1d9] prepares billboard basis state through 0x00566670 and emits accepted entries through 0x00554e70 before committing the vertex24 span.,ghidra + rizin + llvm-objdump
0x0052dd00,864,shell_expand_segment_record_triplets,bootstrap,thiscall,inferred,ghidra-headless,4,Expands one active presentation-batch record into three transformed 0x20-byte segment records inside the caller-provided buffer; each output record is two vec3 blocks at +0x00 and +0x0c plus scalar slots at +0x18 and +0x1c. The selected batch record supplies a source-array pointer at +0x04 a source-count at +0x0c and 0x4c-byte packed source entries that carry four point sources plus three scalar pairs for the emitted triplet.,ghidra + rizin
0x0053f4e0,739,mouse_cursor_update_frame_state,shell,thiscall,inferred,ghidra-headless,4,Per-frame MouseCursor.cpp updater for the global cursor controller at 0x00ccbb20. It refreshes elapsed tick state through 0x0051d890 re-arms the active cursor selection through 0x0053f450 and 0x0053f000 when the 150 ms and 15 s idle thresholds trip resets per-frame cursor globals through 0x0054f6c0 and 0x0054f6d0 samples cursor placement and world-relative state through world_anchor_measure_projected_half_width world_anchor_measure_projected_half_height and shell_queue_world_anchor_marker and publishes the resulting cursor presentation state through shell_publish_text_callout_presentation before finalizing through 0x0054f6e0.,ghidra + rizin + llvm-objdump + strings
0x0052e060,537,shell_expand_vertex24_triplets,bootstrap,thiscall,inferred,ghidra-headless,4,Sibling emitter for the same active presentation-batch record family; expands each 0x4c-byte packed source entry into three 0x18-byte vertex24 records in the caller-provided buffer. Each emitted record stores a vec3 at +0x00 a style dword from [this+0x43] at +0x0c and scalar slots at +0x10 and +0x14 while the output-count accumulator advances by count*3.,ghidra + rizin
0x0052eb20,51,shell_read_optional_presentation_extents4,bootstrap,thiscall,inferred,ghidra-headless,4,Reads an optional four-float extent block from the active presentation-batch record when byte flag [this+0x25] is set; copies dwords at +0x26 +0x2a +0x2e and +0x32 into caller outparams for the presentation-extents helper at 0x547d10.,ghidra + rizin
0x0052eca0,43,shell_get_next_presentation_batch_record,bootstrap,thiscall,inferred,ghidra-headless,4,Returns the next 0x45-byte presentation-batch record for the active item family rooted at [this+0x14] if current index [this+0x21] plus one is still below the family count at [+0x14]; otherwise returns null.,ghidra + rizin
0x00524780,1252,shell_emit_ranked_overlay_cell_items,bootstrap,thiscall,inferred,ghidra-headless,3,Processes one ranked-overlay cell list for 0x0052a2f0. It samples shell range thresholds through 0x00533180 and 0x00533160 filters cell items by distance and intensity derives an alpha-biased packed color from the caller input and emits accepted items into the current vertex24 span through layout helper 0x005468c0.,ghidra + rizin + llvm-objdump
0x00533ba0,39,shell_grid_get_nearby_presentation_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the nearby-presentation layer rooted at [this+0x1671]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1671].,ghidra + rizin + llvm-objdump
0x00533cd0,39,shell_grid_get_static_vertex24_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the fixed-geometry vertex24 layer rooted at [this+0x167d]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x167d].,ghidra + rizin + llvm-objdump
0x00533db0,30,shell_grid_get_geographic_label_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the geographic-label layer rooted at [this+0x1675]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1675].,ghidra + rizin + llvm-objdump
0x00533e30,32,shell_grid_get_animated_quad_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the animated-quad presentation layer rooted at [this+0x1681]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1681].,ghidra + rizin + llvm-objdump
0x00533e50,32,shell_grid_get_ranked_overlay_cell,bootstrap,thiscall,inferred,ghidra-headless,4,Returns one tile-grid cell from the ranked secondary overlay layer rooted at [this+0x1685]. The helper uses the same 16x16 tile addressing and grid width field at [this+0x15d9] as the other shell cell-grid accessors and currently feeds 0x0052a2f0.,ghidra + rizin + llvm-objdump
0x00539fb0,924,shell_emit_geographic_label_frame_vertex24_records,bootstrap,thiscall,inferred,ghidra-headless,4,Expands the current geographic-label item into cached frame vertex24 records inside the caller buffer. The helper patches packed alpha into up to sixteen prebuilt 0x18-byte records copies additional 24-byte frame blocks from fixed item offsets and returns the emitted vertex count for the label border or backing geometry.,ghidra + rizin + llvm-objdump
0x0053a440,14,shell_set_geographic_label_item_alpha,bootstrap,thiscall,inferred,ghidra-headless,4,Stores an 8-bit alpha input into the high-byte color field at [this+0x5b] for the current geographic-label item before frame or text emission.,ghidra + rizin + llvm-objdump
0x0053a960,723,shell_emit_geographic_label_text_span,bootstrap,thiscall,inferred,ghidra-headless,4,Builds and emits one geographic-label text span for the current cell item. The helper calls the item vtable at +0x10 to materialize a null-terminated display string up to 0x12c bytes computes placement from item float fields and shell service state checks visibility through the shell bundle and forwards the resolved text payload into the presentation path through 0x005519f0. The item family aligns with gpdLabelDB and 2DLabel.imb rather than the parallel city assets.,ghidra + rizin + llvm-objdump
0x00543f10,853,layout_state_bind_presentation_asset_bundle,bootstrap,thiscall,inferred,ghidra-headless,4,Initial bind-time asset loader for the layout state's presentation node at [this+0x25df]; pulls a fixed presentation bundle through the node vtable at +0x5c and +0x60 including standalone assets stored around 0x2643 0x2647 0x264b 0x264f 0x2653 0x265b 0x265f and 0x2663 plus a 64-entry asset bank at 0x31ab while advancing an internal asset-offset cursor at [this+0x2543].,ghidra + rizin
0x00554830,142,attachment_object_init_named_asset,bootstrap,thiscall,inferred,ghidra-headless,3,Initializes one named attachment object from a caller-supplied asset string and placement parameters. The helper copies the asset name into the local object buffer at [this+0x10] stores attachment selectors at [this+0x130] and [this+0x138] optionally derives a cached scale pair at [this+0x120] and [this+0x124] and then finalizes object state through 0x005545d0.,ghidra + rizin + llvm-objdump
0x005455e0,224,layout_state_set_slot_triplet_lo,bootstrap,thiscall,inferred,ghidra-headless,4,Updates the first three cached per-slot presentation scalars in the 24-byte slot table at [this+0x2597+slot*24]. In notify mode it compares against the cached values and forwards only changed fields into the bound presentation node through vtable slot +0xfc with subproperty ids 1 through 3.,ghidra + rizin + llvm-objdump
0x005456d0,240,layout_state_set_slot_triplet_hi,bootstrap,thiscall,inferred,ghidra-headless,4,Updates the second three cached per-slot presentation scalars in the same 24-byte slot table at [this+0x2597+slot*24]. In notify mode it compares against the cached values and forwards only changed fields into the bound presentation node through vtable slot +0xfc with subproperty ids 4 through 6.,ghidra + rizin + llvm-objdump
0x005458f0,169,layout_state_read_segment_record_window,bootstrap,thiscall,inferred,ghidra-headless,4,Gates the 32-byte segment-record table at [this+0x2643]; queries record bounds then copies a start-to-end or wrapped window into scratch storage at [this+0x2657] through vtable slot +0x2c while toggling byte flag [this+0x254e]. The downstream shell path treats each 0x20-byte record as two vec3 blocks plus two trailing scalars.,ghidra + rizin
0x005459a0,69,layout_state_read_segment_record_block,bootstrap,thiscall,inferred,ghidra-headless,4,Reads one 32-byte-indexed segment-record block from the same [this+0x2643] table into scratch storage at [this+0x2657] through vtable slot +0x2c using a fixed 0x2800-byte transfer span.,ghidra + rizin
0x00545b10,57,layout_state_read_vertex24_block,bootstrap,thiscall,inferred,ghidra-headless,4,Reads one 24-byte-indexed vertex block from the presentation table at [this+0x2647] through vtable slot +0x2c using index*24 addressing and returns the copied pointer through a stack outparam. The downstream shell emitter treats each record as vec3 plus a style dword plus two trailing scalars.,ghidra + rizin
0x00545b50,59,layout_state_read_vertex24_window,bootstrap,thiscall,inferred,ghidra-headless,4,Copies a window between two 24-byte vertex indices from [this+0x2647] into scratch storage at [this+0x2657] through vtable slot +0x2c using index*24 addressing and a fixed 0x1800-byte transfer span. The downstream shell emitter treats each record as vec3 plus a style dword plus two trailing scalars.,ghidra + rizin
0x00545c50,67,layout_state_commit_vertex24_span,bootstrap,thiscall,inferred,ghidra-headless,4,Converts a start and end vertex index range into a triplet count by dividing the delta by three accumulates that count at [this+0x3711] and notifies the bound presentation node at [this+0x25df] through vtable slot +0x118 with primitive-type argument 4.,ghidra + rizin
0x00546a30,333,layout_state_rebuild_variant_asset_cache,bootstrap,thiscall,inferred,ghidra-headless,3,Releases any loaded entries in the 64-slot presentation asset bank rooted at 0x31ab then rebuilds the paired-key metadata table at 0x266b tracking active entries count at [this+0x2667] and sibling or reuse links for later keyed lookups.,ghidra + rizin
0x005467a0,50,layout_state_enable_presentation_gate,bootstrap,thiscall,inferred,ghidra-headless,4,Ensures the presentation node gate property 0x1c is enabled once for the layout state when the template flag at [[this+0x83c]+0x2e] permits it by setting [this+0x2549] and forwarding the toggle into the node at [this+0x25df].,ghidra + rizin
0x00547d10,288,layout_state_apply_presentation_extents4,bootstrap,thiscall,inferred,ghidra-headless,4,Applies a four-float extent or quad block onto presentation property 0x18 for the bound node at [this+0x25df]. If all four inputs are nonpositive it clears the property through vtable slot +0xfc; otherwise it builds a 0x10-field stack block with the four caller values and a unit scalar then commits it through node slots +0xfc and +0x94.,ghidra + rizin + llvm-objdump
0x00547f20,177,layout_state_apply_gamma_ramp_scalar,bootstrap,thiscall,inferred,ghidra-headless,4,Builds a 256-entry three-channel gamma-ramp buffer from the caller scalar and uploads it through vtable slot +0x48 on the bound presentation node at [this+0x25df]. The helper clamps each 16-bit ramp entry stores the accepted scalar in the subordinate state block at [[this+0x83c]+0x2f] and respects shell capability guards under 0x006d4024 before touching the display device.,ghidra + rizin + llvm-objdump
0x00548da0,1328,layout_state_refresh_presentation_batches,bootstrap,thiscall,inferred,ghidra-headless,4,Walks the active presentation-batch list and refreshes the bound node state for each selected item. The routine applies batch extents through 0x00547d10 pushes style and gate properties including packed color property 0x3c updates per-slot triplets through 0x005455e0 and 0x005456d0 and emits segment-record or vertex24 spans from the current batch family before advancing to the next record.,ghidra + rizin + llvm-objdump
0x005492d0,3747,layout_state_probe_d3d8_capabilities,bootstrap,thiscall,inferred,ghidra-headless,4,Creates a Direct3D8 probe object and walks adapter or device capability queries for the layout-state presentation path. The routine caches probed texture-memory style fields into shell globals under 0x006d4024 including the values later reported as Texture SRAM and Texture VRAM consults the shell memory-budget helpers 0x0051fa40 and 0x0051fa60 refreshes the gamma ramp through 0x00547f20 when needed and assigns a local renderer capability tier at [this+0x04].,ghidra + rizin + llvm-objdump + strings
0x0054a280,626,layout_state_apply_presentation_properties,bootstrap,thiscall,inferred,ghidra-headless,4,Pushes visibility color and mode-dependent scalar properties from the layout state into the bound presentation node at [this+0x25df]; toggles gate property 0x1c writes packed color property 0x22 from bytes 0x2510..0x2512 updates mode properties 0x23 through 0x26 from template flags and caller-supplied scalars and caches the leading scalar at [this+0x25b3].,ghidra + rizin
0x0054bab0,89,layout_state_bind_segment_record_table,bootstrap,thiscall,inferred,ghidra-headless,4,Binds the current 32-byte segment-record table at [this+0x2643] onto the presentation node if it changed since the last bind. The helper drives node property 0x112 through vtable slots +0x130 and +0x14c with record size 0x20 and clears the local dirty byte at [this+0x263b].,ghidra + rizin + llvm-objdump
0x0054bb70,90,layout_state_bind_vertex24_table,bootstrap,thiscall,inferred,ghidra-headless,4,Binds the current 24-byte vertex24 table at [this+0x2647] onto the presentation node if it changed since the last bind. The helper drives node property 0x142 through vtable slots +0x130 and +0x14c with record size 0x18 and clears the local dirty byte at [this+0x263b].,ghidra + rizin + llvm-objdump
0x0054bc10,592,shell_init_layout_state_defaults,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes the large subordinate layout-state object allocated by 0x0055e2b0; seeds default float and flag fields points [this+0x83c] at a shell-bundle template block near 0x006d4024+0x11468a optionally copies a 0x72c-byte preset table and notifies the shell bundle service at [0x006d4024+0x28].,ghidra + rizin
0x0054bea0,1399,layout_state_apply_interpolated_pose,bootstrap,thiscall,inferred,ghidra-headless,4,Applies an interpolated pose and palette sample on the subordinate layout-state object using the controller counters passed by callers; clamps the time window blends preset tables at offsets 0x840 through 0x86f updates color bytes at 0x2510 through 0x2512 invokes the bound presentation node at [this+0x25df] and finishes through 0x0054a280.,ghidra + rizin
0x0054f640,83,shell_step_global_presentation_phase_scalar,shell,cdecl,inferred,ghidra-headless,2,Steps the shared presentation-phase scalar stored at 0x00d93850 downward by a small constant then clamps the returned value against fixed lower-bound constants. Callout-marker world-anchor and other presentation helpers use this as a common time-varying scalar after one of the nearby setters has seeded the global phase.,ghidra + rizin + llvm-objdump
0x0054f700,12,shell_set_global_presentation_phase_scalar,shell,cdecl,inferred,ghidra-headless,3,Stores one caller-supplied float into the shared presentation-phase scalar at 0x00d93850. Mouse-cursor geographic-label and other presentation helpers seed this global before later batch or marker helpers consume it through 0x0054f640.,ghidra + rizin + llvm-objdump
0x0054f710,729,shell_queue_callout_segment_marker,shell,cdecl,inferred,ghidra-headless,2,Queues one short world-space callout segment or marker packet using the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34]. The helper derives scaled endpoint deltas from the caller inputs applies flag-controlled clamps from arg_14h and emits three type-0x01 deferred messages through shell_enqueue_deferred_message_type1.,ghidra + rizin + llvm-objdump
0x0054f9f0,281,shell_queue_callout_frame_segments,shell,cdecl,inferred,ghidra-headless,4,Builds a four-segment callout frame around one projected extent box. The helper samples the same shell zoom and reciprocal scale tables under 0x006d4024 computes the four box legs from the caller extent inputs and emits each side through shell_queue_callout_segment_marker.,ghidra + rizin + llvm-objdump
0x0054fb10,699,shell_queue_callout_leader_path,shell,cdecl,inferred,ghidra-headless,3,Builds one longer world-space callout leader path between two points. It derives slope and angle terms from the caller inputs recursively reuses itself or 0x0054f710 for shorter segments chooses style branches from distance and flag tests and enqueues the resulting type-0x01 deferred messages. shell_publish_text_callout_presentation uses this helper for text-associated leader geometry.,ghidra + rizin + llvm-objdump
0x0054fdd0,256,shell_queue_presentation_batch_pair,shell,cdecl,inferred,ghidra-headless,2,Queues a two-record presentation batch through the shell deferred-message path. One branch emits a single trailing type-0x04 record while the other brackets two type-0x04 payload posts with direct type-0x05 and type-0x06 begin-end records; both legs seed their animated scalar through shell_step_global_presentation_phase_scalar before routing through the shell bundle at 0x006d4024.,ghidra + rizin + llvm-objdump
0x0054fed0,440,shell_queue_presentation_batch_quad,shell,cdecl,inferred,ghidra-headless,2,Queues a four-record presentation batch through the same deferred-message family. It posts a type-0x05 begin record emits four type-0x04 payload records with refreshed phase scalars from shell_step_global_presentation_phase_scalar and finally closes the batch with a type-0x06 end record. The current high-level callers build this from four related point or extent tuples.,ghidra + rizin + llvm-objdump
0x005519f0,902,shell_publish_text_callout_presentation,shell,cdecl,inferred,ghidra-headless,3,Publishes one styled text or callout presentation payload through the active shell bundle at 0x006d4024. It accepts text placement and style inputs conditionally emits a leader path through 0x0054fb10 allocates backing text resources through 0x0051f0b0 and 0x00543c10 sets presentation flags from the mode arguments and finalizes the payload through 0x0051fc20. Geographic-label text and mouse-cursor presentation both feed this helper.,ghidra + rizin + llvm-objdump + strings
0x00552160,56,world_anchor_measure_projected_half_width,shell,cdecl,inferred,ghidra-headless,3,Measures one absolute projected half-width-like extent from the caller world-anchor object. It chooses the X or Z span depending on orientation byte [this+0x24] scales by the owner coefficients at +0x2e or +0x32 multiplies by local width scalar [this+0x1c] and returns the absolute result for later cursor or marker placement code.,ghidra + rizin + llvm-objdump
0x005521a0,56,world_anchor_measure_projected_half_height,shell,cdecl,inferred,ghidra-headless,3,Measures one absolute projected half-height-like extent from the caller world-anchor object. It chooses the complementary axis span using the same orientation byte [this+0x24] scales by owner coefficients at +0x2e or +0x32 multiplies by local height scalar [this+0x20] and returns the absolute result for later cursor or marker placement code.,ghidra + rizin + llvm-objdump
0x005521e0,894,world_anchor_project_screen_extent_pair,shell,cdecl,inferred,ghidra-headless,3,Projects one world-anchor object into a paired screen-space extent result. The helper samples the shell zoom table under 0x006d4024 computes integer-scaled axis spans from the anchor geometry converts them through multiple clamp or reciprocal stages and writes two output integers through the caller pointers before later marker builders use the results for anchor presentation sizing.,ghidra + rizin + llvm-objdump
0x00552560,916,shell_queue_world_anchor_marker,shell,cdecl,inferred,ghidra-headless,3,Builds one world-anchor marker packet from the caller point object and optional scale or style inputs. It samples anchor extents from the object fields converts them through 0x0053dde0 0x0053ddf0 and world_anchor_project_screen_extent_pair consults the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34] and finally enqueues one type-0x01 deferred message through shell_enqueue_deferred_message_type1. mouse_cursor_update_frame_state uses it for one branch of cursor world-relative presentation.,ghidra + rizin + llvm-objdump
0x00552900,1304,shell_queue_projected_world_anchor_quad,shell,cdecl,inferred,ghidra-headless,3,Builds one oriented projected quad around the caller world-anchor object. It derives four projected corner points from the anchor extents and orientation computes edge and diagonal lengths through 0x0051db80 samples the shared presentation phase through shell_step_global_presentation_phase_scalar refines screen-space bounds through world_anchor_project_screen_extent_pair and finally emits two type-0x04 deferred-message posts through shell_enqueue_deferred_message_type4.,ghidra + rizin + llvm-objdump
0x00554d70,248,billboard_item_build_anchor_point_cache,bootstrap,thiscall,inferred,ghidra-headless,3,Builds or refreshes the cached point list for one billboard item at [this+0x1dd]. When source points exist at [this+0x10] it transforms them through the owner object matrix near [this+0x0c]+0xce; otherwise it seeds a one-point fallback from the baked vector at [this+0xfe..0x106].,ghidra + rizin + llvm-objdump
0x00554e70,680,shell_emit_ranked_sprite_billboard_item,bootstrap,thiscall,inferred,ghidra-headless,4,Emits one ranked sprite-billboard item into the current vertex24 span. The helper computes a distance-weighted fade against shell and world state stores the derived scalar at [item+0xdc] and then walks either the item's linked child list at [item+0x4] or the cached anchor list at [item+0x1dd] to write textured quad geometry through 0x005662a0.,ghidra + rizin + llvm-objdump
0x00555740,49,billboard_item_refresh_child_sprite_colors,bootstrap,thiscall,inferred,ghidra-headless,3,Refreshes packed child-sprite colors for one billboard item by iterating the linked child list at [this+0x4] recomputing each child color through 0x005554f0 and storing the 24-bit result at [child+0x70].,ghidra + rizin + llvm-objdump
0x00555780,1739,sprite_billboard_spawn_particle_instance,bootstrap,thiscall,inferred,ghidra-headless,4,Builds one emitted sprite-billboard instance from the template item. It randomizes local offsets through fields [this+0x7c..0x90] optionally samples anchor points from the owner matrix or cached path data chooses atlas uv bounds from [this+0x110..0x124] applies scale and fade terms from [this+0x94..0x108] recomputes packed colors through 0x005554f0 and finalizes the instance through 0x00565e80 and 0x00565f40.,ghidra + rizin + llvm-objdump
0x00555e50,1808,sprite_billboard_update_particle_emitter,bootstrap,thiscall,inferred,ghidra-headless,4,Advances one sprite-billboard emitter template and spawns new instances through 0x00555780. The routine updates emitter clocks and travel bounds in [this+0x68..0xc8] applies burst or repeat controls through [this+0x1ed..0x1f9] walks up to [this+0x34] spawn lanes resolves anchor positions from cached or owner-derived points and refreshes the active emitter origin at [this+0xc0] and [this+0xc4].,ghidra + rizin + llvm-objdump
0x0055d430,6,system_get_total_physical_memory_bytes,support,cdecl,inferred,ghidra-headless,4,Returns the cached total physical-memory byte count from the shared MEMORYSTATUS block at 0x00d9754c. The graphics preset bundle uses this value as one of its coarse runtime capability probes after the cache has been refreshed through GlobalMemoryStatus nearby.,ghidra + rizin + llvm-objdump
0x0055d440,17,system_refresh_available_physical_memory_bytes,support,cdecl,inferred,ghidra-headless,4,Refreshes the shared MEMORYSTATUS block at 0x00d97548 through GlobalMemoryStatus and returns the resulting available physical-memory byte count from dwAvailPhys. This is the active memory-availability probe companion to 0x0055d430.,ghidra + rizin + llvm-objdump + strings
0x0055d460,81,os_is_non_nt_platform,support,cdecl,inferred,ghidra-headless,4,Calls GetVersionExA and returns true only when the platform id is not VER_PLATFORM_WIN32_NT. The graphics preset bundle inverts this result into an NT-family capability flag before finalizing several display-runtime bytes under 0x006d4024.,ghidra + rizin + llvm-objdump + strings
0x0055d8d0,138,display_get_primary_adapter_descriptor,support,cdecl,inferred,ghidra-headless,4,Enumerates display devices through USER32.EnumDisplayDevicesA until it finds the primary adapter flag then copies the adapter DeviceString field into the global buffer at 0x00d97448 and returns that buffer. When enumeration fails it leaves the descriptor empty and still returns the same shared buffer pointer. The graphics preset matcher at 0x00484a60 consumes this descriptor text directly.,ghidra + rizin + llvm-objdump + strings
0x005a0f70,209,stream_cipher_xor_in_place,support,cdecl,inferred,rizin,4,Applies one stateful stream-cipher pass in place over the caller buffer in ECX for the caller byte count in EDX using the 0x102-byte cipher state block passed on the stack. The helper mutates the two state bytes at offsets `+0x100` and `+0x101` and uses the 0x100-byte permutation table at the start of the state block to XOR every byte in the buffer. Current grounded callers are the multiplayer transport text-stream receive and send paths.,rizin + llvm-objdump
0x005a18a0,292,string_copy_bounded_zerofill,support,cdecl,inferred,ghidra-headless,4,Shared bounded string-copy helper that copies up to count bytes from source to destination stops after the first NUL byte and zero-fills the remaining span before returning the destination pointer. The graphics preset matcher uses it to stage the primary adapter descriptor into a local probe buffer before substring token scans,ghidra + rizin + llvm-objdump
0x00556620,305,sprite_billboard_manager_reset,bootstrap,thiscall,inferred,ghidra-headless,3,Releases the shared sprite-billboard manager state including emitter slots at [this+0x10] queued templates at [this+0x18] and owned resource handles or containers before zeroing the manager pointers again.,ghidra + rizin + llvm-objdump
0x00556770,420,sprite_billboard_manager_init_pools,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes the shared sprite-billboard manager when the shell first needs emitter templates. It allocates the long-lived emitter arrays and container objects at [this+0x10] [this+0x18] [this+0x8] [this+0x4] and [this+0x0] with a default capacity of 0xc350 slots unless the caller overrides it.,ghidra + rizin + llvm-objdump
0x00556920,814,sprite_billboard_init_emitter_template,bootstrap,thiscall,inferred,ghidra-headless,4,Initializes one sprite-billboard emitter template from optional source geometry color flags and atlas bounds. It copies source points or seeds a fallback anchor path stores owner position seeds default fade and timing fields across [this+0x94..0xd8] computes atlas uv steps from [this+0xe0..0xec] into [this+0x110..0x124] and optionally prewarms the spawn list through 0x00554ce0 when the caller flags request it.,ghidra + rizin + llvm-objdump
0x00556c50,143,sprite_billboard_manager_create_template_node,bootstrap,thiscall,inferred,ghidra-headless,4,Allocates or reuses one manager node then creates a fresh sprite-billboard template through 0x00556920 with flag 0x400 forced on. The helper stores the new template at [node+0x4] and queues the node into the manager container at [this+0x8].,ghidra + rizin + llvm-objdump
0x00556ce0,160,sprite_billboard_manager_clone_template_node,bootstrap,thiscall,inferred,ghidra-headless,4,Looks up one existing manager node and either returns its current template or clones a new sprite-billboard template from it through 0x00556920. On the first clone path it prewarms the source template through 0x00554ce0 and then queues the new node into the manager container at [this+0x4].,ghidra + rizin + llvm-objdump
0x00556e10,54,intrusive_queue_push_back,support,cdecl,inferred,ghidra-headless,4,Allocates one intrusive-queue node then appends the caller payload pointer to the tail of the container. The helper writes the payload at [node+0x00] links the previous tail through [node+0x04] and [tail+0x08] updates the head and tail slots when needed and increments the queued-node count at [this+0x0c].,ghidra + rizin + llvm-objdump
0x00556ef0,6,intrusive_queue_rewind_iterator,support,cdecl,inferred,ghidra-headless,4,Resets one intrusive-queue iterator by copying the container head pointer at [this+0x00] into the current-iterator slot at [this+0x04]. The helper is reused broadly across shell presentation and gameplay container walkers before repeated next-node calls.,ghidra + rizin + llvm-objdump
0x00556f00,19,intrusive_queue_next_iterator_node,support,cdecl,inferred,ghidra-headless,4,Returns the current intrusive-queue iterator node from [this+0x04] then advances the iterator to the linked next pointer at [node+0x08]. When the iterator is exhausted it returns null without mutating any payload state.,ghidra + rizin + llvm-objdump
0x00556f90,13,intrusive_queue_peek_tail_payload,support,cdecl,inferred,ghidra-headless,4,Returns the payload pointer stored in the current tail node at [this+0x08]. When the container is empty it returns null without mutating the queue state.,ghidra + rizin + llvm-objdump
0x00557010,159,intrusive_queue_clear_owned_nodes,support,cdecl,inferred,ghidra-headless,3,Specialized intrusive-queue clear path for containers with an auxiliary owner or context pointer at [this+0x14]. It iterates the owned node chain through the queue iterator helpers releases nested payload state unlinks each node and decrements the queue count before returning to the outer container clear helper.,ghidra + rizin + llvm-objdump
0x005570b0,80,intrusive_queue_clear_and_release,support,cdecl,inferred,ghidra-headless,4,Clears and releases every node in one intrusive queue container. When [this+0x14] is present it routes through intrusive_queue_clear_owned_nodes; otherwise it walks the linked nodes directly releases them zeroes the head iterator and tail slots and resets the queued-node count at [this+0x0c].,ghidra + rizin + llvm-objdump
0x00559520,166,surface_init_rgba_pixel_buffer,support,thiscall,inferred,ghidra-headless,3,Initializes or refreshes a small 0xec-byte RGBA pixel-buffer object from caller-supplied image data and dimensions. On first use it allocates the backing object through 0x0053b070 stores width and height at [this+0xa2] and [this+0xa6] seeds the inner surface through 0x00543980 and 0x00541970 then copies width*height*4 bytes from the source buffer before finalizing through 0x005438d0. Current callers use it from the PaintTerrain preview path and the Multiplayer.win map-preview branch.,ghidra + rizin + llvm-objdump + strings
0x00565110,600,shell_rebuild_layout_state_and_optional_texture_report,shell,thiscall,inferred,ghidra-headless,3,Rebuilds the active shell layout-state branch when the current mode requires a deeper reset and optionally publishes the texture budget report through 0x00527650. The routine checks the current layout mode through 0x00545e00 tears down and recreates layout-state services through 0x0055dd80 and 0x0055e2b0 optionally notifies global shell services and when the caller flag is set emits the report then commits one layout refresh step through 0x00545d60.,ghidra + rizin + llvm-objdump + strings
0x0058d7a0,55,multiplayer_transport_set_local_name,shell,thiscall,inferred,ghidra-headless,3,Updates the local identity string stored in the session-event transport object. When the transport is already configured through [this+0x44] and the incoming name pointer is non-null and non-empty it copies up to 0x40 bytes into [this+0x04] clears byte [this+0x43] and then forwards the same name into the lower transport update path through 0x0058f330.,ghidra + rizin + llvm-objdump
0x0058d830,40,multiplayer_transport_disconnect,shell,thiscall,inferred,ghidra-headless,3,Disconnects the session-event transport object from its current live route. The helper flips the internal active state through 0x005965d0 and 0x005961b0 calls the shared teardown block at 0x0058d810 and finally clears byte [this+0x60] and the copied local name at [this+0xaf4].,ghidra + rizin + llvm-objdump
0x0058d860,59,multiplayer_transport_release_worker_and_reset_runtime_state,shell,cdecl,inferred,rizin,3,Small runtime-reset wrapper for the outer session-event transport object. When the owned worker pointer at [this] is present it first tears that worker down through multiplayer_transport_worker_shutdown_gracefully then clears the worker pointer the configured flag byte at [this+0x04] the text-stream owner slots at [this+0x44] and [this+0x48] reruns 0x00593370 and the shared reset block at 0x0058d810 and finally clears the live route and deferred-runtime fields at [this+0x180c] [this+0x1810] and [this+0x1edc].,rizin + llvm-objdump
0x0058d960,7,multiplayer_transport_select_status_route,shell,thiscall,inferred,ghidra-headless,3,Thin route-selector wrapper for the session-event transport. It forwards the requested small route id in EDX into multiplayer_transport_set_mode_q_flag which updates [this+0x560] formats the underlying `MODE %s -q` or `MODE %s +q` command text and reconfigures the transport-side callback plumbing.,ghidra + rizin + llvm-objdump
0x0058d970,89,multiplayer_transport_subscribe_field_callback_set,shell,thiscall,inferred,ghidra-headless,3,Registers one field-subscription callback set on the session-event transport. When the transport is active byte [this+0x60] is set it stores the caller metadata at [this+0x176c] and [this+0x1770] then forwards the field-id list string callback and context into multiplayer_transport_register_field_subscription_bundle; on failure it falls back through multiplayer_transport_enqueue_field_snapshot_record.,ghidra + rizin + llvm-objdump
0x0058d9e0,55,multiplayer_transport_send_selector_text,shell,thiscall,inferred,ghidra-headless,3,Sends one caller-supplied text pointer through a selector-specific transport slot. The helper looks up the selector entry from the handler table rooted at [this+0x390] and when both the text pointer and slot are valid forwards the string plus caller flag into the lower send helper at 0x0058e7e0 using the descriptor block at [this+0x80+selector*0x101].,ghidra + rizin + llvm-objdump
0x0058da60,75,multiplayer_transport_register_selector_callback,shell,thiscall,inferred,ghidra-headless,3,Registers or dispatches one selector callback against the transport slot table rooted at [this+0x390]. When the selected slot is absent it directly invokes the supplied callback with mode -1 and null payloads; otherwise it packages the caller context on the stack and walks the registered slot through 0x00594ac0 using helper 0x0058da20.,ghidra + rizin + llvm-objdump
0x0058db00,23,multiplayer_transport_request_status_pump,shell,thiscall,inferred,ghidra-headless,3,Marks the session-event transport status path dirty by setting [this+0xb44] to 1 and then calling multiplayer_transport_service_status_pump when the transport is active.,ghidra + rizin + llvm-objdump
0x0058db20,53,multiplayer_transport_clear_status_pump,shell,thiscall,inferred,ghidra-headless,3,Clears the session-event transport status-pump flag at [this+0xb44] then reruns multiplayer_transport_service_status_pump. When the transport still owns the auxiliary object at [this+0xaf0] it follows up with either 0x00597370 or 0x00597350 depending on whether selector slot [this+0x398] is present.,ghidra + rizin + llvm-objdump
0x0058db60,5,multiplayer_transport_force_status_flush,shell,thiscall,inferred,ghidra-headless,3,Tail-call wrapper into 0x00597370 for the active session-event transport object. The shell flush path uses it immediately before multiplayer_transport_flush_and_maybe_shutdown.,ghidra + rizin + llvm-objdump
0x0058dc30,22,multiplayer_transport_is_route_mode_active_nonterminal,shell,cdecl,inferred,ghidra-headless,3,Tiny predicate over the route-mode field at [this+0x18b8]. It returns false when the mode is zero or terminal mode `5` and true for the other active route modes. Current grounded callers use it to decide whether route callbacks can run inline or whether route work must be re-enqueued.,ghidra + rizin + llvm-objdump
0x0058de90,95,multiplayer_transport_shutdown,shell,thiscall,inferred,ghidra-headless,3,Shuts down the session-event transport object and either marks deferred-close state or tears the object down immediately. It preserves [this+0x178c] across the common shutdown helper at 0x0058de50 disconnects active routes through multiplayer_transport_disconnect and when no outstanding work remains drops into the reset path at 0x0058d8a0; otherwise it latches deferred-close flag [this+0x1ee0].,ghidra + rizin + llvm-objdump
0x0058def0,40,multiplayer_transport_flush_and_maybe_shutdown,shell,thiscall,inferred,ghidra-headless,3,Flushes the transport state through 0x0058d8d0 with selector -1 and when deferred-close flag [this+0x1ee0] is set and the outstanding-work count at [this+0x1808] has reached zero immediately falls into multiplayer_transport_shutdown.,ghidra + rizin + llvm-objdump
0x0058df20,131,multiplayer_transport_submit_text_record,shell,thiscall,inferred,ghidra-headless,3,Submits one prepared text record through the session-event transport using a caller-supplied callback wrapper. The helper allocates a transient transport record through multiplayer_transport_next_work_sequence sends it through multiplayer_transport_try_submit_text_record_fastpath and when that fast path declines packages the caller callback mode and payload into 0x00593170. When the caller requested immediate draining it also services the transport queue through 0x0058d8d0 and 0x0058d720 and may fall into multiplayer_transport_shutdown when deferred close is armed.,ghidra + rizin + llvm-objdump
0x0058e100,230,multiplayer_transport_publish_fixed_token_message,shell,thiscall,inferred,ghidra-headless,3,Publishes one fixed-token status message through selector `2` on the session-event transport. The helper requires the transport to be active and fully configured builds a formatted status line from the caller token plus internal fields such as [this+0x282] and [this+0x54] sends that line through multiplayer_transport_send_selector_text sets [this+0xb44] to 1 reruns the status pump and when appropriate nudges the downstream mode helper at 0x00595650 or the auxiliary object paths 0x00597350 and 0x00597370.,ghidra + rizin + llvm-objdump + strings
0x0058e200,211,multiplayer_transport_register_callback_table,shell,thiscall,inferred,ghidra-headless,3,Registers or refreshes the session-event transport callback table and descriptor block. When the transport is not yet fully configured it copies the local name into [this+0x04] stores the callback-table pointers at [this+0x4c] and [this+0x5c] sets [this+0x44] active and forwards the descriptor block plus caller metadata into multiplayer_transport_attach_callback_table_descriptor. It then routes the resolved table through multiplayer_transport_dispatch_callback_table_binding and optionally drains queued work through 0x0058d8d0 and 0x0058d720 before honoring deferred-close state.,ghidra + rizin + llvm-objdump
0x0058e2e0,38,multiplayer_transport_reset_and_maybe_shutdown,shell,thiscall,inferred,ghidra-headless,3,Resets the common transport state through 0x0058de50 and when deferred-close flag [this+0x1ee0] is armed and the outstanding-work count at [this+0x1808] has reached zero immediately falls into multiplayer_transport_shutdown.,ghidra + rizin + llvm-objdump
0x0058e370,33,multiplayer_transport_is_request_pending,shell,cdecl,inferred,ghidra-headless,3,Returns true while the caller transport request still appears in either the queued request collection at [this+0x550] or the secondary active-work collection checked through 0x0059c540. Immediate-drain callers use it as the loop predicate after pumping queued text and sleeping for 10 ms.,ghidra + rizin + llvm-objdump
0x0058e3f0,137,multiplayer_transport_drain_request_text_queue,shell,cdecl,inferred,ghidra-headless,3,Immediate-drain helper for one transport request. When request kind [req+0x20] is `1` it walks queued transport text lines under [this+0x1c] republishes them through 0x0059b790 and notifies the small observer table through 0x0058e310 until the queue is empty. When request kind `2` drains it also publishes `Disconnected`. Both paths refresh timeout state through 0x00598030 and finish by forwarding the request into 0x0059c470.,ghidra + rizin + llvm-objdump + strings
0x0058e480,105,multiplayer_transport_worker_shutdown_gracefully,shell,cdecl,inferred,rizin,3,"Graceful shutdown wrapper for one multiplayer transport worker. If the callback object at `[this+0x538]` and its owner slot `[this+0x544]` are present it first emits a final owner notification through the callback vtable using fallback text at `0x005c87a8`. When the owned text-stream socket at `[this+0x1c]` is still live it appends `QUIT :Later!` through multiplayer_transport_text_stream_append_crlf_line and services one I/O step through multiplayer_transport_text_stream_service_io before destroying the registered-name store at `[this+0x548]`, the pending-template dispatch store at `[this+0x54c]`, the text-stream object at `[this+0x1c]`, and finally the worker backing block itself.","rizin + llvm-objdump + strings"
0x0058e650,80,multiplayer_transport_sanitize_identifier,shell,cdecl,inferred,ghidra-headless,4,Normalizes a caller-supplied identifier string into the destination buffer by replacing leading punctuation and any later disallowed characters with underscores while preserving acceptable bytes from the source. Current grounded callers use it for the randomized `RT3Player%d` retry name and for locally submitted session-event text records.,ghidra + rizin + llvm-objdump + strings
0x0058e6b0,98,multiplayer_transport_set_mode_q_flag,shell,thiscall,inferred,ghidra-headless,4,Updates the transport mode-q flag tracked at [this+0x560]. When the requested value changes it formats either `MODE %s -q` or `MODE %s +q` against the active name buffer at [this+0x36c] stores the new flag and for mode `0` refreshes the downstream callback plumbing through 0x0059e070 and 0x0059de00 using helper 0x0058e6a0.,ghidra + rizin + llvm-objdump + strings
0x0058e8c0,37,multiplayer_transport_publish_topic_status_line,shell,thiscall,inferred,ghidra-headless,3,Formats and publishes one `TOPIC %s :%s` status line through the active transport text buffer at [this+0x1c]. When the caller text is null it falls back to the shared empty sample at 0x005c87a8. Current grounded caller is multiplayer_transport_handle_names_query_response.,ghidra + rizin + llvm-objdump + strings
0x0058e8f0,56,multiplayer_transport_publish_mode_key_status_line,shell,thiscall,inferred,ghidra-headless,3,Formats and publishes one mode-key status line through the active transport text buffer at [this+0x1c]. Depending on the caller flag it emits either `MODE %s +k %s` or `MODE %s -k %s`. Current grounded caller is multiplayer_transport_handle_bound_route_request.,ghidra + rizin + llvm-objdump + strings
0x0058e930,53,multiplayer_transport_publish_mode_level_status_line,shell,thiscall,inferred,ghidra-headless,3,Formats and publishes one mode-level status line through the active transport text buffer at [this+0x1c]. Depending on whether the caller level value is nonzero it emits either `MODE %s +l %d` or `MODE %s -l`. Current grounded caller is multiplayer_transport_handle_names_query_response.,ghidra + rizin + llvm-objdump + strings
0x0058e970,36,multiplayer_transport_invoke_registered_name_query_callback,shell,cdecl,inferred,ghidra-headless,3,Small callback shim used by the registered-name fast path. It loads the caller callback object from the dispatch frame and invokes its entry method with success flag `1`; the queried sample string; and the collected callback-entry arrays produced by multiplayer_transport_collect_registered_name_callback_entries.,ghidra + rizin + llvm-objdump
0x0058e9a0,177,multiplayer_transport_submit_names_query_with_callback,shell,thiscall,inferred,ghidra-headless,3,Builds and submits one `NAMES %s` query against the active transport text buffer at [this+0x1c]. When the caller sample is already present it bypasses transport submission through multiplayer_transport_dispatch_registered_name_query_fastpath. Otherwise it validates the sample through multiplayer_transport_has_registered_name packages the request through multiplayer_transport_enqueue_names_query_record and when immediate draining is requested loops through multiplayer_transport_drain_request_text_queue system_sleep_milliseconds and multiplayer_transport_is_request_pending. Current grounded callers are multiplayer_transport_handle_bound_route_request and multiplayer_transport_handle_selector_text_route_request.,ghidra + rizin + llvm-objdump + strings
0x0058eb70,212,multiplayer_transport_append_getkey_command,shell,cdecl,inferred,rizin,3,Formats one `GETKEY %s %s 0 :` command into a temporary 0x200-byte stack buffer and appends it to the owned transport text stream through multiplayer_transport_text_stream_append_crlf_line. After the fixed header it walks the caller string-vector argument and appends each additional item separated by backslashes. Current grounded caller is the synchronous submit wrapper at 0x0058ec50.,rizin + llvm-objdump + strings
0x0058ec50,140,multiplayer_transport_submit_getkey_command_and_wait,shell,cdecl,inferred,rizin,3,Synchronous `GETKEY` submit wrapper for the multiplayer transport worker. It resolves the query name from the caller string or falls back to [this+0x36c] primes one transient request through 0x0058eb30 emits the command text through multiplayer_transport_append_getkey_command and then loops through multiplayer_transport_drain_request_text_queue system_sleep_milliseconds and multiplayer_transport_is_request_pending until the request completes.,rizin + llvm-objdump + strings
0x0058ece0,197,multiplayer_transport_append_setchankey_or_setckey_command,shell,cdecl,inferred,rizin,3,Formats either `SETCHANKEY %s :` or `SETCKEY %s %s :` into a temporary 0x200-byte stack buffer and appends the resulting line to the owned transport text stream through multiplayer_transport_text_stream_append_crlf_line. The two-token `SETCKEY` form is selected when the optional caller key string at arg_210h is present and non-empty; otherwise the helper emits the simpler channel-key form.,rizin + llvm-objdump + strings
0x0058edb0,367,multiplayer_transport_append_setchankey_pair_list_command,shell,cdecl,inferred,rizin,2,Builds one larger backslash-delimited channel-key payload and appends it to the owned transport text stream through multiplayer_transport_text_stream_append_crlf_line. The helper formats normalized `\\%s\\%s` pair fragments in a 0x200-byte stack buffer converts backslashes to forward slashes in one staging path handles wildcard samples through the `*` token at 0x005e1e1c and is the main text builder beneath the synchronous submit wrapper at 0x0058ef20.,rizin + llvm-objdump + strings
0x0058ef20,199,multiplayer_transport_submit_setchankey_pair_list_command_and_wait,shell,cdecl,inferred,rizin,2,Synchronous channel-key submit wrapper for the multiplayer transport worker. It primes one transient request through 0x0058eb30 emits the larger backslash-delimited key payload through multiplayer_transport_append_setchankey_pair_list_command dispatches the caller result path through 0x005983b0 or 0x005984c0 depending on the staged optional arguments and then loops through multiplayer_transport_drain_request_text_queue system_sleep_milliseconds and multiplayer_transport_is_request_pending until the request completes.,rizin + llvm-objdump + strings
0x0058eff0,78,multiplayer_transport_is_valid_nick_string,shell,cdecl,inferred,rizin,4,Validates one transport nick string. It rejects null or empty strings rejects a leading digit or `-` through 0x005a53f2 and then scans every remaining byte against the allowed nick-character table at 0x005e1c70. It returns 1 when the full string is acceptable and 0 otherwise.,rizin + llvm-objdump + strings
0x0058f040,90,multiplayer_transport_dispatch_or_release_callback_binding,shell,cdecl,inferred,rizin,3,Generic dispatcher for one optional transport callback-binding structure. When binding field [this+0x0c] is present it packages the caller mode from EDX together with binding fields [this+0x18] and [this+0x36c] into opcode 0x1a through 0x0059b790. Otherwise it clears [this+0x04] and if callback pointer [this+0x14] is installed invokes it directly with the owner cookie at [this+0x18] and a zero status value.,rizin + llvm-objdump + strings
0x0058f380,64,tracked_heap_alloc_with_header,support,cdecl,inferred,ghidra-headless,4,Allocates one caller-sized heap block through the shared allocator at 0x005a125d stores the payload size in a 4-byte header immediately before the returned pointer and updates the global allocation counters at 0x00dba4c8 through 0x00dba4d0. Callers treat the returned value as a payload pointer just past the size header.,rizin + llvm-objdump
0x0058f3c0,43,tracked_heap_free_with_header,support,cdecl,inferred,ghidra-headless,4,Releases one heap block previously returned by tracked_heap_alloc_with_header. It reads the stored payload size from the 4-byte header decrements the shared allocation counters at 0x00dba4c8 and 0x00dba4cc and frees the underlying base pointer through 0x005a1145.,rizin + llvm-objdump
0x0058f3f0,94,tracked_heap_resize_with_header,support,cdecl,inferred,ghidra-headless,4,Resizes one header-tracked heap block to a new payload size. Null plus nonzero size falls through to tracked_heap_alloc_with_header; nonnull plus zero size frees through tracked_heap_free_with_header; and the main path reallocates through 0x005a5922 while preserving and re-accounting the payload size tracked in the 4-byte header.,rizin + llvm-objdump
0x0058f460,8,system_sleep_milliseconds,support,cdecl,inferred,ghidra-headless,4,Tiny wrapper over `Sleep` that forwards the caller millisecond delay in `ecx`. Current grounded callers use it as the 10 ms backoff inside immediate transport-drain loops.,rizin + llvm-objdump
0x005928a0,189,multiplayer_transport_enqueue_opcode_record,shell,cdecl,inferred,ghidra-headless,3,Common allocator and queue-submit helper for session-event transport opcode records. It allocates a zeroed caller-sized record through tracked_heap_alloc_with_header invokes the opcode-specific initializer from the handler table at 0x005e2004 plus opcode times 0x10 packages the resulting payload together with caller metadata into 0x0059e4d0 and increments [this+0x1800] on success. Allocation or initializer failure releases the temporary record through tracked_heap_free_with_header and returns -1.,ghidra + rizin + llvm-objdump
0x00592a40,40,multiplayer_transport_dispatch_callback_table_binding,shell,cdecl,inferred,ghidra-headless,2,Small binding-dispatch wrapper over multiplayer_transport_enqueue_opcode_record with opcode `4`. Current grounded callers use it after preparing callback-table descriptor fields from a live transport registration object and then continue through the common transport cleanup or release path.,ghidra + rizin + llvm-objdump
0x00592a70,109,multiplayer_transport_probe_or_enqueue_route_record,shell,cdecl,inferred,ghidra-headless,2,Small route-probe wrapper over multiplayer_transport_enqueue_opcode_record. It first calls multiplayer_transport_is_route_mode_active_nonterminal and when that succeeds with caller mode `2` directly invokes the supplied callback; otherwise it falls back to an 0x08-byte opcode `1` record built from the caller callback and payload fields.,ghidra + rizin + llvm-objdump
0x00592ae0,111,multiplayer_transport_enqueue_descriptor_block_record,shell,cdecl,inferred,ghidra-headless,2,Copies one caller-supplied seven-dword descriptor block into a local buffer and enqueues it through multiplayer_transport_enqueue_opcode_record as a 0x1c-byte opcode `2` record. Current grounded callers come from the deeper callback-table registration path.,ghidra + rizin + llvm-objdump
0x00592b50,226,multiplayer_transport_enqueue_field_snapshot_record,shell,cdecl,inferred,ghidra-headless,3,Builds and enqueues one field-snapshot transport record through multiplayer_transport_enqueue_opcode_record using opcode `3` and a 0x14-byte payload. Depending on the caller mode it can first remove prior matching entries through 0x005929f0 then normalizes the `hostname` field against `(No Name)` samples the `gamemode` field and compares it against `openstaging` computes a 0 to 100 progress scalar from counters around [this+0x1734] [this+0x1740] and [this+0x1774] and packages the subscribed callback pointers from [this+0x176c] and [this+0x1770].,ghidra + rizin + llvm-objdump + strings
0x00592c40,54,multiplayer_transport_enqueue_callback_binding_record,shell,cdecl,inferred,ghidra-headless,2,Builds and enqueues one 0x08-byte opcode `4` callback-binding record through multiplayer_transport_enqueue_opcode_record. The helper uses the registered callback-table pointer at [this+0x4c] and is the direct worker beneath multiplayer_transport_dispatch_callback_table_binding.,ghidra + rizin + llvm-objdump
0x00592c80,80,multiplayer_transport_enqueue_callback_slot9_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x10-byte opcode `9` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x1790] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592cd0,85,multiplayer_transport_enqueue_callback_slot10_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x14-byte opcode `10` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x1794] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592d30,62,multiplayer_transport_enqueue_callback_slot11_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x04-byte opcode `11` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x1798] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592d70,77,multiplayer_transport_enqueue_callback_slot12_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that copies a caller-supplied seven-dword block and enqueues it as a 0x20-byte opcode `12` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x179c] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592dc0,72,multiplayer_transport_enqueue_callback_slot13_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x0c-byte opcode `13` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17a0] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592e10,72,multiplayer_transport_enqueue_callback_slot14_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x10-byte opcode `14` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17a4] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592e60,64,multiplayer_transport_enqueue_callback_slot15_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x08-byte opcode `15` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17a8] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00592ea0,64,multiplayer_transport_enqueue_callback_slot16_record,shell,cdecl,inferred,ghidra-headless,2,Gated callback-slot wrapper that enqueues one 0x08-byte opcode `16` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17ac] is set. The record is built around the callback-side state rooted near [this+0x17f8].,ghidra + rizin + llvm-objdump
0x00593460,87,multiplayer_transport_mark_selector_slot_records_stale,shell,cdecl,inferred,ghidra-headless,3,Scans the queued transport request collection at [this+0x1780] for records of type `1` or `2` whose selector-slot field at +0x1c matches the requested slot id. Matching records are marked stale by setting byte or dword field +0x38 to one. Current grounded caller is multiplayer_transport_reset_selector_slot.,ghidra + rizin + llvm-objdump
0x00593790,351,multiplayer_transport_handle_names_query_response,shell,cdecl,inferred,ghidra-headless,3,Completion callback for multiplayer_transport_submit_names_query_with_callback. If the request is already stale at +0x38 it just unlinks through 0x5933a0. On nonzero result it can update route-binding state through multiplayer_transport_is_route_mode_active_nonterminal and multiplayer_transport_try_connect_status_route_once seeds selector slot `2` through multiplayer_transport_init_selector_slot upserts returned name records through multiplayer_transport_upsert_selector_name_entry publishes `TOPIC` and `MODE` lines through multiplayer_transport_publish_topic_status_line and multiplayer_transport_publish_mode_level_status_line and may promote one deferred route binding into [this+0x1ec8]. On zero result it resets selector slot `2` and falls back to multiplayer_transport_probe_or_enqueue_route_record before unlinking the request.,ghidra + rizin + llvm-objdump + strings
0x005938f0,145,multiplayer_transport_handle_bound_route_request,shell,cdecl,inferred,ghidra-headless,3,Completion callback for multiplayer_transport_submit_bound_route_request. If the request is already stale at +0x38 it just unlinks through 0x5933a0. On nonzero result it can publish [req+0x24] through multiplayer_transport_publish_mode_key_status_line and then schedules multiplayer_transport_handle_names_query_response through multiplayer_transport_submit_names_query_with_callback. On zero result it resets selector slot `2` and falls back to multiplayer_transport_probe_or_enqueue_route_record before unlinking the request.,ghidra + rizin + llvm-objdump
0x00594690,76,multiplayer_transport_mark_selector_slot_views_dirty,shell,cdecl,inferred,ghidra-headless,2,Marks one selector slot dirty in the transport-side view state rooted at [this+0xac8]. It sets slot-specific dirty bits at +0xa0 and +0xa4 when backing arrays at [this+0xad0] or [this+0xadc] are populated and also sets +0xa8 for selector slot `2`. Current grounded callers are multiplayer_transport_set_selector_slot_flags and multiplayer_transport_upsert_selector_name_entry.,ghidra + rizin + llvm-objdump
0x00594bd0,97,multiplayer_transport_set_selector_slot_flags,shell,cdecl,inferred,ghidra-headless,3,Updates one selector-slot flag dword at [entry+0x5c] after resolving the current selector entry through 0x00594a40. When selector index `2` flips bit `1` it forwards the new bit value through multiplayer_transport_enqueue_callback_slot15_record and then notifies the shared selector-change callback path through 0x00593250 with selector id old flags and new flags.,ghidra + rizin + llvm-objdump
0x00594c40,103,multiplayer_transport_parse_selector_mode_letters,shell,cdecl,inferred,ghidra-headless,3,Parses one selector-mode letter string into a small bitmask by probing for the letters `s` `r` `g` `a` and `h`. Current grounded callers merge this mask into the selector-slot flags that live at [entry+0x5c].,ghidra + rizin + llvm-objdump + strings
0x00594cb0,65,multiplayer_transport_merge_selector_mode_mask,shell,cdecl,inferred,ghidra-headless,3,Resolves one selector entry through 0x00594a40 parses the caller mode-letter string through multiplayer_transport_parse_selector_mode_letters preserves the current presence bits 0x20 and 0x40 from [entry+0x5c] and commits the merged result through multiplayer_transport_set_selector_slot_flags.,ghidra + rizin + llvm-objdump + strings
0x00594d00,72,multiplayer_transport_set_selector_presence_mask,shell,cdecl,inferred,ghidra-headless,3,Overwrites the selector presence bits 0x20 and 0x40 in [entry+0x5c] from one caller byte mask while preserving the rest of the selector-slot flags. The helper then commits the new value through multiplayer_transport_set_selector_slot_flags.,ghidra + rizin + llvm-objdump
0x00594f20,142,multiplayer_transport_upsert_selector_name_entry,shell,cdecl,inferred,ghidra-headless,3,Looks up or creates one selector-name entry for the requested selector slot. It resolves the current slot entry through 0x594a40 allocates a new entry through 0x594e70 when no match exists marks the selector index active at [entry+0x40+slot*4] increments the per-slot generation counter at [this+0xab8+slot*4] applies the caller flag bits 0x20 and 0x40 into [entry+0x5c+slot*4] and then marks the slot views dirty through multiplayer_transport_mark_selector_slot_views_dirty. Current grounded callers come from multiplayer_transport_handle_names_query_response and multiplayer_transport_handle_selector_update_response.,ghidra + rizin + llvm-objdump
0x005950d0,101,multiplayer_transport_reset_selector_tables,shell,cdecl,inferred,ghidra-headless,4,Resets the three selector registration tables rooted at [this+0x80] [this+0x390] and [this+0x39c] together with state at [this+0x9a8] and [this+0x9ac]. When [this+0xab0] is set it preserves selector slot `0`; otherwise it clears all three selector slots.,ghidra + rizin + llvm-objdump
0x00595140,89,multiplayer_transport_set_selector_name,shell,cdecl,inferred,ghidra-headless,4,Copies one selector name into the fixed 0x101-byte selector-name slot at [this+0x80+index*0x101] when the caller string fits. It then marks the selector present at [this+0x384+index*4] and clears the paired transient pointer at [this+0x99c+index*4].,ghidra + rizin + llvm-objdump
0x005951a0,67,multiplayer_transport_find_selector_name,shell,cdecl,inferred,ghidra-headless,4,Scans the three selector-name slots rooted at [this+0x80] for an exact string match and returns the matching selector index through the caller pointer. The callback-slot wrapper family uses this helper before enqueueing several selector-bound opcode records.,ghidra + rizin + llvm-objdump
0x005951f0,579,multiplayer_transport_service_status_pump,shell,cdecl,inferred,ghidra-headless,3,Central session-event transport status-pump and route-service loop. It inspects selector presence under [this+0x384] and [this+0x390] builds temporary selector-mode masks through multiplayer_transport_parse_selector_mode_letters emits status text and field updates through multiplayer_transport_append_setchankey_or_setckey_command multiplayer_transport_dispatch_field_snapshot_mode and related helpers and drives the deeper route-state machine through multiplayer_transport_init_selector_slot multiplayer_transport_reset_selector_slot 0x005965d0 0x0059f3c0 and related helpers.,ghidra + rizin + llvm-objdump + strings
0x00595440,98,multiplayer_transport_init_selector_slot,shell,cdecl,inferred,ghidra-headless,3,Initializes one selector slot under [this+0x384] and [this+0x390]. It copies caller text or the default sample at 0x005c87a8 into the fixed selector buffer at [slot+0x39c] clears byte [slot+0x59b] reruns multiplayer_transport_service_status_pump and then notifies multiplayer_transport_submit_profile_key_query_bundle_default for the refreshed selector slot.,ghidra + rizin + llvm-objdump + strings
0x005954b0,238,multiplayer_transport_reset_selector_slot,shell,cdecl,inferred,ghidra-headless,3,Resets one selector slot under [this+0x384] and [this+0x390]. When the slot is active it tears the current selector object down through 0x593460 optionally republishes caller text through 0x58e7a0 refreshes selector bookkeeping through 0x5950a0 and clears the active and present flags before returning.,ghidra + rizin + llvm-objdump
0x00595620,35,multiplayer_transport_release_route_binding,shell,cdecl,inferred,ghidra-headless,3,Releases the current route binding stored at [this+0x1ec8]. It detaches the binding from the descriptor object at [this+0x1ed0] through 0x58f3c0 unlinks it through 0x5933a0 and clears [this+0x1ec8].,ghidra + rizin + llvm-objdump
0x00595650,688,multiplayer_transport_set_route_mode,shell,cdecl,inferred,ghidra-headless,3,Main route-mode state machine for the session-event transport. It latches the requested small mode at [this+0x18b8] and dispatches modes `0` through `5` across live-route teardown selector-slot init or reset am-rating route seeding live-route connect and route-binding release paths. The branch uses multiplayer_transport_release_live_route multiplayer_transport_try_seed_am_rating_route_table multiplayer_transport_try_connect_live_route and multiplayer_transport_release_route_binding to converge on the next stable mode.,ghidra + rizin + llvm-objdump + strings
0x005958e0,156,multiplayer_transport_try_stage_route_callback_payload,shell,cdecl,inferred,ghidra-headless,2,Builds one staged route-callback payload from the caller route object and transport-local text buffer at [this+0x60]. It extracts several caller fields through the 0x58d1f0 0x58d240 0x58d220 and 0x58d250 or 0x58d200 helpers packs them through multiplayer_transport_format_gsp_payload submits the staged text through multiplayer_transport_submit_selector_text_route_request and on success stores the cloned callback payload returned by multiplayer_transport_clone_staged_callback_payload at [this+0xb50].,ghidra + rizin + llvm-objdump + strings
0x00595980,84,multiplayer_transport_handle_route_status_result,shell,cdecl,inferred,ghidra-headless,2,Completion callback used by multiplayer_transport_submit_route_status_request. When the callback result is nonzero it compares the live status counters at [this+0xac0] and [this+0xb48] and advances the route-mode state machine through mode `2` or modes `3` or `4`. When the callback result is zero it sets [this+0x1ed8] and re-enters multiplayer_transport_set_route_mode using the current am-rating route state at [this+0x1ed4].,ghidra + rizin + llvm-objdump
0x005959e0,81,multiplayer_transport_submit_route_status_request,shell,cdecl,inferred,ghidra-headless,3,Submits one route-status request for the current binding at [this+0x1ec8]. It gathers the binding fields at +0x2c and +0x30 together with the local counter at [this+0xb48] and default sample text at 0x005c87a8 then sends that request through 0x593980 using multiplayer_transport_handle_route_status_result as the completion callback. Failure sets [this+0x1ed8] so the route-mode setter can fall back immediately.,ghidra + rizin + llvm-objdump
0x00596270,70,multiplayer_transport_clone_staged_callback_payload,shell,cdecl,inferred,ghidra-headless,3,Clones one staged route-callback payload block by allocating a same-sized object through 0x58d5b0 copying the first nine dwords and then registering a cleanup callback through 0x58fa00 with shim 0x596260. Current grounded caller is multiplayer_transport_try_stage_route_callback_payload.,ghidra + rizin + llvm-objdump
0x00597720,96,multiplayer_transport_format_gsp_payload,shell,cdecl,inferred,ghidra-headless,3,Formats one transport text payload with the `#GSP!%s!%c%s%c` template at 0x005e2358. Depending on whether the global formatter state at 0x00dba4c4 is present it builds either a 0x58-byte or 0x4d-byte intermediate fragment through 0x597590 or 0x5976c0 and then emits the final string through 0x5a19c4. Current grounded callers are multiplayer_transport_submit_bound_route_request and multiplayer_transport_try_stage_route_callback_payload.,ghidra + rizin + llvm-objdump + strings
0x00593980,382,multiplayer_transport_submit_bound_route_request,shell,cdecl,inferred,ghidra-headless,3,Builds and submits one bound-route request using the current transport text buffers and a caller-supplied binding id or fallback route id. It formats the request payload through multiplayer_transport_format_gsp_payload allocates a type `1` transient request record through 0x5934e0 stores route and callback metadata on that record publishes selector `2` text through multiplayer_transport_set_selector_name and finally submits the request through 0x58e720 using multiplayer_transport_handle_bound_route_request. A nonempty caller text sample sets [this+0xb4c].,ghidra + rizin + llvm-objdump + strings
0x00593b00,161,multiplayer_transport_handle_selector_update_response,shell,cdecl,inferred,ghidra-headless,3,Follow-up callback used by multiplayer_transport_handle_selector_text_route_request. When the callback succeeds it initializes or repopulates selector slot [req+0x1c] through multiplayer_transport_init_selector_slot and multiplayer_transport_upsert_selector_name_entry. When it fails it resets that selector slot. Both paths finish by enqueueing a route record through multiplayer_transport_probe_or_enqueue_route_record and unlinking the request through 0x5933a0.,ghidra + rizin + llvm-objdump
0x00593bb0,144,multiplayer_transport_handle_selector_text_route_request,shell,cdecl,inferred,ghidra-headless,3,Completion callback for multiplayer_transport_submit_selector_text_route_request. If the request is already stale at +0x38 it clears the transient state through 0x5962c0 and unlinks the request. On nonzero result it schedules multiplayer_transport_handle_selector_update_response through multiplayer_transport_submit_names_query_with_callback. On zero result it resets selector slot [req+0x1c] and falls back to multiplayer_transport_probe_or_enqueue_route_record before unlinking the request.,ghidra + rizin + llvm-objdump
0x00593c40,177,multiplayer_transport_submit_selector_text_route_request,shell,cdecl,inferred,ghidra-headless,3,Builds and submits one selector-text route request. It validates the caller text defaults the sample text to 0x005c87a8 allocates a type `2` transient request record through 0x5934e0 stores the selector id at +0x1c refreshes selector naming through 0x59fc80 and multiplayer_transport_set_selector_name and then submits the request through 0x58e720 using multiplayer_transport_handle_selector_text_route_request.,ghidra + rizin + llvm-objdump + strings
0x00595a40,245,multiplayer_transport_dispatch_field_snapshot_mode,shell,cdecl,inferred,ghidra-headless,3,Dispatches several session-field snapshot update modes into multiplayer_transport_enqueue_field_snapshot_record. Depending on the mode it can enqueue hostname or gamemode snapshots clear the progress scalar at [this+0x1774] reset the callback payload to zero or copy one dword from [eax+0x490] into [this+0x54] while updating the local field cache rooted at [this+0x1724].,ghidra + rizin + llvm-objdump + strings
0x00595b60,25,multiplayer_transport_enqueue_field_snapshot_mode1_if_enabled,shell,cdecl,inferred,ghidra-headless,2,Tiny field-snapshot wrapper that enqueues one mode-1 field snapshot only when the caller enable flag is zero. The helper is a thin front end over multiplayer_transport_enqueue_field_snapshot_record.,ghidra + rizin + llvm-objdump
0x00595b80,50,multiplayer_transport_clear_progress_field_cache,shell,cdecl,inferred,ghidra-headless,3,Clears the progress-related field cache rooted at [this+0xba0] and then clears the local field cache at [this+0x1724]. It finishes by forwarding mode `3` into 0x005929a0 to remove the matching queued field-snapshot records.,ghidra + rizin + llvm-objdump + strings
0x00595bc0,272,multiplayer_transport_enqueue_capacity_descriptor_record,shell,cdecl,inferred,ghidra-headless,3,Builds and enqueues one descriptor-block transport record tied to the capacity or progress cache at [this+0x1778]. One branch forwards cached descriptor fields directly through multiplayer_transport_enqueue_descriptor_block_record while the live branch samples hostname openstaging gamemode and numplayers strings from the current transport object before enqueueing the same opcode-2 descriptor record.,ghidra + rizin + llvm-objdump + strings
0x00595ce0,22,multiplayer_transport_clear_capacity_descriptor_cache,shell,cdecl,inferred,ghidra-headless,3,Clears the auxiliary capacity-descriptor cache when [this+0xba0] is present by forwarding the embedded object at [this+0xba4] into 0x00590740. Current grounded callers use this before disconnect or larger route-state cleanup.,ghidra + rizin + llvm-objdump
0x00595d60,84,multiplayer_transport_check_openstaging_capacity_gate,shell,cdecl,inferred,ghidra-headless,2,Checks whether the current transport object still matches the cached openstaging-like descriptor and whether numplayers remains below maxplayers. When the cached route object at [this+0x1ecc] already matches the current transport identifiers it returns success immediately; otherwise it compares the current maxplayers and numplayers fields and on success falls into 0x00592710 for the caller's route transition path.,ghidra + rizin + llvm-objdump + strings
0x00595dc0,79,multiplayer_transport_try_transition_after_capacity_gate,shell,cdecl,inferred,ghidra-headless,2,Rejects when [this+0x1e8c] or selector slot [this+0x38c] is busy then runs multiplayer_transport_check_openstaging_capacity_gate refreshes route-side state through 0x5973b0 and 0x5954b0 forwards the caller event into 0x5958e0 and on success transitions through 0x595650 mode `0`.,ghidra + rizin + llvm-objdump
0x00595e10,321,multiplayer_transport_dispatch_route_event_mode,shell,cdecl,inferred,ghidra-headless,2,Dispatches route-event modes for the callback branch rooted at [this+0x18bc]. Depending on the mode it may update [this+0x18bc] or [this+0x1e7c] reuse multiplayer_transport_try_transition_after_capacity_gate force mode `2` through 0x595650 or copy a selected descriptor pointer into [this+0x54]. Current surrounding evidence ties this branch to the `gsi_am_rating` route table.,ghidra + rizin + llvm-objdump
0x00595f70,237,multiplayer_transport_dispatch_am_rating_route_callback,shell,cdecl,inferred,ghidra-headless,3,Callback handler for the `gsi_am_rating` route branch rooted at [this+0x18bc]. Mode `0` forwards directly into multiplayer_transport_try_transition_after_capacity_gate while mode `2` prunes stale route entries against multiplayer_transport_check_openstaging_capacity_gate updates surviving entries through 0x58d130 with the `gsi_am_rating` token and either forces mode `2` or forwards the surviving head entry into 0x5958e0 before transitioning through 0x595650 mode `0`.,ghidra + rizin + llvm-objdump + strings
0x00596060,48,multiplayer_transport_reset_am_rating_route_state,shell,cdecl,inferred,ghidra-headless,3,Small reset helper for the active `gsi_am_rating` route state. When [this+0xba0] is set it clears the route callback table at [this+0x18bc] resets [this+0x1ec4] to zero and clears the auxiliary route cache at [this+0x1e7c].,ghidra + rizin + llvm-objdump + strings
0x00596090,272,multiplayer_transport_init_route_callback_tables,shell,cdecl,inferred,ghidra-headless,3,Initializes route callback tables at [this+0xba4] [this+0x1724] [this+0x1164] [this+0x18bc] and [this+0x1e7c]. Installs handlers 0x00595a40 0x00595b60 0x00595bc0 0x00595e10 and multiplayer_transport_dispatch_am_rating_route_callback seeds default selector text from static tables and sets [this+0xba0].,ghidra + rizin + llvm-objdump
0x005961b0,92,multiplayer_transport_teardown_route_callback_tables,shell,cdecl,inferred,ghidra-headless,4,Clears progress and capacity caches destroys the callback tables at [this+0xba4] [this+0x1164] and [this+0x18bc] clears the related caches at [this+0x1724] and [this+0x1e7c] and resets [this+0x1ec4] to zero.,ghidra + rizin + llvm-objdump
0x005962e0,583,multiplayer_transport_register_field_subscription_bundle,shell,cdecl,inferred,ghidra-headless,3,Builds one field-subscription bundle from the field-id list optional suffix text and selector-name table. Rebuilds the callback table at [this+0xba4] seeds the local field cache at [this+0x1724] installs the subscription block through 0x590ed0 sets [this+0x1774] on success and enqueues an immediate mode-3 field snapshot through multiplayer_transport_enqueue_field_snapshot_record.,ghidra + rizin + llvm-objdump
0x00596530,101,multiplayer_transport_try_seed_am_rating_route_table,shell,cdecl,inferred,ghidra-headless,2,Used by the larger route-mode setter around 0x595650. It first calls multiplayer_transport_reset_am_rating_route_state then rebuilds one mode `4` route entry in the callback table at [this+0x18bc] from the stored descriptor at [this+0x1ed0]. Success clears [this+0x1ed4] sets [this+0x1ec4] to one and failure reverts through multiplayer_transport_reset_am_rating_route_state before setting [this+0x1ed4].,ghidra + rizin + llvm-objdump + strings
0x005965a0,44,multiplayer_transport_try_connect_status_route_once,shell,cdecl,inferred,ghidra-headless,3,Single-shot wrapper for the auxiliary status-route object at [this+0xaf0]. When the in-flight latch at [this+0xb40] is already set it returns false immediately. Otherwise it sets that latch and forwards the caller route id into multiplayer_transport_try_connect_status_route then booleanizes the result. Current grounded caller is multiplayer_transport_handle_names_query_response.,ghidra + rizin + llvm-objdump
0x00596da0,497,multiplayer_transport_submit_profile_key_query_bundle,shell,cdecl,inferred,rizin,2,Wrapper above the transport key-command builders that stages a small named-key query bundle around the strings `username` and `b_flags`. It allocates temporary key-name arrays and callback-entry tables submits the first request through multiplayer_transport_submit_getkey_command_and_wait folds returned key results into transport-owned callback state through 0x0058f8f0 and 0x0058fa00 and then follows with the larger channel-key submission path through multiplayer_transport_submit_setchankey_pair_list_command_and_wait when the staged key set is nonempty.,rizin + llvm-objdump + strings
0x00596fa0,19,multiplayer_transport_submit_profile_key_query_bundle_with_context,shell,cdecl,inferred,rizin,2,Thin wrapper over multiplayer_transport_submit_profile_key_query_bundle that preserves the caller selector or route context in `edx` and forwards the stack-supplied context pointer as the extra bundle argument. Current grounded use is through the local callback table rooted at 0x0059f8b0.,rizin + llvm-objdump
0x00596fc0,14,multiplayer_transport_submit_profile_key_query_bundle_default,shell,cdecl,inferred,rizin,3,Thin wrapper over multiplayer_transport_submit_profile_key_query_bundle that preserves the caller selector slot in `edx` and forces a null extra-context argument. Current grounded caller is multiplayer_transport_init_selector_slot and the same wrapper is also installed through the local callback table rooted at 0x0059fb60.,rizin + llvm-objdump
0x00596fd0,441,multiplayer_transport_dispatch_status_route_event,shell,cdecl,inferred,rizin,3,Main local callback dispatcher for the auxiliary status-route object. It gates on [this+0x398] [this+0xb44] and flag bits in [this+0xb38] then maps route event ids through the local table at 0x005970c4 into selector text publication openstaging publication boolean status publication and callback forwarding paths. The dispatcher publishes through multiplayer_transport_send_selector_text and multiplayer_transport_publish_fixed_token_message and can also invoke the owner callback at [this+0x17dc] with payload [this+0x17f8].,rizin + llvm-objdump + strings
0x00597350,30,multiplayer_transport_release_status_route,shell,cdecl,inferred,ghidra-headless,3,Releases the auxiliary status-route object stored at [this+0xaf0] through 0x58cfd0 and clears the owner slot afterward. Status-pump cleanup fixed-token publishing and the auxiliary route connect helper use this before rebuilding status-route state.,ghidra + rizin + llvm-objdump
0x005973d0,170,multiplayer_transport_try_connect_status_route,shell,cdecl,inferred,ghidra-headless,3,Attempts to connect or rebuild the auxiliary status-route object at [this+0xaf0]. It first tears any existing status route down through multiplayer_transport_release_status_route then builds a callback table from the local handler set rooted at multiplayer_transport_dispatch_status_route_event through 0x5972c0 chooses either the default route id `0x1964` or the caller route id and connects through 0x58cc40 or 0x58c9b0. On success it copies [this+0x9a8] into [this+0xb3c] wires the created route object through 0x58bc90 using callback 0x597330 and clears [this+0xb38].,ghidra + rizin + llvm-objdump + strings
0x005973b0,30,multiplayer_transport_release_live_route,shell,cdecl,inferred,ghidra-headless,4,Releases the current live route object stored at [this+0x1ecc] through 0x58cfd0 and clears the owner slot afterward. The route-mode setter and connect helper use it before rebuilding or switching live route state.,ghidra + rizin + llvm-objdump
0x00597480,261,multiplayer_transport_try_connect_live_route,shell,cdecl,inferred,ghidra-headless,3,Attempts to connect or rebuild the current live route object at [this+0x1ecc]. It first clears any existing live route through multiplayer_transport_release_live_route then formats a local identifier from [this+0x60] and 0x005dccfc chooses either the default route id `0x1964` or the binding-specific id and connects through 0x58cc40 or 0x58c9b0. On success it updates [this+0x1ed8] and preserves the new live route state for the route-mode setter.,ghidra + rizin + llvm-objdump + strings
0x00598230,67,multiplayer_transport_enqueue_names_query_record,shell,cdecl,inferred,ghidra-headless,3,Allocates one 0x10-byte transient names-query work item zeroes its four dword fields and submits it through 0x5980f0 as request kind `3` using the caller-provided sample or callback context pointer. The helper returns the allocated work item on success and null on allocation or submit failure. Current grounded caller is multiplayer_transport_submit_names_query_with_callback.,ghidra + rizin + llvm-objdump
0x0058f0a0,99,multiplayer_transport_append_user_and_optional_nick_commands,shell,cdecl,inferred,rizin,3,Builds the initial identity command bundle for one multiplayer transport worker. It appends `USER %s %s %s :%s` to the owned text stream using worker text fields at [this+0x3ac] [this+0x42c] and [this+0x4b0] together with the fallback host `127.0.0.1` then checks the current nick through multiplayer_transport_is_valid_nick_string and either falls through multiplayer_transport_dispatch_or_release_callback_binding with mode `1` or appends `NICK %s` directly through the same text-stream path.,rizin + llvm-objdump + strings
0x0058f920,72,hashed_entry_table_upsert,support,cdecl,inferred,rizin,4,Generic hashed-entry-table upsert over a bucket array of contiguous vectors. It computes the bucket index through the table hash callback at [this+0x0c] looks for an existing matching entry through hashed_entry_table_lookup and when found overwrites that slot through generic_vector_overwrite_with_callback; otherwise it appends the caller record into the selected bucket vector through 0x0059e4d0.,rizin + llvm-objdump
0x0058f970,69,hashed_entry_table_remove,support,cdecl,inferred,rizin,4,Generic hashed-entry-table remove over a bucket array of contiguous vectors. It hashes the caller key into one bucket and erases the matching slot through generic_vector_erase_with_callback when present; otherwise it returns false.,rizin + llvm-objdump
0x0058f9c0,63,hashed_entry_table_lookup,support,cdecl,inferred,rizin,4,Generic hashed-entry-table lookup over a bucket array of contiguous vectors. It hashes the caller key into one bucket resolves the matching index through generic_vector_find_index and returns the matched entry pointer or null.,rizin + llvm-objdump
0x0058f110,465,multiplayer_transport_worker_init,shell,cdecl,inferred,rizin,3,"Initializes one heap-backed multiplayer transport worker and its owned text-stream and store state. It zeroes the `0x5e4`-byte worker copies caller identifier strings into the fixed buffers at `[this+0x00]`, `[this+0x36c]`, `[this+0x3ac]`, `[this+0x42c]`, and `[this+0x4b0]`, copies one 5-dword descriptor block into `[this+0x534]`, seeds the state fields at `[this+0x04]` and `[this+0x558]`, initializes the registered-name store at `[this+0x548]`, the pending-template dispatch store at `[this+0x54c]`, and the owned text-stream object at `[this+0x1c]`, and tears partial state back down on failure.","rizin + llvm-objdump"
0x0058f2f0,60,multiplayer_transport_worker_create,shell,cdecl,inferred,rizin,3,"Thin allocation wrapper for multiplayer_transport_worker_init. It allocates one `0x5e4`-byte worker block through tracked_heap_alloc_with_header and then forwards the descriptor pointer already staged in `EDX` plus the caller argument bundle into multiplayer_transport_worker_init.","rizin + llvm-objdump"
0x0059d430,47,string_hash_sum_mod,support,cdecl,inferred,rizin,3,Small string-hash helper that accumulates one normalized integer value per input byte through 0x005a5900 and returns the running sum modulo the caller divisor. Current grounded callers use it as the bucket-selector callback for registered-name entry tables.,rizin + llvm-objdump
0x0059d470,57,multiplayer_transport_lookup_registered_name,shell,cdecl,inferred,ghidra-headless,3,Copies one caller string into a stack-local buffer and looks it up against the registered-name store rooted at [this+0x548] through hashed_entry_table_lookup. It returns the matched entry pointer or null. Current grounded callers are multiplayer_transport_has_registered_name and the deeper names-query payload helper family.,ghidra + rizin + llvm-objdump
0x0059d520,91,multiplayer_transport_init_registered_name_store,shell,thiscall,inferred,rizin,4,Initializes the transport-side registered-name store by allocating the hashed bucket table at [this+0x548] with 7 buckets and a 0x1e0-byte entry shape through 0x0058f840 and then allocating the companion flat entry vector at [this+0x54c] through 0x0059e0b0. On allocation failure it tears any partial state back down.,rizin + llvm-objdump
0x0059d580,35,multiplayer_transport_destroy_registered_name_store,shell,thiscall,inferred,rizin,4,Destroys the transport-side registered-name store by releasing the hashed bucket table at [this+0x548] through 0x0058f8b0 and the companion flat entry vector at [this+0x54c] through generic_vector_destroy when present.,rizin + llvm-objdump
0x0059d610,81,multiplayer_transport_contains_registered_name_entry,shell,cdecl,inferred,rizin,3,Linear membership check over the flat registered-name entry vector at [this+0x54c]. It compares each live entry against the caller key through 0x005a57cf and returns true on the first exact match.,rizin + llvm-objdump
0x0059d670,240,multiplayer_transport_upsert_registered_name_entry,shell,cdecl,inferred,rizin,3,Builds one temporary 0x1e0-byte registered-name entry on the stack from the caller descriptor and name string; allocates the entry-owned callback table through 0x0058f840; removes any older flat-vector entry with the same key from [this+0x54c]; and then inserts or replaces the canonical entry in the hashed registered-name store at [this+0x548] through hashed_entry_table_upsert.,rizin + llvm-objdump
0x0059d760,103,multiplayer_transport_remove_registered_name_entry,shell,cdecl,inferred,rizin,4,Copies the caller name into a stack-local temporary key; removes any matching entry from the flat registered-name vector at [this+0x54c]; and then removes the canonical hashed-store entry from [this+0x548] through hashed_entry_table_remove.,rizin + llvm-objdump
0x0058fa00,49,generic_callback_list_for_each,support,cdecl,inferred,ghidra-headless,4,Generic callback-list walker over one `[items count]` style callback collection. It uses generic_vector_for_each to visit every entry pointer and forwards the caller context through the supplied callback shim unchanged. Transport registration and the registered-name fast path reuse it to fan out one callback over all registered entries.,rizin + llvm-objdump
0x0059e110,3,generic_vector_count,support,cdecl,inferred,rizin,4,Returns the current element count from dword [this+0x00] for one contiguous vector-style container.,rizin + llvm-objdump
0x0059e120,10,generic_vector_index_ptr,support,cdecl,inferred,rizin,4,Computes one element pointer as base [this+0x14] plus index times stride [this+0x08]. Most higher-level vector helpers funnel slot access through this helper.,rizin + llvm-objdump
0x0059e130,58,generic_vector_erase,support,cdecl,inferred,rizin,4,Removes one indexed element from a contiguous vector. When the erased slot is not already the tail it memmoves the trailing span down and then decrements the element count at [this+0x00].,rizin + llvm-objdump
0x0059e170,21,generic_vector_sort,support,cdecl,inferred,rizin,4,Sorts the backing element range at [this+0x14] through the shared qsort-style helper using the current count and stride from the vector header.,rizin + llvm-objdump
0x0059e190,49,generic_vector_for_each,support,cdecl,inferred,rizin,4,Forward iterator for one contiguous vector. It walks indices `0..count-1` resolves each slot through generic_vector_index_ptr and invokes the caller callback with the shared context argument.,rizin + llvm-objdump
0x0059e1d0,42,generic_vector_for_each_reverse,support,cdecl,inferred,rizin,4,Reverse iterator for one contiguous vector. It walks indices `count-1..0` and invokes the caller callback on each resolved slot pointer.,rizin + llvm-objdump
0x0059e200,61,generic_vector_find_first,support,cdecl,inferred,rizin,4,Scans the vector from the front and returns the first element pointer whose caller predicate returns zero. When no match is found it returns null.,rizin + llvm-objdump
0x0059e2f0,19,generic_vector_invoke_element_callback,support,cdecl,inferred,rizin,4,Invokes the optional per-element callback stored at [this+0x10] for one indexed slot when that callback pointer is nonnull. Erase overwrite and destroy helpers reuse it before mutating storage.,rizin + llvm-objdump
0x0059e310,31,generic_vector_store_at,support,cdecl,inferred,rizin,4,Copies one caller-supplied element record into the indexed slot resolved through generic_vector_index_ptr using the current element stride from the vector header.,rizin + llvm-objdump
0x0059e330,49,generic_vector_destroy,support,cdecl,inferred,rizin,4,Walks all live elements through generic_vector_invoke_element_callback then frees the backing storage at [this+0x14] and finally releases the vector object itself through tracked_heap_free_with_header.,rizin + llvm-objdump
0x0059e370,87,generic_vector_insert_copy_at,support,cdecl,inferred,rizin,4,Ensures capacity grows through 0x0059e090 when full increments the count shifts the tail upward when inserting before the end and copies the caller element record into the requested slot through generic_vector_store_at.,rizin + llvm-objdump
0x0059e3d0,22,generic_vector_erase_with_callback,support,cdecl,inferred,rizin,4,Calls generic_vector_invoke_element_callback for the indexed slot and then removes that slot through generic_vector_erase. Current grounded callers use it for registered-name and callback-entry teardown paths.,rizin + llvm-objdump
0x0059e3f0,33,generic_vector_overwrite_with_callback,support,cdecl,inferred,rizin,4,Invokes generic_vector_invoke_element_callback for one indexed slot and then copies the caller replacement record back into that same slot through generic_vector_store_at. Hashed entry-table upsert uses it when replacing an existing matching record.,rizin + llvm-objdump
0x0059e420,137,generic_vector_find_index,support,cdecl,inferred,rizin,4,Returns the index of one matching element within the contiguous vector or `-1` when none is found. Depending on the caller flag it uses either the linear comparator scan at 0x0059e240 or the ordered search helper at 0x0059e290 and derives the final index from the matched element pointer and stride.,rizin + llvm-objdump
0x0059d7f0,86,multiplayer_transport_collect_registered_name_callback_entries,shell,cdecl,inferred,ghidra-headless,3,Callback collector used by the registered-name fast path. For each callback entry in the name entry's callback list it grows two parallel pointer arrays in the caller scratch frame through tracked_heap_resize_with_header and appends the callback entry pointer plus its `[entry+0xdc]` payload pointer. Current grounded caller is multiplayer_transport_dispatch_registered_name_query_fastpath through generic_callback_list_for_each.,ghidra + rizin + llvm-objdump
0x0059d850,114,multiplayer_transport_dispatch_registered_name_query_fastpath,shell,cdecl,inferred,ghidra-headless,3,Fast path for multiplayer_transport_submit_names_query_with_callback when the queried sample already exists in the registered-name table. It resolves the name entry through multiplayer_transport_lookup_registered_name collects entry-owned callback state through multiplayer_transport_collect_registered_name_callback_entries and invokes the caller callback through multiplayer_transport_invoke_registered_name_query_callback without enqueueing a transport names-query record. Temporary callback arrays are released through tracked_heap_free_with_header on exit.,ghidra + rizin + llvm-objdump
0x0059d8d0,15,multiplayer_transport_has_registered_name,shell,cdecl,inferred,ghidra-headless,3,Boolean wrapper over multiplayer_transport_lookup_registered_name. It returns true when the caller string resolves to one registered-name entry in the transport-side table and false otherwise. Current grounded caller is multiplayer_transport_submit_names_query_with_callback.,ghidra + rizin + llvm-objdump
0x0059d8e0,64,multiplayer_transport_try_read_registered_name_header_block,shell,cdecl,inferred,rizin,4,Looks up one registered-name entry and when the header-valid flag at `[entry+0x154]` is set copies the 7-dword header block at `[entry+0x138]` into the caller buffer and returns true. Otherwise it returns false without mutating the destination.,rizin + llvm-objdump
0x0059d920,48,multiplayer_transport_set_registered_name_header_block,shell,cdecl,inferred,rizin,4,Looks up one registered-name entry copies 7 caller-supplied dwords into the header block at `[entry+0x138]` and sets the paired valid flag at `[entry+0x154]` to one.,rizin + llvm-objdump
0x0059d950,112,multiplayer_transport_set_registered_name_status_text,shell,cdecl,inferred,rizin,3,Looks up one registered-name entry frees the prior heap string at `[entry+0x158]` and replaces it with a heap copy of the caller text or the shared empty string when the caller passes null. The helper currently looks like the main per-name status or topic text setter for the registered-name store.,rizin + llvm-objdump
0x0059d9c0,32,multiplayer_transport_mark_registered_name_dirty,shell,cdecl,inferred,rizin,3,Looks up one registered-name entry and sets the dword dirty or active flag at `[entry+0x15c]` to one.,rizin + llvm-objdump
0x0059d9e0,32,multiplayer_transport_get_registered_name_dirty,shell,cdecl,inferred,rizin,3,Looks up one registered-name entry and returns the current dword dirty or active flag stored at `[entry+0x15c]` or zero when the entry is absent.,rizin + llvm-objdump
0x0059da00,64,multiplayer_transport_set_registered_name_display_text,shell,cdecl,inferred,rizin,3,Looks up one registered-name entry copies up to 0x80 bytes of caller text into the embedded buffer at `[entry+0x160]` through string_copy_bounded_zerofill and clears the trailing byte flag at `[entry+0x1df]`. This is a second inline text field distinct from the heap string at `[entry+0x158]`.,rizin + llvm-objdump
0x0059da40,208,multiplayer_transport_upsert_registered_name_callback_entry,shell,cdecl,inferred,rizin,4,Looks up one registered-name entry zeroes a temporary 0xe0-byte nested callback-entry record copies the secondary key string into the local record and when both payload blocks are provided copies 0x18 bytes into `[record+0x80]` and 0x40 bytes into `[record+0x98]` sets the local active flag at `[record+0xd8]` and stores one caller dword at `[record+0xdc]` before upserting the record into the entry-owned callback table at `[entry+0x134]` through hashed_entry_table_upsert.,rizin + llvm-objdump
0x0059db10,80,multiplayer_transport_remove_registered_name_callback_entry,shell,cdecl,inferred,rizin,4,Looks up one registered-name entry copies the caller secondary key into a stack-local temporary and removes the matching nested callback-entry record from the entry-owned callback table at `[entry+0x134]` through hashed_entry_table_remove.,rizin + llvm-objdump
0x0059db90,96,multiplayer_transport_dispatch_registered_name_callback_entry,shell,cdecl,inferred,rizin,3,Fans one callback descriptor over the transport-side registered-name store. It copies the primary name into a stack-local key builds a small dispatch frame and visits all registered-name entries through generic_callback_list_for_each where helper 0x0059db60 resolves the matching nested callback-entry record and invokes the descriptor function pointer at `[desc+0x08]` with the descriptor owner context plus the secondary key plus the payload cookie plus the owning registered-name entry.,rizin + llvm-objdump
0x0059dcb0,48,multiplayer_transport_update_registered_name_callback_key,shell,cdecl,inferred,rizin,3,Visits every registered-name entry through generic_callback_list_for_each and runs helper 0x0059dbf0 to rewrite one nested callback-entry key. The helper removes the existing nested record from `[entry+0x134]` copies the replacement key into the local record reinserts it through hashed_entry_table_upsert and conditionally emits transport opcode 8 through 0x0059b790 when the name entry is marked dirty and has owner callbacks installed.,rizin + llvm-objdump
0x0059dce0,256,multiplayer_transport_update_registered_name_callback_flags,shell,cdecl,inferred,rizin,4,Looks up one registered-name entry then resolves one nested callback-entry record by secondary key from the entry-owned callback table at `[entry+0x134]`. Depending on the caller mode flag it ORs or clears the caller bitmask against `[subentry+0xdc]` and when the parent entry has transport callbacks installed publishes an opcode-11 update through 0x0059b790 carrying the primary name plus the secondary key plus the new flag mask.,rizin + llvm-objdump
0x0059de00,64,multiplayer_transport_dispatch_registered_name_callbacks,shell,cdecl,inferred,rizin,3,If the owning transport is active at `[*this]` it walks the full registered-name store through generic_callback_list_for_each and helper 0x0059dde0 increments a dispatch count and invokes the caller-provided callback function for each live registered-name entry.,rizin + llvm-objdump
0x0059de40,96,multiplayer_transport_stage_registered_name_callback_payload,shell,cdecl,inferred,rizin,3,Resolves one nested callback-entry record by secondary key from the caller registered-name entry then copies a 0x18-byte payload block into `[subentry+0x80]` and a 0x40-byte payload block into `[subentry+0x98]` null-terminates both copied regions and sets the active flag at `[subentry+0xd8]` to one.,rizin + llvm-objdump
0x0059dea0,96,multiplayer_transport_stage_registered_name_callback_payload_for_name,shell,cdecl,inferred,rizin,3,Looks up one primary registered-name entry then fans helper multiplayer_transport_stage_registered_name_callback_payload across the registered-name store through generic_callback_list_for_each using the caller secondary key plus the two payload buffers. Current grounded role is a primary-name keyed payload staging wrapper for nested callback-entry records.,rizin + llvm-objdump
0x0059df00,96,multiplayer_transport_try_resolve_registered_name_callback_payload,shell,cdecl,inferred,rizin,4,Fast resolver for one nested callback-entry payload. When the descriptor either has no selector string or matches the shared two-byte default token at 0x005e1e1c it looks up the nested callback-entry record by key from `[entry+0x134]` and if the entry is active at `[subentry+0xd8]` marks the descriptor successful and returns pointers to the staged payload blocks at `[subentry+0x80]` and `[subentry+0x98]`.,rizin + llvm-objdump
0x005934c0,30,multiplayer_transport_next_work_sequence,shell,thiscall,inferred,ghidra-headless,3,Returns the next monotonically increasing transport work-sequence value by incrementing dword [this+0x177c] and clamping negative wraparound back to zero. Current grounded callers use the returned value when allocating transient transport records for text submission registration and related async work.,ghidra + rizin + llvm-objdump
0x00593650,229,multiplayer_transport_attach_callback_table_descriptor,shell,cdecl,inferred,ghidra-headless,3,Builds one transport-side callback-table descriptor from the caller table pointers and metadata. The helper allocates a temporary registration object through 0x005934e0 installs callback vectors from the 0x0059f5c0 and 0x0059f650 tables copies the caller transport pointer into the local stack frame and finishes by linking the result through 0x0058f2f0 and 0x005933a0. The current grounded caller is multiplayer_transport_register_callback_table.,ghidra + rizin + llvm-objdump
0x00593d60,66,multiplayer_transport_try_submit_text_record_fastpath,shell,cdecl,inferred,ghidra-headless,3,Attempts the fast submission path for one prepared transport text record. It allocates a type-9 transient record through 0x005934e0 and when that succeeds forwards the caller callback and payload through 0x0058e510 with callback shim 0x00593d00. The current grounded caller is multiplayer_transport_submit_text_record.,ghidra + rizin + llvm-objdump
0x00598d50,496,multiplayer_transport_handle_registered_name_callback_bind_record_mode1,shell,cdecl,inferred,rizin,3,Owner-side wrapper for record mode 1 in the registered-name branch. It parses the mode prefix from the secondary key string at record field `+0x08` checks whether the primary name matches the local transport name at `[this+0x36c]` and either seeds one local registered-name entry through multiplayer_transport_upsert_registered_name_entry plus multiplayer_transport_set_registered_name_status_text or upserts one nested callback-entry record through multiplayer_transport_upsert_registered_name_callback_entry and emits follow-up opcode 6 or opcode 12 notifications when the target name entry is already marked dirty.,rizin + llvm-objdump
0x00598f40,255,multiplayer_transport_handle_registered_name_callback_remove_record_mode1,shell,cdecl,inferred,rizin,3,Owner-side removal wrapper for registered-name record mode 1. It resolves the primary and secondary key strings from the caller record removes the matching nested callback-entry through multiplayer_transport_remove_registered_name_callback_entry and then emits opcode 7 or opcode 12 notifications from the current registered-name owner callbacks when the target entry is dirty.,rizin + llvm-objdump
0x00599040,308,multiplayer_transport_handle_registered_name_callback_remove_record_mode23,shell,cdecl,inferred,rizin,3,Owner-side removal wrapper for registered-name record modes 2 and 3. It removes one nested callback-entry record by secondary key and then branches on whether the primary name matches the local transport name. The local-owner branch can emit opcode 5 and remove the whole registered-name entry through multiplayer_transport_remove_registered_name_entry while the remote branch emits opcode 7 subtype notifications through the installed owner callbacks.,rizin + llvm-objdump
0x00599180,160,multiplayer_transport_publish_registered_name_callback_remove_mode1,shell,cdecl,inferred,rizin,3,Small publish helper for registered-name callback-removal mode 1. It removes the named nested callback-entry and then emits the same owner callback notifications as the wider mode-1 removal path through opcode 7 and opcode 12 when the target entry is dirty and callback-enabled.,rizin + llvm-objdump
0x00599230,25,multiplayer_transport_dispatch_registered_name_callback_remove_mode1,shell,cdecl,inferred,rizin,3,Dispatch shim for registered-name callback-removal mode 1. When the input record kind equals 1 it forwards the primary name and one mode-1 removal helper descriptor into multiplayer_transport_dispatch_registered_name_callback_entry so the removal helper runs against each matching registered-name entry.,rizin + llvm-objdump
0x00599250,160,multiplayer_transport_publish_registered_name_callback_remove_mode3,shell,cdecl,inferred,rizin,3,Small publish helper for registered-name callback-removal mode 3. It removes the named nested callback-entry and emits the mode-3 owner callback notifications through opcode 7 and opcode 12 when the target registered-name entry is dirty and callback-enabled.,rizin + llvm-objdump
0x00599300,25,multiplayer_transport_dispatch_registered_name_callback_remove_mode3,shell,cdecl,inferred,rizin,3,Dispatch shim for registered-name callback-removal mode 3. When the input record kind equals 2 it forwards the primary name and one mode-3 removal helper descriptor into multiplayer_transport_dispatch_registered_name_callback_entry.,rizin + llvm-objdump
0x00599320,93,multiplayer_transport_handle_registered_name_display_text_record_mode2,shell,cdecl,inferred,rizin,4,Owner-side wrapper for registered-name display-text record mode 2. It copies the record string into the inline display buffer through multiplayer_transport_set_registered_name_display_text and when the target registered-name entry has an installed owner callback emits opcode 9 carrying the primary name and copied display text.,rizin + llvm-objdump
0x00599380,253,multiplayer_transport_apply_registered_name_update_bundle,shell,cdecl,inferred,rizin,4,Applies one parsed update bundle to an existing registered-name entry. It walks the decoded element list from 0x00598630 and uses the element tags to route updates into multiplayer_transport_update_registered_name_callback_flags multiplayer_transport_set_registered_name_status_text and the header read or write pair multiplayer_transport_try_read_registered_name_header_block plus multiplayer_transport_set_registered_name_header_block before releasing the decoded bundle object.,rizin + llvm-objdump
0x005997f0,177,multiplayer_transport_handle_registered_name_display_text_record_mode3,shell,cdecl,inferred,rizin,3,Owner-side wrapper for registered-name display-text record mode 3. It stores the supplied display text into the inline registered-name buffer and either resolves one pending template node through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node or falls back to emitting opcode 9 through the installed owner callback for the target registered-name entry.,rizin + llvm-objdump
0x005998b0,171,multiplayer_transport_handle_registered_name_display_text_clear_record,shell,cdecl,inferred,rizin,3,Owner-side wrapper for clearing registered-name display text. It builds a small mode-2 template with the shared empty string and either satisfies that request through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node or emits opcode 9 with the empty display text through the installed owner callback for the target registered-name entry.,rizin + llvm-objdump
0x00599960,144,multiplayer_transport_handle_pending_template_pair_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Structural mode-3 wrapper over the pending-template path. It builds one single-entry pending-template query from the pair of caller strings then resolves a matching node through multiplayer_transport_find_pending_template_node and dispatches it through multiplayer_transport_dispatch_pending_template_node. When no pending node exists it falls back to the transport-side callback at `[this+0x04]` through multiplayer_transport_dispatch_or_release_callback_binding.,llvm-objdump
0x005999f0,412,multiplayer_transport_handle_registered_name_callback_payload_record_mode8,shell,cdecl,inferred,rizin,3,Owner-side wrapper for registered-name record mode 8. It stages the supplied nested callback-entry payload blocks through multiplayer_transport_stage_registered_name_callback_payload_for_name and then walks the returned template nodes to emit higher-level follow-up notifications including opcode 0x16 and opcode 0x17 based on the decoded template kinds and the marker characters found in the staged payload text through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node.,rizin + llvm-objdump
0x00599c40,96,multiplayer_transport_copy_backslash_segment,shell,cdecl,inferred,llvm-objdump,4,Copies one backslash-delimited segment from the caller text into a freshly allocated heap string and writes the consumed byte count back through the out-parameter. Higher-level pending-template handlers reuse it to split multi-segment payloads before dispatch or callback fallback.,llvm-objdump
0x00599ca0,320,multiplayer_transport_handle_segment_list_template_record_mode4,shell,cdecl,inferred,llvm-objdump,3,Mode-4 pending-template wrapper for template kind 0x0c. It resolves one pending node through multiplayer_transport_find_pending_template_node splits the caller payload into a temporary heap string list with multiplayer_transport_copy_backslash_segment and then either dispatches that list through multiplayer_transport_dispatch_pending_template_node or falls back to emitting opcode 0x1e through the node-owned callback path before freeing the temporary segments.,llvm-objdump
0x00599de0,128,multiplayer_transport_handle_pair_template_record_mode4,shell,cdecl,inferred,llvm-objdump,3,Compact mode-4 pending-template wrapper for template kind 0x0c. After multiplayer_transport_find_pending_template_node succeeds it forwards two dword values from the matched node-owned payload block into one simple dispatch descriptor and completes the request through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x00599e60,768,multiplayer_transport_handle_segment_broadcast_template_record_mode5,shell,cdecl,inferred,llvm-objdump,3,Structural mode-5 pending-template wrapper over split payload broadcasting. One branch matches a fixed token and walks the registered-name owner callback list to emit opcode 0x1d once per backslash-delimited segment. The other branch resolves one template-kind 0x0d pending node builds a temporary split-string array with multiplayer_transport_copy_backslash_segment optionally appends node-owned paired strings and then either dispatches the finished descriptor through multiplayer_transport_dispatch_pending_template_node or falls back to opcode 0x1f through the node callback path.,llvm-objdump
0x0059a160,128,multiplayer_transport_handle_triplet_template_record_mode4,shell,cdecl,inferred,llvm-objdump,3,Compact mode-4 pending-template wrapper for template kind 0x0d. After multiplayer_transport_find_pending_template_node succeeds it forwards the caller primary string plus two dword fields from the matched node payload block through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059a1e0,1024,multiplayer_transport_handle_segment_pair_template_record_mode4,shell,cdecl,inferred,llvm-objdump,3,Structural mode-4 sibling of the split-payload template path for template kind 0x0e. One branch matches the fixed auxiliary token and emits opcode 0x1d once per backslash-delimited segment through the installed registered-name owner callbacks. The other branch resolves one pending node builds a temporary split-string array with multiplayer_transport_copy_backslash_segment appends paired node-owned strings and completes the request through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059a650,64,multiplayer_transport_mark_pending_template_kind1_ready,shell,cdecl,inferred,llvm-objdump,3,Small pending-template helper that looks up one kind-1 node through multiplayer_transport_find_pending_template_node and sets the first dword in its payload block to one when present.,llvm-objdump
0x0059a690,448,multiplayer_transport_stage_pending_template_triplet_record_mode4,shell,cdecl,inferred,llvm-objdump,3,Mode-4 helper for pending-template kind 1. It resolves one kind-1 node through multiplayer_transport_find_pending_template_node duplicates the caller strings plus one normalized helper string into heap storage emits opcode 0x0e through 0x0059b790 using the node-owned callback metadata and appends the three staged values into the node payload's parallel pointer arrays for later dispatch.,llvm-objdump
0x0059a850,112,multiplayer_transport_dispatch_pending_template_quintuple_helper,shell,cdecl,inferred,llvm-objdump,3,Small helper that resolves one kind-5 pending-template node through multiplayer_transport_find_pending_template_node and forwards the four dword payload fields stored at `[node+0x1c+0x04..0x10]` through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059a8c0,272,multiplayer_transport_handle_registered_name_update_bundle_record_mode3plus,shell,cdecl,inferred,llvm-objdump,3,Owner-side registered-name update handler for record kinds 3 and above. It decodes one update bundle through 0x00598630 and 0x00598860 tries the registered-name header read or write path through multiplayer_transport_try_read_registered_name_header_block plus multiplayer_transport_set_registered_name_header_block publishes opcode 0x0a when the target entry already has owner callbacks and then completes any waiting kind-5 pending-template node through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059a9d0,320,multiplayer_transport_handle_pending_template_triplet_record_mode6,shell,cdecl,inferred,llvm-objdump,3,Mode-6 pending-template wrapper that looks up either a kind-4 or kind-7 node through multiplayer_transport_find_pending_template_node. The kind-4 branch copies three caller strings into the node-owned payload slots while the kind-7 branch formats a derived string through 0x0059cbd0 and completes the request through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059ab10,256,multiplayer_transport_handle_token_list_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Mode-3 pending-template helper for kind 4. It parses the caller text into a token list with 0x005a3db9 trims leading `-` `@` and `+` markers duplicates each token into heap storage and appends the cleaned strings into the node-owned dynamic vector after multiplayer_transport_find_pending_template_node succeeds.,llvm-objdump
0x0059ac10,144,multiplayer_transport_dispatch_extended_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Mode-3 helper for kind-4 pending-template nodes. After multiplayer_transport_find_pending_template_node succeeds it builds one extended dispatch descriptor from the caller string a boolean derived from the first payload dword and the remaining four dwords stored in the node payload block then completes the request through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059aca0,176,multiplayer_transport_append_string_template_record_mode8,shell,cdecl,inferred,llvm-objdump,3,Helper for pending-template kind 8. It resolves one node through multiplayer_transport_find_pending_template_node grows the node-owned pointer vector through tracked_heap_resize_with_header duplicates the caller string and appends that heap string to the vector.,llvm-objdump
0x0059ad50,112,multiplayer_transport_dispatch_string_vector_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Mode-3 dispatch helper for pending-template kind 8. It resolves one node through multiplayer_transport_find_pending_template_node then forwards the caller key together with the node-owned string-count and string-vector pointers through multiplayer_transport_dispatch_pending_template_node.,llvm-objdump
0x0059adc0,96,multiplayer_transport_handle_local_name_record_mode2,shell,cdecl,inferred,llvm-objdump,4,Mode-2 transport-state setter for the local name buffer at `[this+0x36c]`. It copies the caller string into that fixed buffer clears state dword `[this+0x04]` sets active flag `[this+0x00]` and when the transport owner callback at `[this+0x14]` is installed invokes it with mode `1` and the owner cookie at `[this+0x18]`.,llvm-objdump
0x0059ae20,176,multiplayer_transport_handle_transport_text_pair_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Mode-3 transport-state setter for a pair of fixed text buffers. It copies the caller strings into the fixed buffers at `[this+0x564]` and `[this+0x140]` updates the associated length or dirty fields through helpers 0x005a1050 and 0x005a0d00 marks `[this+0x13c]` active and refreshes the transport-side status line rooted at `[this+0x1c]` through 0x0059caf0.,llvm-objdump
0x0059aed0,112,multiplayer_transport_handle_normalized_pair_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Mode-3 wrapper that normalizes the secondary caller string through 0x005a1ea5 then resolves one kind-0x10 pending-template node through multiplayer_transport_find_pending_template_node and completes it through multiplayer_transport_dispatch_pending_template_node with the normalized value plus the original secondary string.,llvm-objdump
0x00597920,56,multiplayer_transport_find_pending_template_kind0c_by_key,shell,cdecl,inferred,llvm-objdump,4,Searches the linked pending-template list rooted at `[this+0x550]` for the first kind-0x0c node whose payload string at `[node+0x1c+0x08]` exactly matches the caller key. It returns the matched node or null.,llvm-objdump
0x0059af40,186,multiplayer_transport_dispatch_fallback_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Mode-3 fallback wrapper over the pending-template path. It first queries for either a kind-1 or kind-5 node keyed by the caller string through multiplayer_transport_find_pending_template_node and dispatches the matching node through multiplayer_transport_dispatch_pending_template_node with a minimal descriptor. When neither node exists it falls back to multiplayer_transport_find_pending_template_kind0c_by_key and completes that node with an empty descriptor instead.,llvm-objdump
0x0059b000,103,multiplayer_transport_dispatch_kind1_string_template_record_mode6,shell,cdecl,inferred,llvm-objdump,3,Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `6` and the original string payload.,llvm-objdump
0x0059b070,103,multiplayer_transport_dispatch_kind1_string_template_record_mode2,shell,cdecl,inferred,llvm-objdump,3,Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `2` and the original string payload.,llvm-objdump
0x0059b0e0,103,multiplayer_transport_dispatch_kind1_string_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `3` and the original string payload.,llvm-objdump
0x0059b150,103,multiplayer_transport_dispatch_kind1_string_template_record_mode4,shell,cdecl,inferred,llvm-objdump,3,Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `4` and the original string payload.,llvm-objdump
0x0059b1c0,103,multiplayer_transport_dispatch_kind1_string_template_record_mode5,shell,cdecl,inferred,llvm-objdump,3,Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `5` and the original string payload.,llvm-objdump
0x0059b230,103,multiplayer_transport_dispatch_kind1_string_template_record_mode8,shell,cdecl,inferred,llvm-objdump,3,Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `8` and the original string payload.,llvm-objdump
0x0059b2a0,1,multiplayer_transport_noop_cleanup_callback,shell,cdecl,inferred,llvm-objdump,2,Trivial no-op cleanup callback that returns immediately. Current grounded role is as a placeholder callback target in the transport cleanup layer.,llvm-objdump
0x0059b2b0,17,multiplayer_transport_release_optional_callback_binding,shell,cdecl,inferred,llvm-objdump,2,Small cleanup helper that checks the optional callback binding stored at `[this+0x04]` and when present forwards it into multiplayer_transport_dispatch_or_release_callback_binding with mode `1`.,llvm-objdump
0x0059b2d0,8,multiplayer_transport_free_template_entry_owner_string,shell,cdecl,inferred,llvm-objdump,3,Small element cleanup helper that releases the owner string pointer stored at `[entry+0x14]` through tracked_heap_free_with_header. The companion pending-template container uses it as the per-element cleanup callback when destroying its flat vector.,llvm-objdump
0x0059b2e0,1239,multiplayer_transport_destroy_pending_template_dispatch_record,shell,cdecl,inferred,llvm-objdump,3,Type-switched destructor for one pending-template dispatch record. It reads the record kind at `[record+0x00]` and frees the owned payload graph under `[record+0x08]` through tracked_heap_free_with_header including nested string arrays and paired pointer vectors for the more complex template kinds before finally releasing the top-level payload block itself.,llvm-objdump
0x0059b710,40,multiplayer_transport_init_pending_template_dispatch_store,shell,thiscall,inferred,llvm-objdump,3,Initializes the companion flat pending-template dispatch store at `[this+0x55c]` by allocating a stride-0x18 contiguous vector through 0x0059e0b0 and installing multiplayer_transport_free_template_entry_owner_string as the per-element cleanup callback. Returns true on success.,llvm-objdump
0x0059b740,74,multiplayer_transport_destroy_pending_template_dispatch_store,shell,thiscall,inferred,llvm-objdump,3,Destroys the companion flat pending-template dispatch store at `[this+0x55c]`. It walks every live element through multiplayer_transport_destroy_pending_template_dispatch_record and then releases the backing vector through generic_vector_destroy.,llvm-objdump
0x0059c220,458,multiplayer_transport_dispatch_pending_template_dispatch_record,shell,unknown,inferred,rizin,3,Switch-driven dispatcher for one flat pending-template dispatch-store record after the store manager has removed it from the vector. It reads the record kind at `[record+0x00]` invokes the record-owned callback at `[record+0x04]` with a payload tuple rooted at `[record+0x08]` and the owner string or selector at `[record+0x0c]` and then destroys the record through multiplayer_transport_destroy_pending_template_dispatch_record. Case `16` also resolves the registered-name dirty flag through 0x0059d9c0 before invoking the callback.,rizin + llvm-objdump
0x0059c470,203,multiplayer_transport_service_pending_template_dispatch_store,shell,unknown,inferred,rizin,3,"Services the flat pending-template dispatch store at `[this+0x55c]`. It walks every live 0x18-byte entry; entries whose owner string at `[entry+0x14]` no longer resolves through multiplayer_transport_has_registered_name are destroyed and erased immediately, while surviving entries are dispatched only when their registered-name dirty flag is nonzero and the optional filter value in EDX is zero or matches `[entry+0x10]`. Dispatching copies the 0x18-byte record to stack storage, erases the vector slot, and forwards the copied record into multiplayer_transport_dispatch_pending_template_dispatch_record.",rizin + llvm-objdump
0x0059c540,70,multiplayer_transport_find_pending_template_dispatch_record_index,shell,unknown,inferred,rizin,4,Searches the flat pending-template dispatch store at `[this+0x55c]` for the first record whose selector or request field at `[entry+0x10]` matches the caller key. It returns the zero-based vector index on success or `-1` when no record matches.,rizin + llvm-objdump
0x0059c590,21,multiplayer_transport_has_pending_template_dispatch_record,shell,unknown,inferred,rizin,4,Boolean wrapper over multiplayer_transport_find_pending_template_dispatch_record_index. It returns true when the flat pending-template dispatch store currently contains one record for the caller key and false otherwise.,rizin + llvm-objdump
0x0059c5b0,40,growable_text_buffer_init,support,unknown,inferred,rizin,3,"Initializes one heap-backed growable text buffer structure. It clears the used-length field at `[buf+0x04]`, seeds the initial capacity at `[buf+0x08]` to `0x2000`, allocates a `0x2001`-byte NUL-terminated backing block through tracked_heap_alloc_with_header, stores that pointer at `[buf+0x00]`, and returns true on success.",rizin + llvm-objdump
0x0059c5e0,3,growable_text_buffer_free,support,unknown,inferred,rizin,4,Small wrapper that frees the heap-backed buffer pointer stored at `[buf+0x00]` through tracked_heap_free_with_header.,rizin + llvm-objdump
0x0059c5f0,65,growable_text_buffer_reserve_append,support,unknown,inferred,rizin,4,Ensures that one growable text buffer has room to append the requested byte count in ECX while preserving a trailing NUL terminator. When `[buf+0x04] + requested` would exceed capacity `[buf+0x08]` it rounds the new capacity up in 0x2000-byte chunks resizes the backing block through tracked_heap_resize_with_header stores the new pointer at `[buf+0x00]` and updates `[buf+0x08]` before returning success or failure.,rizin + llvm-objdump
0x0059c670,76,multiplayer_transport_text_stream_init,shell,thiscall,inferred,rizin,3,Initializes one multiplayer transport text-stream object. It zeroes the 0x350-byte state block seeds socket `[this+0x00]` to `-1` and allocates two growable text buffers at `[this+0x108]` and `[this+0x114]` through growable_text_buffer_init. Failure to allocate the second buffer frees the first and returns false.,rizin + llvm-objdump
0x0059c790,194,multiplayer_transport_text_stream_destroy,shell,thiscall,inferred,rizin,4,"Destroys one multiplayer transport text-stream object. If socket `[this+0x00]` is live it shuts it down with `shutdown(..., 2)` and `closesocket`, marks state `[this+0x04]` as closed, frees the two growable text buffers at `[this+0x108]` and `[this+0x114]`, releases the fixed pointer fields at `[this+0x328]` through `[this+0x344]`, then walks and frees the pointer vector rooted at `[this+0x348]` before freeing that vector itself.",rizin + llvm-objdump
0x0059c860,300,multiplayer_transport_select_socket_ready_flags,shell,cdecl,inferred,rizin,4,"Small `select` wrapper for one transport socket. It takes the socket on the stack plus up to three optional out-pointers for read write and exception readiness, builds the requested `fd_set` structures on the stack, calls `select(0x40, ...)` with a null timeout, and stores `1` or `0` into each requested out-slot depending on whether `__WSAFDIsSet` reports that socket as ready.",rizin + llvm-objdump
0x0059c990,113,multiplayer_transport_text_stream_send_pump,shell,thiscall,inferred,rizin,4,"Attempts to flush queued bytes from the transport text-stream send buffer at `[this+0x114]`. While buffered length `[this+0x118]` remains nonzero it probes writability through multiplayer_transport_select_socket_ready_flags, sends up to `min(len, 0x400)` bytes with `send`, slides any remaining buffered bytes down through `0x0059c640`, and continues until the socket is no longer writable or the buffer is empty.",rizin + llvm-objdump
0x0059ca10,190,multiplayer_transport_text_stream_recv_pump,shell,thiscall,inferred,rizin,3,Receives available socket text into the transport text-stream receive buffer at `[this+0x108]`. It first probes readability through multiplayer_transport_select_socket_ready_flags then repeatedly reserves 0x1000 bytes through growable_text_buffer_reserve_append calls `recv` into the free tail of the buffer optionally applies the stream-cipher helper at 0x005a0f70 when `[this+0x120]` is armed advances the used-length field at `[this+0x10c]` NUL-terminates the buffer and loops while readability remains set. Socket errors store closed-state value `2` into `[this+0x04]`.,rizin + llvm-objdump
0x0059cad0,25,multiplayer_transport_text_stream_service_io,shell,thiscall,inferred,rizin,4,Services one multiplayer transport text-stream I/O step unless state `[this+0x04]` is already closed. It first flushes queued outbound bytes through multiplayer_transport_text_stream_send_pump and then pumps inbound socket text through multiplayer_transport_text_stream_recv_pump.,rizin + llvm-objdump
0x0059caf0,216,multiplayer_transport_text_stream_append_crlf_line,shell,thiscall,inferred,rizin,4,"Appends one caller text line plus `\\r\\n` to the transport text-stream send buffer at `[this+0x114]`. It ignores requests when state `[this+0x04]` is already closed, reserves `strlen(text) + 2` bytes through growable_text_buffer_reserve_append, copies the bytes into the current tail tracked by `[this+0x118]`, appends CRLF, and updates the used-length field. When the stream-cipher gate at `[this+0x120]` is armed it post-processes the newly appended span through 0x005a0f70 using the send-side cipher state rooted at `[this+0x226]`.",rizin + llvm-objdump
0x00597880,159,multiplayer_transport_find_pending_template_node,shell,cdecl,inferred,rizin,4,Searches the linked pending-template list rooted at `[this+0x550]` for the first node whose caller-provided query tuple array matches the node kind and its primary and secondary string selectors. When it finds a match it refreshes the node timeout field at `[node+0x04]` from GetTickCount plus 0xea60 and returns that node pointer otherwise it returns null.,rizin + llvm-objdump
0x005979d0,1164,multiplayer_transport_dispatch_pending_template_node,shell,cdecl,inferred,rizin,3,Consumes one pending-template node and one caller dispatch descriptor. Depending on the node kind it emits one or more transport notifications through 0x0059b790 using the node-owned strings arrays and callback state then releases the node-owned heap strings arrays and child lists before unlinking the node from the pending-template list. Higher-level registered-name wrappers reuse it as the common completion path after multiplayer_transport_find_pending_template_node succeeds.,rizin + llvm-objdump
0x005996c0,304,multiplayer_transport_handle_pending_template_record_mode3,shell,cdecl,inferred,llvm-objdump,3,Structural mode-3 wrapper over the pending-template path for registered-name updates. It normalizes the caller selector string against the shared default token at 0x005e1e1c builds a four-way pending-template query and dispatches the matched node through multiplayer_transport_dispatch_pending_template_node. Depending on the matched node kind it can mark the registered-name entry dirty through multiplayer_transport_mark_registered_name_dirty or forward the node-owned payload fields into the dispatch descriptor.,llvm-objdump
0x00565c90,208,shell_queue_indexed_world_anchor_marker,shell,cdecl,inferred,ghidra-headless,3,Variant world-anchor marker emitter that selects one indexed entry from the owner table at +0x24 using byte [this+0xd8] derives scale and packed color from the entry fields and enqueues the resulting type-0x01 deferred message through shell_enqueue_deferred_message_type1.,ghidra + rizin + llvm-objdump
0x005662a0,964,shell_emit_sprite_billboard_quad_vertex24,bootstrap,thiscall,inferred,ghidra-headless,4,Expands one sprite billboard into six vertex24 records forming two textured triangles. It derives an alpha byte from item timing flags at [this+0x48] [this+0x4c] and [this+0x5c] combines that alpha with packed color [this+0x70] scales a prepared four-corner basis by [this+0x44] and writes six 24-byte vertices using atlas uv pairs from [this+0x2c..0x38].,ghidra + rizin + llvm-objdump
0x00566670,84,shell_prepare_sprite_billboard_basis,bootstrap,thiscall,inferred,ghidra-headless,3,Builds the temporary four-corner sprite-billboard basis used by 0x005662a0 from the current shell transform state and writes the result into global scratch vectors around 0x00d97ae0 and 0x00d97b98.,ghidra + rizin + llvm-objdump
0x0055e2b0,179,shell_create_layout_state,bootstrap,thiscall,inferred,ghidra-headless,4,Allocates a 0x3715-byte layout-state object for the shell controller stores it at [this+0x2d] seeds the dirty flags invokes 0x0054bc10 with owner state and a template byte from the shell bundle then binds the first presentation asset bundle through 0x00543f10 before later update hooks run.,ghidra + rizin
0x005679b0,569,shell_emit_animated_quad_vertex24,bootstrap,thiscall,inferred,ghidra-headless,4,Expands one cell-list item into four `vertex24` corner records with a time-varying color phase. The helper derives an 8-step brightness cycle from GetTickCount plus item field [this+0x3a] combines that phase with per-corner bytes at +0x35 through +0x38 and mask bytes at +0x31 through +0x34 and writes four 24-byte vertices from the quad corner positions stored across +0x00..+0x2c.,ghidra + rizin + llvm-objdump
0x00567c70,103,shell_stream_primary_cell_quad_list,bootstrap,thiscall,inferred,ghidra-headless,4,Streams the primary quad-item list rooted at [this+0x1c] into the caller's `vertex24` buffer. It seeds the shared color input through 0x00d97bbc iterates each list entry through 0x005679b0 and advances the destination pointer by count*0x90 for four vertices per item.,ghidra + rizin + llvm-objdump
0x00567ce0,105,shell_stream_alternate_cell_quad_list,bootstrap,thiscall,inferred,ghidra-headless,4,Streams the alternate quad-item list rooted at [this+0x20] into the caller's `vertex24` buffer using the same quad writer at 0x005679b0. Unlike the primary path it forwards an extra caller-supplied selector value into each emitted quad before advancing the destination pointer by count*0x90.,ghidra + rizin + llvm-objdump
0x005a644d,81,__heap_init,startup,cdecl,inferred,ghidra-headless,4,Initializes the CRT heap path via ___heap_select and ___sbh_heap_init before later allocations occur.,ghidra + rizin
0x005abd49,111,startup_init_tls_state,startup,unknown,inferred,ghidra-headless,3,Initializes per-thread startup state: mt locks plus TLS slot allocation and current-thread bookkeeping.,ghidra + rizin
0x005abf1b,510,startup_init_file_handle_table,startup,cdecl,inferred,ghidra-headless,4,Allocates and seeds the CRT file descriptor table then consumes STARTUPINFO handles and classifies inherited std handles.,ghidra + rizin
0x005aca5d,61,startup_run_init_callback_table,startup,unknown,inferred,ghidra-headless,3,Walks a startup callback table and invokes non-null entries before continuing the CRT path.,ghidra + rizin
0x005ad12d,199,__setenvp,startup,cdecl,inferred,ghidra-headless,4,Builds the process envp array by counting environment strings and splitting name/value entries around '='.,ghidra + rizin
0x005ad360,162,startup_build_argv,startup,cdecl,inferred,ghidra-headless,3,Initializes the multibyte table and uses a two-pass helper to count and copy argv entries from the process command line.,ghidra + rizin
0x005ad402,290,___crtGetEnvironmentStringsA,startup,cdecl,inferred,ghidra-headless,4,Copies the Windows environment block into CRT-owned storage before envp construction.,ghidra + rizin
1 address size name subsystem calling_convention prototype_status source_tool confidence notes verified_against
2 0x00444dd0 3301 map_bundle_open_reference_databases map cdecl inferred ghidra-headless 3 Opens and registers a broad reference-database bundle for the active map path. The routine formats %1\\%2 paths allocates bundle state through 0x00530c80 and wires many global datasets including gpdLabelDB gpdCityDB and related city geographic and map reference tables before later shell and map loaders continue. ghidra + rizin + llvm-objdump + strings
3 0x00456920 3247 unit_visual_init_weapon_airframe_and_exhaust_effects bootstrap thiscall inferred ghidra-headless 4 Initializes one armed-unit visual bundle spanning turret and cannon hardware exhaust emitters and aircraft airframe attachments. The routine creates static Turret Mantlet Cannon and MuzzleFlash assets at [this+0x31a] through [this+0x326] direct JetExhaust and PropExhaust sprite emitters at [this+0x2f6] and [this+0x2fa] a cannon-audio attachment at [this+0x32a] indexed WingL and WingR assets plus plane-audio state at [this+0x32e] through [this+0x346] and cached Aileron Elevator Rudder and Thrust vectors at [this+0x2d1] [this+0x2c5] [this+0x2b9] and [this+0x2dd]. ghidra + rizin + llvm-objdump + strings
4 0x00461650 120 map_load_geographic_label_database map cdecl inferred ghidra-headless 3 Loads the geographic-label database branch inside the broader reference-bundle setup. It stages resource ids 0x5209 through 0x520b binds the selected bundle through 0x517d90 iterates the loaded collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44 using the current map path context. ghidra + rizin + llvm-objdump + strings
5 0x00464410 12679 shell_dispatch_ui_command shell cdecl inferred ghidra-headless 4 Large shell UI command dispatcher reached from shell-side event callbacks and direct command pushes. It switches over many command ids including 0x7530 through 0x7532 graphics-preset commands that route into 0x0051ebc0 0x00484590 and 0x004853c0; 0x7533 through 0x7534 TigerTank viewer actions; and 0x7540 through 0x7543 scenario-text report build and batch-processing commands that route into 0x00489830 0x004886e0 and 0x00489a20. ghidra + rizin + llvm-objdump + strings
6 0x00474610 120 map_load_city_database map cdecl inferred ghidra-headless 3 Loads the city database branch in the same pattern as the geographic-label loader. It stages resource ids 0x61a9 through 0x61ab binds the selected bundle through 0x517d90 iterates the collection with 0x517cf0 0x518380 and 0x518140 and dispatches each record through vtable slot +0x44. ghidra + rizin + llvm-objdump + strings
7 0x00474e20 336 effect_slot_create_attached_sprite_emitter bootstrap thiscall inferred ghidra-headless 3 Creates or clones one attached sprite emitter for an effect slot on the owning object. Depending on flag bit 0x400 it either clones through 0x00556ce0 or allocates a fresh 0x1fd template through 0x00556920 then attaches the emitter to the owner at [emitter+0x60] and optionally sets persistent flag [emitter+0xbc]. ghidra + rizin + llvm-objdump
8 0x00474f70 97 effect_slot_update_attached_sprite_emitters bootstrap thiscall inferred ghidra-headless 3 Advances every sprite emitter stored in one effect-slot container by iterating its pointer list and calling 0x00555e50 with update mode zero. When the caller passes null it instead walks the global linked slot list rooted at 0x006cea74. ghidra + rizin + llvm-objdump
9 0x00478200 291 shell_queue_single_world_anchor_overlay shell cdecl inferred ghidra-headless 3 Builds one world-anchor overlay packet for the current owner object. It samples the owner transform through 0x00455800 and 0x00455810 derives projected half-height and half-width through 0x00477a10 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and then enqueues the finished marker through shell_queue_world_anchor_marker. ghidra + rizin + llvm-objdump
10 0x00478330 2432 shell_queue_world_anchor_overlay_list shell cdecl inferred ghidra-headless 3 Builds and queues a repeated world-anchor overlay list for one owner-managed collection. The routine iterates several owner sublists and state branches repeatedly derives projected extents through 0x00477a10 0x004779c0 world_anchor_measure_projected_half_height and world_anchor_measure_projected_half_width and emits one shell_queue_world_anchor_marker packet per accepted overlay entry. ghidra + rizin + llvm-objdump
11 0x00485750 14 shell_has_tiger_tank_viewer shell cdecl inferred ghidra-headless 4 Returns whether the dedicated TigerTank shell viewer object at 0x006cfc8c is currently active. The 0x7533 open and 0x7534 close commands both gate on this global before showing status text or mutating viewer state. ghidra + rizin + llvm-objdump + strings
12 0x004840e0 863 bootstrap_init_shell_window_services bootstrap cdecl inferred ghidra-headless 4 Consumes the early bootstrap object then allocates the shell service bundle rooted at 0x006d4024 seeds a 640x480 fallback and drives the main window focus path before later startup continues. ghidra + rizin
13 0x00484440 323 app_bootstrap_main bootstrap cdecl inferred ghidra-headless 4 Primary post-CRT bootstrap coordinator; initializes COM and branding strings then probes host state and hands off into the main application bootstrap chain. ghidra + rizin
14 0x00484590 887 shell_init_graphics_preset_state shell cdecl inferred ghidra-headless 3 Initializes the shell graphics-preset state block rooted at [this+0x70]. It clears a large option buffer seeds many default fields and applies one of three coarse mode layouts from its integer argument before later preset application or config-save helpers continue. ghidra + rizin + llvm-objdump
15 0x00484910 105 shell_save_graphics_config shell cdecl inferred ghidra-headless 4 Persistently writes the current shell graphics configuration to data\\configuration\\game.cfg. It optionally syncs the global display runtime through 0x0051eea0 then writes config keys 0x429 and 0x48d from the shell state block before closing the file. ghidra + rizin + llvm-objdump + strings
16 0x00484980 212 shell_load_graphics_config_or_init_defaults shell cdecl inferred ghidra-headless 4 Loads the shell graphics configuration from data\\configuration\\game.cfg during early shell setup. It optionally pulls the larger display-runtime blob through 0x0051ef20 validates key 0x429 reads key 0x48d into the shell state block at [this+0x70] and falls back to 0x00484590 plus 0x00484910 when the file is missing or invalid. ghidra + rizin + llvm-objdump + strings
17 0x00484a60 125 shell_match_legacy_gpu_profile_token shell cdecl inferred ghidra-headless 4 Collects the current display-adapter descriptor string then scans the legacy GPU-profile table at 0x0062142c for the first matching token. The table contains vendor and chipset strings such as geforce radeon Voodoo matrox i810 sis savage and 3dfx; the returned index or -1 then drives the preset-tier tables in 0x004853c0. ghidra + rizin + llvm-objdump + strings
18 0x00484d70 700 shell_apply_graphics_option_runtime_effects shell thiscall inferred ghidra-headless 3 Walks the pending graphics-option array rooted at [this+0x1c] and applies runtime side effects for the dirty entries selected by the caller mask. The cases fan into the active engine object at 0x0062c120 and shell globals under 0x006d4024 and 0x006d4030 updating several float scaled thresholds integer quality values and display capability bytes before clearing the dirty array and notifying the active shell object at 0x0062be68. ghidra + rizin + llvm-objdump
19 0x004852e0 210 shell_apply_default_graphics_master_profile shell thiscall inferred ghidra-headless 4 Reads the default master graphics profile value from 0x006211dc currently 6 and broadcasts it across option ids 1 through 16 in the shell settings block. Special option ids 10 11 12 and 13 are remapped through the preset tables at 0x00621250 through 0x00621358 before the function refreshes runtime side effects through 0x00484d70 updates shell display-profile flags under 0x006d4024 and persists game.cfg through 0x00484910. ghidra + rizin + llvm-objdump
20 0x004853c0 740 shell_apply_graphics_preset_bundle shell cdecl inferred ghidra-headless 4 Applies one table-driven graphics preset bundle to the shell settings object. It derives a preset tier from shell state and runtime capability probes then writes per-setting values through repeated 0x00485060 calls refreshes dependent runtime state through 0x00484d70 optionally saves game.cfg through 0x00484910 and updates several display capability flags under 0x006d4024. ghidra + rizin + llvm-objdump
21 0x00485060 635 shell_set_graphics_option_with_fanout shell thiscall inferred ghidra-headless 4 Writes one graphics option value into the shell settings arrays at [this+0xac] and coordinates grouped fanout updates. Primary preset selectors recursively expand into dependent option ids 1 through 16 using preset remap tables at 0x00621250 through 0x00621358. The function compares the new normalized value against the previous setting invokes 0x00484d70 when a runtime refresh is needed and persists game.cfg through 0x00484910 once the update batch completes. ghidra + rizin + llvm-objdump
22 0x00485760 2746 vehicle_visual_init_running_gear_and_smoke_effects bootstrap thiscall inferred ghidra-headless 4 Builds a larger vehicle visual bundle covering running-gear assets smoke effects and attachment-audio objects. The routine fills indexed road-wheel visual arrays from RoadWheelR and RoadWheelL asset strings creates direct MuzzleSmoke and ExhaustSmoke sprite emitters at [this+0x216] and [this+0x21a] and then creates five fixed attachment objects at [this+0x3cc] through [this+0x3dc] for diesel1 tracks german88 turret and mantlet audio assets before registering them on the owner. ghidra + rizin + llvm-objdump + strings
23 0x004883f0 325 scenario_text_export_append_numbered_entry scenario cdecl inferred ghidra-headless 4 Formats and appends one numbered translation entry into the scenario-text export buffer. It duplicates the source text applies the export wrapper template through helper formatters and appends the finished block through 0x531030 while updating the running non-comment word count at 0x006cfca0. ghidra + rizin + llvm-objdump + strings
24 0x004886e0 3796 scenario_text_export_build_language_file scenario cdecl inferred ghidra-headless 4 Builds one MAPS\\%s.lng scenario-text export for the active map and returns the non-comment word count. It writes translator guidance and section headers then walks map briefing territory city geographic-label station company and event collections appending numbered entries through 0x004883f0 before finalizing the output buffer. ghidra + rizin + llvm-objdump + strings
25 0x00487450 153 shell_open_tiger_tank_viewer shell cdecl inferred ghidra-headless 3 Allocates and shows the dedicated TigerTank shell viewer object when no viewer is active. It samples shell-owned placement data allocates a 0x434-byte object initializes it through 0x00485760 with the TigerTank title and stores the resulting viewer pointer in 0x006cfc8c. ghidra + rizin + llvm-objdump + strings
26 0x004874f0 70 shell_close_tiger_tank_viewer shell cdecl inferred ghidra-headless 4 Closes and frees the dedicated TigerTank shell viewer rooted at 0x006cfc8c. It detaches the viewer if currently selected in the shell owner at 0x0062be68 destroys its internal resources through 0x00530680 frees the object and clears the global viewer slot. ghidra + rizin + llvm-objdump + strings
27 0x00489830 496 scenario_text_export_report_language_file scenario cdecl inferred ghidra-headless 3 Opens one existing MAPS\\%s.lng file for the selected map and reports on its parsed contents without rebuilding it. The routine loads the file into memory iterates numbered entries through 0x00488540 formats summary strings through 0x004895c0 and presents success or failure dialogs when interactive mode is enabled. ghidra + rizin + llvm-objdump + strings
28 0x00489a20 1085 scenario_text_export_batch_process_maps scenario cdecl inferred ghidra-headless 4 Enumerates maps\\*.gmp and batch-processes every scenario through the scenario-text export branch. Command 0x7542 runs the build path through 0x004886e0 while command 0x7543 runs the report path through 0x00489830; the wrapper tracks progress formats per-map status strings and emits a final summary dialog. ghidra + rizin + llvm-objdump + strings
29 0x00468d00 222 multiplayer_update_semicolon_name_list shell cdecl inferred ghidra-headless 4 Adds or removes one player-name token in the semicolon-delimited moderation list rooted at `[ecx+0x905c]`. With mode `1` it appends the supplied token only when not already present writing `;` as the delimiter; with mode `0` it removes the matched token collapses the remainder left and skips an adjacent delimiter when present. ghidra + rizin + llvm-objdump + strings
30 0x00468de0 14 multiplayer_session_event_forward_action1_request shell unknown inferred ghidra-headless 2 Session-event callback wrapper that always forwards request id `1` through multiplayer_set_pending_session_substate with a zero auxiliary payload. The callback clears EDX before the shared setter call and currently lands on a request id that does not yet map to a visible pending substate so this row remains structural. ghidra + rizin + llvm-objdump
31 0x00468e00 188 multiplayer_session_event_publish_pair_chat_template shell unknown inferred ghidra-headless 3 Session-event callback that formats one two-string chat/status line through multiplayer_route_chat_line when the callback status in EDX is zero and the current live session count is not positive. A selector near `[esp+0x214]` chooses the template `%s* %s` `%s %s` or `%s > %s`; the helper length-checks both inputs against the local 0x1f4-byte buffer before formatting and returns without publishing when either string is null or too long. ghidra + rizin + llvm-objdump + strings
32 0x00468ec0 144 multiplayer_session_event_publish_action2_single_name shell unknown inferred ghidra-headless 3 Session-event callback wrapper for the one-name action-2 status path. When the callback status in EDX is zero and the current session count is positive it length-checks the supplied name formats localized text id `0xb73` routes the resulting line through multiplayer_route_chat_line and then forwards request id `2` through multiplayer_set_pending_session_substate with that same name payload. The currently grounded setter does not visibly store a pending substate for id `2` so this row stays partly structural. ghidra + rizin + llvm-objdump
33 0x00468f50 192 multiplayer_session_event_publish_action2_pair shell unknown inferred ghidra-headless 3 Session-event callback wrapper for the two-string action-2 status path. When the callback status in EDX is zero and the supplied name lengths fit within the local buffer it formats localized text id `0xb74` or `0xe34` depending on whether the first string is present routes the resulting line through multiplayer_route_chat_line and then forwards request id `2` through multiplayer_set_pending_session_substate with the second string as the target payload and the first string as the auxiliary payload. The currently grounded setter does not visibly store a pending substate for id `2` so this row stays partly structural. ghidra + rizin + llvm-objdump
34 0x00469010 30 multiplayer_session_event_forward_action4_request shell unknown inferred ghidra-headless 3 Session-event callback wrapper that forwards request id `4` only when both supplied payload pointers are non-null. It passes the second stack argument as the action payload and a zero auxiliary argument through multiplayer_set_pending_session_substate. The currently grounded setter does not visibly store a pending substate for id `4` so this row remains structural. ghidra + rizin + llvm-objdump
35 0x00469030 30 multiplayer_session_event_forward_action7_request shell unknown inferred ghidra-headless 2 Session-event callback wrapper that forwards one payload pointer through multiplayer_set_pending_session_substate with request id `7` when the callback status in EDX is nonzero. The wrapper normalizes its incoming pointer into the second stack slot before tail-calling the shared setter but the currently grounded setter does not map request id `7` to a visible pending substate so this row remains structural. ghidra + rizin + llvm-objdump
36 0x00469060 3 multiplayer_session_event_noop_12byte_stub shell unknown inferred ghidra-headless 4 Three-byte no-op callback stub in the Multiplayer.win session-event registration table. It returns immediately with `ret 0xc` and does not touch any state. ghidra + rizin + llvm-objdump
37 0x00469070 87 multiplayer_session_event_publish_status_value shell unknown inferred ghidra-headless 3 Session-event callback that publishes one status value into the destination text builder passed in the third stack argument. It first compares the supplied index against the live session count from `0x006d40d0`; out-of-range entries publish the fixed fallback text at `0x005c87a8`; in-range entries publish integer `100` through 0x0058cd40 when event code EDX is `0x18`; publish the string at `0x00521d40+0x08` when EDX is `0x15`; and otherwise fall back to the same fixed text token. ghidra + rizin + llvm-objdump + strings
38 0x004690d0 15 multiplayer_session_event_publish_fixed_status_text shell unknown inferred ghidra-headless 3 Session-event callback that appends the fixed status text token at `0x005c87a8` into the destination text builder passed in the second stack argument. This is the smallest text-publisher sibling in the same callback family and shares the same append helper 0x0058bce0 used by 0x00469070. ghidra + rizin + llvm-objdump
39 0x004690f0 106 multiplayer_session_event_seed_control_id_list shell unknown inferred ghidra-headless 3 Session-event callback that seeds a byte-list builder with the fixed control-id set `3 1 8 10 11 19 4 5` when the callback status in EDX is zero. It appends each id through 0x0058bcb0 into the destination builder passed in the first stack argument and returns immediately when the callback status is nonzero. ghidra + rizin + llvm-objdump
40 0x00469160 26 multiplayer_session_event_query_session_count shell unknown inferred ghidra-headless 4 Session-event callback helper that returns the live session count from `0x006d40d0` through 0x00521670 only when the callback mode in EDX equals `1`; all other modes return zero. This looks like the count-query slot in the same registration table. ghidra + rizin + llvm-objdump
41 0x00469180 3 multiplayer_session_event_noop_8byte_stub shell unknown inferred ghidra-headless 4 Three-byte no-op callback stub in the Multiplayer.win session-event registration table. It returns immediately with `ret 8` and does not touch any state. ghidra + rizin + llvm-objdump
42 0x00469190 8 multiplayer_session_event_latch_status_code shell unknown inferred ghidra-headless 4 Small session-event callback helper that stores the incoming status code from EDX into `0x006cd974` and returns. The registration branch later clears the same global before transport teardown or retry reset. ghidra + rizin + llvm-objdump
43 0x004691a0 45 multiplayer_session_event_notify_owner_and_queue_action8 shell unknown inferred ghidra-headless 3 Session-event callback wrapper that first notifies the current Multiplayer.win owner through multiplayer_notify_window_owner. When the callback status in EDX is zero it then queues request id `8` through multiplayer_set_pending_session_substate with the same payload pointer; otherwise it returns after the owner notification only. ghidra + rizin + llvm-objdump
44 0x004691d0 39 multiplayer_find_session_event_capacity_entry shell unknown inferred ghidra-headless 4 Scans the fixed 0x80-entry session-event capacity array for a live record owned by the supplied key pointer in EDX. Each 0x11c-byte record is live when [entry+0x104] is nonzero and a match requires [entry+0x10c] to equal the incoming key. The helper returns the matched entry pointer or null. ghidra + rizin + llvm-objdump
45 0x00469200 428 multiplayer_sync_session_event_capacity_entry shell unknown inferred ghidra-headless 3 Session-event cache-field callback that creates updates or clears one cached capacity record for the supplied owner key. Mode `0` creates the first free 0x11c-byte record when none exists mode `1` updates an existing record and mode `2` clears an existing record by zeroing [entry+0x104]. The create and update paths store the owner key at [entry+0x10c] seed [entry+0x104] with 0x2328 resolve `numplayers` and `maxplayers` handles through 0x0058d6d0 and copy the current display string into [entry+0x84]. ghidra + rizin + llvm-objdump + strings
46 0x004693b0 80 multiplayer_session_event_cache_line_callback shell unknown inferred ghidra-headless 4 Transport-side callback that appends one incoming status line into the cached session-event line store at `0x006ae4d8`. When the callback status in EDX is nonzero and the incoming line pointer is valid it copies the string from the third stack argument into slot `0x006cd97c << 8` subject to the `0x1f4` entry cap and a small flag filter on the fourth stack argument then increments `0x006cd97c` for later iteration. ghidra + rizin + llvm-objdump
47 0x00469410 56 multiplayer_init_session_event_transport_state shell unknown inferred ghidra-headless 3 Initializes the Multiplayer.win session-event transport state rooted at `0x006cd970`. The helper latches the incoming mode or state into `0x006cd978`; when that value is nonzero it zeroes the large scratch block at `0x006ae4d8` resets `0x006cd97c` and registers the cached-line callback block rooted at `0x004693b0` through multiplayer_transport_register_selector_callback before returning. ghidra + rizin + llvm-objdump
48 0x00469450 97 multiplayer_teardown_session_event_transport shell unknown inferred ghidra-headless 3 Tears down the active session-event transport object at `0x006cd970`. When the latched mode at `0x006cd978` is nonzero and the multiplayer session object at `0x006cd920` exists it first switches the transport back to status route `0` through multiplayer_transport_select_status_route clears the status pump through multiplayer_transport_clear_status_pump disconnects through multiplayer_transport_disconnect shuts the object down through multiplayer_transport_shutdown and finally clears `0x006cd970`. ghidra + rizin + llvm-objdump
49 0x004694c0 57 multiplayer_publish_session_event_fixed_token shell unknown inferred ghidra-headless 3 Small session-event transport helper that publishes one fixed token through the active transport object when the latched mode and multiplayer session object are both present. It first switches the transport to status route `1` through multiplayer_transport_select_status_route and then sends the fixed token at `0x005c87a8` plus flag `1` through multiplayer_transport_publish_fixed_token_message. The current grounded caller is the Multiplayer.win branch at `0x0046c3c0`. ghidra + rizin + llvm-objdump + strings
50 0x00469500 27 multiplayer_flush_session_event_transport shell unknown inferred ghidra-headless 3 Lightweight session-event transport flush wrapper. When the active transport object at `0x006cd970` exists it first forces a status flush through multiplayer_transport_force_status_flush and then tail-calls multiplayer_transport_flush_and_maybe_shutdown on that same object. ghidra + rizin + llvm-objdump
51 0x00469520 94 multiplayer_register_session_event_cache_fields shell unknown inferred ghidra-headless 3 Registers the session-event cache-field subscription set for the active Multiplayer.win object. When no multiplayer session object is present it marks `[this+0x8f18]` armed and subscribes callback `0x00469200` through multiplayer_transport_subscribe_field_callback_set with the fixed field-id list `3 1 4 8 10 11 19 5` rooted at `[this+0x10]`. ghidra + rizin + llvm-objdump
52 0x00469580 65 multiplayer_begin_session_event_line_iteration shell unknown inferred ghidra-headless 4 Primes iteration over the cached session-event line store at `0x006ae4d8`. When the multiplayer session object at `0x006cd920` is absent it sets `[this+0x9874]` armed clears the cached line slots and line index at `0x006cd97c` and re-registers the line callback `0x004693b0` through multiplayer_transport_register_selector_callback before returning. ghidra + rizin + llvm-objdump
53 0x004695d0 66 multiplayer_next_session_event_cached_line shell unknown inferred ghidra-headless 4 Returns the next non-empty cached session-event line from the fixed store at `0x006ae4d8`. On first use after multiplayer_begin_session_event_line_iteration it resets `0x006cd97c` and clears `[this+0x9874]`; afterwards it returns the current 0x100-byte slot pointer when the first byte is nonzero and advances `0x006cd97c` or returns null when no further cached lines remain. ghidra + rizin + llvm-objdump
54 0x00469620 52 multiplayer_submit_owner_notified_session_event_text shell unknown inferred ghidra-headless 3 Submits one caller-supplied text buffer through the active session-event transport using callback multiplayer_session_event_notify_owner_and_queue_action8. The helper first sanitizes the input string into a local 0x100-byte transport record through multiplayer_transport_sanitize_identifier and then forwards that record through multiplayer_transport_submit_text_record with fixed mode arguments `0` and `1`. ghidra + rizin + llvm-objdump
55 0x00469660 27 multiplayer_send_session_event_text_selector0 shell unknown inferred ghidra-headless 3 Thin session-event transport wrapper that sends one caller-supplied text pointer through multiplayer_transport_send_selector_text with selector `0` when the pointer is non-null. The current grounded caller is the Multiplayer.win control dispatcher around `0x00469d30`. ghidra + rizin + llvm-objdump
56 0x00469680 14 multiplayer_pump_session_event_status shell unknown inferred ghidra-headless 3 Thin session-event transport wrapper that immediately requests a status pump through multiplayer_transport_request_status_pump on the active transport object at `0x006cd970` and discards one stack argument. Current grounded callers use it after updating Multiplayer.win status text ids `0xe60` and `0xe61`. ghidra + rizin + llvm-objdump
57 0x0046a6c0 307 multiplayer_session_event_publish_registration_field shell unknown inferred ghidra-headless 3 Switch-driven session-event callback that publishes one Multiplayer.win registration/status field into the destination builder passed on the stack. Depending on selector EDX it emits the local session name from `0x006cec74` the profile text at `0x006cd8d8+0x8e10` the constant `0x2328` the live session count from `0x006d40d0` the field at `[0x006d1270+0x3b6]` the active profile string at `[0x006cec7c+0x44]` or fixed strings such as `Initializing...` `openstaging` and `closedplaying`; unsupported selectors fall back to the fixed token at `0x005c87a8`. ghidra + rizin + llvm-objdump + strings
58 0x0046a830 194 multiplayer_session_event_retry_with_random_player_name shell unknown inferred ghidra-headless 3 Registration-side callback that increments the retry counter at `0x006cd984` and on early retries formats a randomized `RT3Player%d` name into `0x006ae0c0` sanitizes it into a local notification object notifies the current Multiplayer.win owner and forwards that object through multiplayer_transport_set_local_name. On the first retry it also routes request id `5` or `6` through multiplayer_set_pending_session_substate depending on the incoming status flag; after 25 retries it resets `0x006cd984` and `0x006cd974` and calls multiplayer_transport_reset_and_maybe_shutdown instead. ghidra + rizin + llvm-objdump + strings
59 0x0046a900 522 multiplayer_register_session_event_callbacks shell thiscall inferred ghidra-headless 4 Builds and registers the Multiplayer.win session-event callback table rooted at the local block on `[esp+0x28]`. The function seeds slots with multiplayer_session_event_forward_action1_request multiplayer_session_event_publish_pair_chat_template multiplayer_session_event_publish_action2_single_name multiplayer_session_event_publish_action2_pair multiplayer_session_event_forward_action4_request multiplayer_session_event_forward_action7_request multiplayer_session_event_noop_12byte_stub multiplayer_session_event_publish_registration_field multiplayer_session_event_publish_status_value multiplayer_session_event_publish_fixed_status_text multiplayer_session_event_seed_control_id_list multiplayer_session_event_query_session_count multiplayer_session_event_noop_8byte_stub multiplayer_session_event_latch_status_code multiplayer_session_event_notify_owner_and_queue_action8 multiplayer_init_session_event_transport_state and multiplayer_session_event_retry_with_random_player_name. It allocates the transport callback object under `0x006cd970` stages the session name into the local descriptor block and then finishes registration through multiplayer_transport_register_callback_table which in turn routes through multiplayer_transport_attach_callback_table_descriptor multiplayer_transport_enqueue_descriptor_block_record and multiplayer_transport_dispatch_callback_table_binding. ghidra + rizin + llvm-objdump + strings
60 0x0046c360 32 multiplayer_route_chat_line shell cdecl inferred ghidra-headless 3 Routes one multiplayer chat line through the active transport object at `0x006cec78` when present or falls back to the local Multiplayer.win chat publisher otherwise. The transport path forwards the supplied text into 0x4554e0 with fixed mode arguments `5 1 0`; the local fallback tail-calls multiplayer_publish_wrapped_chat_message. ghidra + rizin + llvm-objdump
61 0x0046f960 2209 multiplayer_dispatch_chat_command shell cdecl inferred ghidra-headless 4 Parses and dispatches one slash-prefixed Multiplayer.win chat command line from `[eax+0x08]`. The parser normalizes `/` to `\\` and handles the grounded command family `\\kick` `\\clear` `\\whois` `\\me` `\\unban` `\\ban` `\\snore` `\\sneeze` `\\hurry` `\\trackisfree` `\\loadgame` and `\\sendgame`. The strongest branches are now clear: `\\kick` resolves a typed peer name through the active session tables and forwards the resulting peer object through multiplayer_request_peer_session_control when the target is neither null nor the local player; `\\clear` clears the local chat pane through multiplayer_publish_wrapped_chat_message(null); `\\whois` finds a named peer and emits multi-line `%s Ip = %s` `Cpu` `Game` and `Build Time` diagnostics through multiplayer_route_chat_line; `\\ban` and `\\unban` resolve either a dotted player name or the selected peer name then update the semicolon-delimited moderation list through multiplayer_update_semicolon_name_list with add/remove modes while `\\unban` can also forward a live peer object through multiplayer_request_peer_session_control; `\\snore` `\\sneeze` and `\\hurry` build transient presentation objects then broadcast text ids `0xb79` `0xb7a` and `0xb7b`; `\\loadgame` copies the requested filename into `0x006ce630` and arms flag `0x006ce9bc`; `\\trackisfree` arms flag `0x006ce9b4`; and `\\sendgame` allocates one 0x5c-byte transfer record under `0x006ce290` for the chosen player slot. The parser returns `1` only when a command branch handled the line and otherwise leaves the caller to treat it as ordinary chat text. ghidra + rizin + llvm-objdump + strings
62 0x00470210 119 multiplayer_submit_chat_or_command_line shell cdecl inferred ghidra-headless 4 Submits one Multiplayer.win chat-entry line. The wrapper first calls multiplayer_dispatch_chat_command on the raw line buffer; when the parser returns zero it formats a normal `%s > %s` named chat line from the sender object at `[edi+0x08]` and the message payload; then either publishes it locally through multiplayer_publish_wrapped_chat_message or routes it through the active transport object at `0x006cec78`. When the parser returns nonzero the wrapper skips normal chat formatting because the slash-command branch already consumed the line. ghidra + rizin + llvm-objdump + strings
63 0x004ecc90 52 multiplayer_set_pending_session_substate shell unknown inferred ghidra-headless 2 Small pending-session-substate setter used by the multiplayer session-event callback family. The grounded stores are request id `5` to substate `5` request id `6` to substate `6` and request id `8` to substate `8` at `0x006d1288`. Other current callback-family callers still pass ids `1` `2` `4` and `7` without a visible store in this helper so this row stays structural for now. ghidra + rizin + llvm-objdump
64 0x004edce0 19 multiplayer_notify_window_owner shell unknown inferred ghidra-headless 3 Thin Multiplayer.win owner-notification wrapper. It loads the current window owner singleton from `0x006d1268` and when present forwards the supplied payload pointer into 0x004eccd0 for owner-side handling; current grounded callers are the session-event callback family around 0x004691a0 and the related registration path near 0x0046a8b3. ghidra + rizin + llvm-objdump
65 0x004ecb20 101 multiplayer_reset_local_session_slot_state shell cdecl inferred ghidra-headless 4 Resets the local Multiplayer.win session-slot state before window init or add-open-slot flows. The helper marks the local state at `0x006cec7c+0x97` initialized clears the local slot counters at `+0x79` and `+0x7b` zeroes the slot-marker bytes at `+0x87` clears the local summary block at `+0x44` and zero-fills the large session backing block at `0x006d1270` when present. ghidra + rizin + llvm-objdump
66 0x004ecb90 191 multiplayer_probe_or_allocate_open_player_slot shell cdecl inferred ghidra-headless 3 Probes or allocates one open local player-slot marker against the active Multiplayer.win session block at 0x006d1270. In probe mode `ecx=1` the helper checks that the local open-slot count and slot-marker bytes at `0x006cec7c+0x87` still fit within the remote slot counts and occupancy bytes rooted at `session+0x31b` and `session+0x3a3` and returns nonzero only when one additional slot can be claimed. In allocate mode `ecx=0` it finds the first locally empty slot whose remote occupancy byte is nonzero writes marker `0x64+index` into the local slot array increments `0x006cec7c+0x7b` and returns `0xff` on success. ghidra + rizin + llvm-objdump
67 0x004ed590 224 multiplayer_sync_staged_text_controls shell cdecl inferred ghidra-headless 3 Synchronizes the shared Multiplayer.win staged-text buffer into the two mirrored text controls at ids 0xe48 and 0xe5d and then copies the same string back into the active selection buffer at 0x006cec74+0x1ef when it changed. The helper reallocates each control-owned backing string as needed and is used from the larger window initializer pending-status service and one delayed service-loop recovery branch. ghidra + rizin + llvm-objdump
68 0x004ed890 164 multiplayer_schedule_requested_action shell cdecl inferred ghidra-headless 3 Initializes one requested Multiplayer.win action and resets the shared action globals before later dispatch. The helper writes the requested action id from EDI into 0x006d127c marks the action-active bit at 0x006d1274 clears the pending-step and substate fields at 0x006d1278 0x006d1280 and 0x006d1288 tears down the prior helper object at 0x006d1294 and allocates a fresh 0x10-byte helper. The currently named action writers above it queue action ids 1 and 4 from preview-dataset reset 2 from staged text-entry dialog setup 3 from staged text-entry commit and 5 or 6 from selected-preview follow-up branches. ghidra + rizin + llvm-objdump
69 0x004ed940 235 multiplayer_rebuild_open_player_slot_markers shell cdecl inferred ghidra-headless 3 Rebuilds the local Multiplayer.win open-player slot markers from the active session slot table and republishes the resulting count. The helper clears any existing local slot bytes above `0x64` from `0x006cec7c+0x87` while decrementing `0x006cec7c+0x7b` then walks the remote slot records at `session+0x31b` with count `session+0x3ae`. For each remotely open record it uses multiplayer_probe_or_allocate_open_player_slot to claim the next local marker when capacity remains and then formats the updated open-slot count into shell control `0x6f` with resource id `0xe36`. ghidra + rizin + llvm-objdump
70 0x004edc40 145 multiplayer_reset_preview_dataset_and_request_action shell cdecl inferred ghidra-headless 3 Resets the active Multiplayer.win preview dataset object at 0x006cd8d8 and immediately schedules the next requested action. The helper destroys any existing 0x9898-byte dataset object allocates and constructs a fresh one through 0x004ed800 clears the text control at id 0xe47 and the staged entry buffer at 0x006d11a8 and then queues action id 1 when the caller passes zero or action id 4 when the caller passes a nonzero dataset-related value. ghidra + rizin + llvm-objdump
71 0x004ee0e0 225 multiplayer_open_staged_text_entry_dialog shell cdecl inferred ghidra-headless 3 Opens the small Multiplayer.win staged text-entry dialog and queues requested action 2. The helper chooses one of two prompt ids from the current preview mode copies the current profile text from 0x006cec74+0x1ef into the staging buffer at 0x006d1128 persists the profile state through 0x00484910 builds a formatted prompt string through 0x00518de0 and opens the modal shell dialog through 0x004c98a0 with the local callbacks at 0x004ed100 and 0x004ed4c0 before queuing action 2. ghidra + rizin + llvm-objdump
72 0x004ee1d0 456 multiplayer_commit_staged_text_entry shell cdecl inferred ghidra-headless 3 Commits one staged Multiplayer.win text entry and queues requested action 3 when validation succeeds. The helper refreshes the mode-dependent prompt text saves the shared profile state through 0x00484910 copies either the caller-provided string or the text control 0xe47 into the staging buffer at 0x006d11a8 derives the companion buffer at 0x006d1228 from the current preview object or fallback globals and when the staged text exceeds five bytes schedules action 3 through multiplayer_schedule_requested_action; otherwise it clears the staged buffer and text control. ghidra + rizin + llvm-objdump
73 0x004ee3a0 244 multiplayer_reset_tool_globals shell thiscall inferred ghidra-headless 3 Resets the smaller multiplayer-tool singleton state rooted around 0x006d1268 through 0x006d1270 for one shell mode created from 0x00482ec0. The helper seeds the shared vtable clears or rebinds the active singleton pointers and performs the same early shell-service notifications used by the larger Multiplayer.win initializer before later selection or preview code runs. ghidra + rizin + llvm-objdump + strings
74 0x004ee430 141 multiplayer_update_preview_mode_labels shell cdecl inferred ghidra-headless 3 Updates the small mode-dependent label widget pair used by the Multiplayer.win preview branch. The helper chooses one of two label-id pairs anchored by string ids 0xe12 0xe18 and 0xe73 then writes them through 0x00540120 into shell controls such as ids 0x65 0x6d 0x86 and 0x87. It is called from multiplayer_load_selected_map_preview_surface the larger multiplayer initializer and the restore-from-globals callback. ghidra + rizin + llvm-objdump + strings
75 0x004ee4c0 49 multiplayer_publish_control_0x69_mode shell cdecl inferred ghidra-headless 2 Publishes the current mode for Multiplayer.win control 0x69 from the presence of the session-related singleton at 0x006d40dc. The helper pushes mode 3 when that object exists or mode 1 otherwise through 0x00469d30 and is used after preview and count-setting branches to keep that control in sync with session state. ghidra + rizin + llvm-objdump
76 0x004ee500 50 multiplayer_are_all_peer_ready shell cdecl inferred ghidra-headless 4 Returns true only when every element in the shell-owned multiplayer peer list exposed through 0x00521680 has ready flag bit 0x01 set at offset +0x5c. The service loop uses this gate before committing the larger multiplayer launch or transition branch. ghidra + rizin + llvm-objdump
77 0x004ee540 352 multiplayer_refresh_peer_roster_list shell cdecl inferred ghidra-headless 3 Refreshes the Multiplayer.win peer-roster list for preview modes 0xe12 and 0xe13. The helper chooses one of two mode-dependent text ids updates control 0x8b when the current roster selection is valid enumerates either the direct peer list at 0x006d40d0 or the fallback dataset-backed names from 0x006cd8d8 into repeated control-0x88 entries and when no roster entries remain forces a preview-dataset reset through multiplayer_reset_preview_dataset_and_request_action. It also republishes one session-state byte into shell control 9 before returning. ghidra + rizin + llvm-objdump
78 0x004ee6a0 359 multiplayer_refresh_map_entry_list shell cdecl inferred ghidra-headless 3 Refreshes the Multiplayer.win map-entry list for preview modes 0xe11 and 0xe13. The helper chooses one of two mode-dependent text ids writes the active selection header into control 0x8b walks up to 0x80 0x11c-byte records from the list object exposed by control 0xe47 publishes each entry into repeated control-0x88 rows and mirrors the currently selected matching row into control 0x66. The comparison path uses the current staged selection text copied into a local buffer before the list walk. ghidra + rizin + llvm-objdump
79 0x004ee810 308 multiplayer_publish_wrapped_chat_message shell cdecl inferred ghidra-headless 4 Publishes one Multiplayer.win chat or status message into the mode-dependent chat pane. The helper chooses text resource `0xe32` or `0xe5c` from the current preview mode at `[window+0x7c]`; resolves the corresponding text list object through `0x0053f830`; word-wraps the supplied string to width `0x3e`; emits each wrapped row into control `0x88` through `0x00540120`; stores per-row metadata back into the list object; and finally updates the summary row in control `0x66` or clears the pane when the caller passes a null string. It is used by the local chat transport fallback; the named `%s > %s` message publisher; and the Multiplayer.win launch-side action wrappers. ghidra + rizin + llvm-objdump + strings
80 0x004eed30 208 multiplayer_sync_selected_map_entry shell cdecl inferred ghidra-headless 3 Selection wrapper above 0x004ee950 for the multiplayer map-preview branch. It walks the current 0x25a-byte multiplayer entry table compares the selected record string against the shell selection buffer near 0x006cec7c and then calls 0x004ee950 with either the matching strings or null inputs to refresh the active preview state. ghidra + rizin + llvm-objdump
81 0x004ee950 982 multiplayer_load_selected_map_preview_surface shell cdecl inferred ghidra-headless 4 Loads or refreshes the currently selected .gmt-backed preview surface for the multiplayer window family rooted at 0x006d1270. The routine validates the selected filename suffix copies selected strings into the active record updates preview or status values under offsets such as +0x3b2 and +0x3b6 formats several shell text fields through 0x00540120 and finishes by decoding a 256x256 image through 0x0053f830 and surface_init_rgba_pixel_buffer. The branch is anchored by the larger Multiplayer.win initializer at 0x004efe80. ghidra + rizin + llvm-objdump + strings
82 0x004eee00 649 multiplayer_refresh_map_preview_panel shell cdecl inferred ghidra-headless 3 Refreshes the multiplayer map-preview panel for one requested preview state or sentinel value. The helper stores the requested state at [this+0x78] updates several shell text fields through 0x00540120 handles the special active state 0xe15 and the fallback -1 case copies the selected entry strings out of the multiplayer entry table at 0x006d126c into the shell selection buffer near 0x006cec7c and then routes through multiplayer_sync_selected_map_entry or multiplayer_load_selected_map_preview_surface before returning. ghidra + rizin + llvm-objdump + strings
83 0x004ef090 365 multiplayer_select_preview_mode_and_refresh shell cdecl inferred ghidra-headless 3 Selects one of the top-level multiplayer preview modes identified by command ids 0xe10 through 0xe13 then refreshes the preview panel. The helper stores the requested mode at [this+0x7c] updates the four mode-button states through 0x00540120 handles the special 0xe12 branch with extra multiplayer refresh helpers and a direct multiplayer_refresh_map_preview_panel call for state 0xe15 emits a summary status field at 0xe55 falls back through multiplayer_refresh_map_preview_panel(-1) and finally refreshes the panel timestamp at [this+0x80] through 0x0051d890. ghidra + rizin + llvm-objdump + strings
84 0x004ef200 1786 multiplayer_service_pending_status_state_machine shell cdecl inferred ghidra-headless 4 Services the pending Multiplayer.win status or transition state machine when the global flag at `0x006d1278` is set. The routine clears the pending flag switches over the queued step id at `0x006d1280` and now has several grounded branches: step `1` builds modal status `0xe4f` optionally appends owner text from `0x006d4118/0x006d411c` tears down the preview dataset at `0x006cd8d8` and refreshes control `0xcc`; step `2` clears `0x006cd920` destroys the preview dataset and opens status `0xe50`; step `3` gates on latch byte `0x006d1292` and warns with `0xe51`; step `4` requires `0x006cd920 != 0` and `0x006ae3c8 >= 3` or warns with `0xe52` otherwise it seeds a random `RT3Player%d` name into the staged-text controls through multiplayer_sync_staged_text_controls and sets `0x006ae3c4 = 2`; step `5` opens status `0xe54` then rebuilds the preview dataset through multiplayer_reset_preview_dataset_and_request_action. A second substate switch on `0x006d1284` formats statuses `0xe55..0xe5f` `0xe92` and `0xf53`; its `0x5` and `0x8` families either force preview mode `0xe13` or reseed the default player-name path before syncing the staged-text controls. ghidra + rizin + llvm-objdump + strings
85 0x004ef960 1260 multiplayer_dispatch_requested_action shell cdecl inferred ghidra-headless 4 Dispatches the current requested Multiplayer.win action stored in `0x006d127c`. The switch drives six higher-level action cases that combine immediate mode changes through multiplayer_select_preview_mode_and_refresh with deferred pending-step writes into `0x006d1278` and `0x006d1280`. The grounded wrappers are now broader than before: action `1` either enters preview mode `0xe11` immediately or schedules pending step `1`; action `2` resets the local session-slot state through multiplayer_reset_local_session_slot_state copies the staged text buffers into the active dataset seeds one local open-slot marker refreshes the local player rows enters preview mode `0xe12` and rebuilds the open-slot markers; action `3` copies the staged text buffers back into the active multiplayer object and then uses the dataset mode at `[0x006cd8d8+0x0c]` to schedule pending steps `0xa` `0xb` `0xc` `0xe` or fallback `0x2` while its resolved-mode branch re-enters preview mode `0xe12` clears latches `0x006d1291/0x006d1292` and seeds the local player panel; action `4` promotes the committed staged text into preview mode `0xe13` or schedules pending step `5` or `6` from the launcher substate at `0x006d1288`; action `5` pumps the selected-map follow-up callback then either rebuilds the open-slot markers and refreshes status control `0x109` or schedules pending step `1` with control `0x11` updates depending on the current launch-side state; action `6` validates the staged text against the active dataset and schedules pending step `6` when the launcher substate remains armed. ghidra + rizin + llvm-objdump
86 0x004efe80 1388 multiplayer_window_init_globals shell thiscall inferred ghidra-headless 4 Initializes the Multiplayer.win shell window family and its large backing state block. The constructor seeds the shared vtable at 0x005d12ac clears multiplayer globals under 0x006d1274 through 0x006d1288 allocates and zeroes a 0x100f2-byte data block stored at 0x006d1270 registers the active singleton at 0x006d1268 pushes the Multiplayer.win resource into the standard shell window setup helper and then continues with multiplayer-specific list and status initialization. ghidra + rizin + llvm-objdump + strings
87 0x004f03f0 3612 multiplayer_window_service_loop shell cdecl inferred ghidra-headless 3 Top-level Multiplayer.win service loop. The function performs an early startup countdown through `0x006cd90c` calls multiplayer_service_pending_status_state_machine processes the special pending-step-10 gate with latch byte `0x006d1292` clears one text field when pending step 2 completes and then continues into the broader multiplayer update loop with timed retries staged-text synchronization peer-roster and map-entry list refresh helpers object-state checks and several mode-specific update branches. It queues requested action 5 after rebuilding one selected-map preview follow-up path and requested action 6 after the validated staged-text follow-up dialog branch. The launch-side inline wrappers now separate into three behaviors: a peers-not-ready warning dialog on resource `0xf15`; an add-open-slot path that seeds `0x006cec7c+0x83` stores the callback owner in `0x006d4110` and refreshes status control `0x109`; and a missing-session or slot-capacity warning path that opens modal dialogs on resources `0x2cf` `0x2b8` or `0x2b9`. ghidra + rizin + llvm-objdump
88 0x004f13e0 167 multiplayer_restore_preview_state_from_globals shell thiscall inferred ghidra-headless 3 Restores the Multiplayer.win preview UI from the current global mode and preview-state fields. The callback refreshes the mode-dependent labels through multiplayer_update_preview_mode_labels mirrors selection presence into the active shell object toggles the 0x006d1291 recursion guard replays multiplayer_select_preview_mode_and_refresh and multiplayer_refresh_map_preview_panel using the saved fields at [this+0x7c] and [this+0x78] and if the active preview resources are missing schedules pending status step 7 by writing 0x006d1278 and 0x006d1280 instead of forcing an immediate redraw. ghidra + rizin + llvm-objdump + strings
89 0x00502220 813 paint_terrain_load_selected_gmt_surface shell cdecl inferred ghidra-headless 4 Loads or refreshes the currently selected .gmt-backed preview surface for the PaintTerrain tool family rooted at 0x006d14bc and tied to the PaintTerrain.win or GroundTerrain.tga branch. The routine validates the selected filename suffix copies selected strings into the active record updates tool status bytes and counters formats several shell text fields through 0x00540120 and finishes by decoding a 256x256 image through 0x0053f830 and surface_init_rgba_pixel_buffer. ghidra + rizin + llvm-objdump + strings
90 0x00502550 456 paint_terrain_refresh_status_panel shell cdecl inferred ghidra-headless 3 Refreshes the PaintTerrain tool status or selection panel after the active .gmt surface changes. The helper reads the PaintTerrain singleton at 0x006d14bc consults shell selection globals and lookup tables formats several text or numeric fields through 0x00540120 and toggles the side flag at 0x006d14a8 before returning. ghidra + rizin + llvm-objdump + strings
91 0x00502720 144 paint_terrain_tool_init_globals shell thiscall inferred ghidra-headless 4 Initializes the PaintTerrain shell tool singleton rooted at 0x006d14bc. The constructor seeds the tool vtable and default fields registers the active instance globally and is selected directly from shell_transition_mode alongside the neighboring terrain-edit tool constructor at 0x004ee3a0. ghidra + rizin + llvm-objdump + strings
92 0x00481d00 612 bootstrap_parse_command_line_flags bootstrap cdecl inferred ghidra-headless 4 Parses the startup command line from ECX handling slash and dash switches and writes multiple bootstrap globals and option buffers before shell service init. ghidra + rizin
93 0x00481fd0 348 bootstrap_scan_autorun_media bootstrap cdecl inferred ghidra-headless 4 Scans drive letters for RT3 autorun marker files rt3d1.txt and rt3d2.txt using GetDriveTypeA and open or close helpers before deeper shell init. ghidra + rizin
94 0x004821d0 1019 shell_recompute_layout_slots bootstrap thiscall inferred ghidra-headless 4 Recomputes the shell layout-slot table after resolution or related display selectors change; derives normalized coordinates from static float tables updates 144 slot entries through the shell bundle child at [0x006d4024+0x18] and then commits the refreshed state. ghidra + rizin
95 0x00482ec0 1359 shell_transition_mode bootstrap thiscall inferred ghidra-headless 4 Switches the shell state's active mode at [this+0x08] tearing down any prior mode object selecting one of seven mode-specific handlers and updating globals like 0x006cec78 before notifying the shell bundle through 0x00538e50. ghidra + rizin
96 0x005a2d64 101 crt_init_exit_handlers startup cdecl inferred ghidra-headless 3 Initializes on-exit tables and registers atexit handling before control reaches application startup. ghidra + rizin
97 0x005a30f2 34 __amsg_exit startup cdecl inferred ghidra-headless 4 CRT fatal-exit helper that forwards startup failures into __exit. ghidra + rizin
98 0x005a3117 36 crt_fast_error_exit startup cdecl inferred ghidra-headless 4 Startup error path that optionally emits the CRT banner then formats the failure and terminates through ___crtExitProcess. ghidra + rizin
99 0x005a313b 423 crt_startup_entrypoint startup cdecl inferred ghidra-headless 4 PE entrypoint for patch 1.06; performs CRT and environment setup then validates early state before handing off to application bootstrap. sha256:01b0d2496cddefd80e7e8678930e00b13eb8607dd4960096f527564f02af36d4 + ghidra + rizin + llvm-objdump
100 0x0053b020 70 bootstrap_reset_locale_state bootstrap unknown inferred ghidra-headless 2 Calls the locale helper at 0x0053ae70 then frees and clears related global pointers before later shell setup continues. ghidra + rizin
101 0x0053b010 11 bootstrap_mark_runtime_started bootstrap cdecl inferred ghidra-headless 2 Single-purpose bootstrap helper that flips a process-global started flag to one before branding and shell setup continue. ghidra + rizin
102 0x0054e6d0 42 bootstrap_capture_keyboard_state bootstrap cdecl inferred ghidra-headless 4 Single-purpose bootstrap probe that snapshots the host keyboard state through GetKeyboardState. ghidra + rizin
103 0x0055da40 424 bootstrap_probe_system_profile bootstrap cdecl inferred ghidra-headless 4 Collects GlobalMemoryStatus and CPUID feature bits then stores coarse machine capability flags used by later bootstrap decisions. ghidra + rizin
104 0x00507b90 346 geography_info_refresh_category_controls map cdecl inferred ghidra-headless 3 Refreshes the geography info category controls for the current panel mode stored at 0x00622af4. It emits the six-entry mode selector plus dependent label fields through 0x00540120 and in mode 5 it can seed [this+0x8c] from the current selection path before preview formatting continues. ghidra + rizin + llvm-objdump
105 0x00508550 363 geography_info_format_selected_record_summary map cdecl inferred ghidra-headless 3 Formats the selected geography record summary for the info panel. It looks up the active record index [this+0x8c] in 0x0062b2fc follows secondary data through field +0x173 into 0x0062b268 computes scaled values against current shell state and emits the localized summary block through 0x00540120. ghidra + rizin + llvm-objdump + strings
106 0x00508730 292 geography_info_format_preview_panel map cdecl inferred ghidra-headless 3 Formats the geography info preview panel for the currently selected record stored at [arg_4h+0x8c]. It chooses preview assets like 2DLabel.imb 2DCity.imb 2DVent.imb 2DMist.imb and 2DVolcano.imb and emits localized text blocks through repeated 0x00540120 calls using geography tables rooted at 0x0062b2fc and 0x0062b268. ghidra + rizin + llvm-objdump + strings
107 0x00508880 727 geography_info_select_record_and_refresh map cdecl inferred ghidra-headless 3 Selects one geography record or category then refreshes the preview panel. It stores the requested mode at 0x00622af4 resolves a matching record from the geography tables formats localized headings and detail text calls 0x00508730 and then triggers the surrounding panel refresh path. ghidra + rizin + llvm-objdump + strings
108 0x0051d900 155 string_find_substring_ex support cdecl inferred ghidra-headless 3 Reusable substring finder that returns a pointer to the first matching window in the haystack or null. It precomputes both string lengths then slides across the haystack calling one of two compare helpers depending on the mode flag pushed on the stack; the graphics branch uses it to probe adapter strings for legacy GPU-profile tokens and bootstrap code uses it for startup media or compatibility string checks. ghidra + rizin + llvm-objdump
109 0x0051d870 21 bootstrap_seed_tick_count bootstrap cdecl inferred ghidra-headless 4 Lazily snapshots GetTickCount into a bootstrap-global cache so later subsystems start from a nonzero host tick baseline. ghidra + rizin
110 0x0051ebc0 731 shell_reset_display_runtime_defaults shell cdecl inferred ghidra-headless 3 Resets the global display runtime defaults rooted at 0x006d4024. It clears the large display-settings block under offsets 0x11468a and above seeds default resolution and capability flags from mode 0x006d4028 and reinitializes several shell display toggles before later preset application continues. ghidra + rizin + llvm-objdump
111 0x0051eea0 128 shell_save_display_runtime_config shell cdecl inferred ghidra-headless 4 Writes the larger display-runtime blob to data\\configuration\\engine.cfg. It stores version key 0x41b serializes the 0x1e4-byte runtime block rooted at [this+0x11468a] and writes an additional 0x1ec-byte companion block before closing the file. ghidra + rizin + llvm-objdump + strings
112 0x0051ef20 194 shell_load_display_runtime_config_or_init_defaults shell cdecl inferred ghidra-headless 4 Loads the larger display-runtime blob from data\\configuration\\engine.cfg. When the file is missing invalid or already superseded by mode state at 0x006d4028 it falls back to 0x0051ebc0 and 0x0051eea0; otherwise it validates key 0x41b restores the 0x1e4-byte and 0x1ec-byte blocks and clears one shell display flag when [this+0x11474a] is set. ghidra + rizin + llvm-objdump + strings
113 0x0051f1d0 90 shell_signal_deferred_work_item_shutdown shell thiscall inferred ghidra-headless 3 Walks the shell deferred-work item queue at [this+0x1136a5] and inspects each queued payload object's nested message queue at [item+0xe4]. When intrusive_queue_peek_tail_payload finds a nonnull tail payload it clears the outer queued-handle slot at [item+0xe8] and appends a null sentinel into the nested queue through intrusive_queue_push_back before continuing iteration. ghidra + rizin + llvm-objdump
114 0x0051f230 128 shell_enqueue_deferred_work_message shell thiscall inferred ghidra-headless 4 Routes one deferred-work message through the shell queue system. When the global routing gate at 0x006d4034 and shell flag [this+0x11369c] are both set it feeds the special queue at [this+0x11369d]; otherwise a nonnull payload object is queued once in [this+0x1136a5] with the returned queue-node handle cached at [item+0xe8] and the message is appended to the payload-owned nested queue at [item+0xe4] while a null payload appends directly into the fallback queue at [this+0x1136a1]. ghidra + rizin + llvm-objdump
115 0x0051f2b0 104 shell_post_deferred_message_type5 shell thiscall inferred ghidra-headless 4 Allocates one 0x5e-byte deferred-message record from the shell-owned slab rooted at [this+0x5c] using count [this+0x58] tags it as type 0x05 stores four caller dwords at offsets +0x01 +0x05 +0x09 and +0x0d and then posts the record directly into the shell deferred queue roots through [this+0x11369d] or [this+0x1136a1]. ghidra + rizin + llvm-objdump
116 0x0051f320 72 shell_post_deferred_message_type6 shell thiscall inferred ghidra-headless 4 Allocates one 0x5e-byte deferred-message record from the same shell slab and tags it as type 0x06 before posting it directly into the shell deferred queue roots. This is the minimal direct-post sibling of the type-0x05 builder and uses the same count field at [this+0x58] and slab base at [this+0x5c]. ghidra + rizin + llvm-objdump
117 0x0051f370 229 shell_enqueue_deferred_message_type4 shell thiscall inferred ghidra-headless 4 Allocates one 0x5e-byte deferred-message record from the shell-local slab at [this+0x5c] populates the larger multi-field payload tags it as type 0x04 mixes the shell byte [this+0x114227] into record byte +0x5d and routes the finished record through shell_enqueue_deferred_work_message. ghidra + rizin + llvm-objdump
118 0x0051f460 173 shell_enqueue_deferred_message_type1 shell thiscall inferred ghidra-headless 4 Allocates one 0x5e-byte deferred-message record from the same shell-local slab fills the smaller type-0x01 payload subset mixes the shell byte [this+0x114227] into record byte +0x5d and routes the finished record through shell_enqueue_deferred_work_message. ghidra + rizin + llvm-objdump
119 0x0051f510 48 shell_set_gamma_ramp_scalar shell thiscall inferred ghidra-headless 4 Applies one shell gamma-ramp scalar to the active display runtime state. When the presentation service pointer at [this+0x0c] is live it forwards the scalar into 0x00547f20 for an immediate hardware upload; otherwise it only caches the requested value at [this+0x1146b9] until the service is ready. ghidra + rizin + llvm-objdump
120 0x0051fd70 516 shell_update_frame_time_history shell thiscall inferred ghidra-headless 4 Updates a 256-sample frame-time history from successive GetTickCount deltas. The helper advances the ring index in 0x006d403c stores each delta under [this+0x11428a] and derives a smoothed frame scalar at [this+0x114282] for later shell frame consumers such as 0x0051ff80 and the presentation-frame path. ghidra + rizin + llvm-objdump
121 0x00521d10 38 multiplayer_request_peer_session_control shell cdecl inferred ghidra-headless 3 Requests one direct session-control action for a resolved multiplayer peer object. When the live session transport at `0x006d40dc` is present it follows the transport-owned interface at `[ecx+0x18e]->+0x08` and invokes vtable slot `+0x68` with the target peer object and three zero trailing arguments; the current grounded callers are the `\\kick` branch and the online-peer `\\unban` follow-up path. ghidra + rizin + llvm-objdump
122 0x0051fa00 56 shell_get_memory_budget_ceiling_bytes shell thiscall inferred ghidra-headless 3 Returns the current upper memory-budget bucket in bytes for the shell display runtime. When override field [this+0x1146ca] is set it maps that tier through the shared table at 0x00624c34 containing 0 1MB 2MB and 4MB entries; otherwise it starts from baseline field [this+0x1136ad] and adjusts it by the active lower-tier delta derived from [this+0x1146c6] and [this+0x1136a9] before clamping negative results to zero. ghidra + rizin + llvm-objdump
123 0x0051fa40 25 shell_get_memory_budget_floor_bytes shell thiscall inferred ghidra-headless 3 Returns the current lower memory-budget bucket in bytes for the shell display runtime. When field [this+0x1146c6] is nonzero it maps that tier through the shared 0 1MB 2MB 4MB table at 0x00624c34; otherwise it falls back to baseline field [this+0x1136a9]. ghidra + rizin + llvm-objdump
124 0x0051fa60 63 shell_get_nonnegative_memory_budget_floor_bytes shell thiscall inferred ghidra-headless 3 Returns a nonnegative lower memory-budget value for float consumers in the shell and presentation paths. It prefers explicit tier field [this+0x1146ce] then the active floor bucket behind [this+0x1146c6] and finally baseline field [this+0x1136a9] using the shared 0 1MB 2MB 4MB table at 0x00624c34 and clamping negative results to zero. ghidra + rizin + llvm-objdump
125 0x005204b0 128 shell_flush_deferred_work_queues shell thiscall inferred ghidra-headless 3 Flushes the shell controller's three deferred-work queue roots at [this+0x1136a1] [this+0x11369d] and [this+0x1136a5]. The helper clears the first two containers through intrusive_queue_clear_and_release then rewinds the deferred-item queue through intrusive_queue_rewind_iterator repeatedly pops each queued payload through intrusive_queue_next_iterator_node clears its outer queued-handle slot at [item+0xe8] and finally releases the remaining queue storage before returning. It is used at the end of the shell frame cycle and from the broader shell-mode helper at 0x00443a50. ghidra + rizin + llvm-objdump
126 0x00520620 141 shell_service_frame_cycle shell thiscall inferred ghidra-headless 3 Services one shell frame cycle for the active controller. When pending-frame state is armed through [this+0x56] and the controller pointers at [this+0x18] [this+0x1c] and [this+0x28] are live it runs the main presentation refresh through 0x0052b990 then updates frame timing through 0x0051fd70 runs the mouse-cursor frame updater 0x0053f4e0 requests the deeper layout-state rebuild path through 0x00565110 performs a one-time ShowWindow on [this] drains deferred work through 0x005204b0 and clears the pending flags at [this+0x56] and [this+0x58]. ghidra + rizin + llvm-objdump
127 0x00521060 805 bootstrap_init_shell_service_bundle bootstrap cdecl inferred ghidra-headless 4 Builds the shell-facing singleton bundle stored through globals like 0x006d4024 0x006d402c and 0x006d4030 wiring startup width and height state and an rt3_ prefixed service path. ghidra + rizin
128 0x00521390 486 bootstrap_destroy_shell_service_bundle bootstrap cdecl inferred ghidra-headless 4 Destroys the shell service bundle created by 0x00521060 releasing each global singleton and clearing 0x006d4024 0x006d402c 0x006d4030 0x006d4020 and 0x006d4018. ghidra + rizin
129 0x00523d90 65 shell_commit_layout_updates bootstrap thiscall inferred ghidra-headless 3 Applies pending layout-slot changes from the shell controller into its subordinate layout-state object at [this+0x2d] by walking embedded service pointers and issuing the follow-on rebuild or refresh calls that make the updated slot table live. ghidra + rizin
130 0x00523e40 51 shell_invalidate_layout_state bootstrap thiscall inferred ghidra-headless 4 Marks the shell controller's layout-state path dirty by setting flags [this+0x3747] [this+0x3748] and [this+0x3749] then forwarding two state parameters into the subordinate object at [this+0x2d]. ghidra + rizin
131 0x005270d0 8 shell_mark_layout_dirty bootstrap thiscall inferred ghidra-headless 2 Marks the shell layout child dirty by setting byte flag [this+0x3749] before later code forces a commit pass. ghidra + rizin
132 0x00527650 1476 shell_publish_texture_budget_report shell thiscall inferred ghidra-headless 4 Builds and publishes a shell-side texture budget report through the current layout state at [this+0x2d]. The routine formats the current memory-budget floor and ceiling buckets from 0x0051fa40 and 0x0051fa00 converts them to kilobytes adds the current texture-change counter through 0x0055d390 appends labels like Texture changes per frame Texture SRAM and Texture VRAM and forwards the assembled text into 0x00566980. ghidra + rizin + llvm-objdump + strings
133 0x00527e10 868 shell_update_layout_tracking_sample bootstrap thiscall inferred ghidra-headless 4 Samples a tracked shell target from the object argument computes distance heading and orientation deltas against cached values at [this+0x36b8..0x36cc] consults the dirty flags and index helper at 0x00526590 and returns whether the controller should drive a fresh layout-state apply; on success it updates the cached sample fields and the global tick at 0x00cc3b4c. ghidra + rizin
134 0x0052b990 4993 shell_refresh_presentation_frame shell thiscall inferred ghidra-headless 3 Main shell frame-style refresh pass for the active controller and layout-state path. It handles mode-sensitive layout-state rebuilds and dirties updates tracked shell samples through 0x00527e10 runs the nearby geographic-label static-cell animated-quad ranked-overlay and ranked-billboard sweeps applies presentation-node properties and cached vertex spans optionally publishes the texture budget report through 0x00527650 may request a deeper rebuild through 0x00565110 and can recurse once for a follow-up presentation pass before downstream timing or present helpers run. ghidra + rizin + llvm-objdump
135 0x0052da00 102 vehicle_visual_register_attachment_object bootstrap thiscall inferred ghidra-headless 3 Registers one prebuilt attachment object on the owning vehicle visual. The helper lazily allocates a small attachment list at [this+0x81] pushes the object through 0x00556e10 copies the owner tint triple from [this+0x1e2] [this+0x1e6] and [this+0x1ea] into the object through 0x005545d0 and links the owner back through 0x005540a0. ghidra + rizin + llvm-objdump
136 0x00529840 400 shell_build_static_cell_triangle_sweep bootstrap thiscall inferred ghidra-headless 4 Builds the fixed-cell triangle sweep over the grid returned by 0x00533cd0. It samples shell brightness to derive one grayscale packed color binds the layout-state vertex24 table once and then expands each accepted 0x24-byte cell record into six vertex24 records by emitting the same three-point face twice before committing the span and restoring presentation state. ghidra + rizin + llvm-objdump
137 0x00529b50 1149 shell_build_geographic_label_vertex24_sweep bootstrap thiscall inferred ghidra-headless 4 Builds the geographic-label vertex24 sweep over the grid returned by 0x00533db0. It gates on config byte [this+0x29+0x63] primes one vertex24 span and text presentation state samples shell brightness and the 0x006d9098 priority map to derive per-item alpha rejects items through virtual check +0x0c emits per-item geographic-label frame geometry through 0x00539fb0 optionally emits geographic-label text through 0x0053a960 and commits buffered spans through the layout-state presentation helpers. The naming matches the dedicated geographic-label asset family backed by gpdLabelDB and 2DLabel.imb. ghidra + rizin + llvm-objdump
138 0x00528d90 1824 shell_process_nearby_presentation_item bootstrap thiscall inferred ghidra-headless 3 Processes one candidate item for the nearby-presentation sweep. It rejects disabled entries and mode-mismatched flags optionally gates by forward-range tests around the caller origin lazily assigns the item's segment-record window from the layout-state tables stores accepted nearest-candidate distances in the side buffer at [this+0xa9] and [this+0xad] and forwards the item plus eligible child collections into the active presentation lists. ghidra + rizin + llvm-objdump
139 0x005294b0 912 shell_update_nearby_presentation_sweep bootstrap thiscall inferred ghidra-headless 3 Performs the higher-level nearby-presentation sweep for the current shell state. It scans candidate cells from the offset table at [this+0x374f] using the priority map at 0x006d9098 enumerates item lists for each accepted cell normalizes the first accepted direction vector binds the segment-record presentation table through 0x0054bab0 calls 0x00528d90 for each candidate and then selects the nearest buffered item into [this+0x366e] before refreshing presentation batches through 0x00548da0. ghidra + rizin + llvm-objdump
140 0x00529fd0 793 shell_build_cell_vertex24_sweep bootstrap thiscall inferred ghidra-headless 4 Builds the animated-quad cell sweep over the grid returned by 0x00533e30 depending on the boolean mode argument. It gates on configuration bytes [this+0x29+0x5f] or [this+0x29+0x60] walks candidate-cell offsets from [this+0x374f] selects the primary list at [cell+0x1c] or alternate list at [cell+0x20] initializes the layout-state vertex24 table once through 0x0054bb70 streams each list through 0x00567c70 or 0x00567ce0 and then commits the accumulated span through 0x00545c50 before restoring presentation state. ghidra + rizin + llvm-objdump
141 0x0052a2f0 736 shell_build_ranked_overlay_vertex24_sweep bootstrap thiscall inferred ghidra-headless 3 Builds a ranked secondary vertex24 overlay pass over the cell grid returned by 0x00533e50 and two object collections at [this+0x85] and [this+0x81]. It computes a per-frame packed tint from the current shell brightness gathers and sorts candidate items by priority field [item+0x1d9] binds the layout-state vertex24 table and emits accepted items through 0x00524780 and 0x00554e70 before committing the span. ghidra + rizin + llvm-objdump
142 0x0052a5d0 1784 shell_build_ranked_object_billboard_sweep bootstrap thiscall inferred ghidra-headless 3 Builds the sibling ranked object-overlay pass gated by config byte [this+0x29+0x5e]. It merges candidates from the object collections at [this+0x85] and [this+0x81] sorts them by priority field [item+0x1d9] prepares billboard basis state through 0x00566670 and emits accepted entries through 0x00554e70 before committing the vertex24 span. ghidra + rizin + llvm-objdump
143 0x0052dd00 864 shell_expand_segment_record_triplets bootstrap thiscall inferred ghidra-headless 4 Expands one active presentation-batch record into three transformed 0x20-byte segment records inside the caller-provided buffer; each output record is two vec3 blocks at +0x00 and +0x0c plus scalar slots at +0x18 and +0x1c. The selected batch record supplies a source-array pointer at +0x04 a source-count at +0x0c and 0x4c-byte packed source entries that carry four point sources plus three scalar pairs for the emitted triplet. ghidra + rizin
144 0x0053f4e0 739 mouse_cursor_update_frame_state shell thiscall inferred ghidra-headless 4 Per-frame MouseCursor.cpp updater for the global cursor controller at 0x00ccbb20. It refreshes elapsed tick state through 0x0051d890 re-arms the active cursor selection through 0x0053f450 and 0x0053f000 when the 150 ms and 15 s idle thresholds trip resets per-frame cursor globals through 0x0054f6c0 and 0x0054f6d0 samples cursor placement and world-relative state through world_anchor_measure_projected_half_width world_anchor_measure_projected_half_height and shell_queue_world_anchor_marker and publishes the resulting cursor presentation state through shell_publish_text_callout_presentation before finalizing through 0x0054f6e0. ghidra + rizin + llvm-objdump + strings
145 0x0052e060 537 shell_expand_vertex24_triplets bootstrap thiscall inferred ghidra-headless 4 Sibling emitter for the same active presentation-batch record family; expands each 0x4c-byte packed source entry into three 0x18-byte vertex24 records in the caller-provided buffer. Each emitted record stores a vec3 at +0x00 a style dword from [this+0x43] at +0x0c and scalar slots at +0x10 and +0x14 while the output-count accumulator advances by count*3. ghidra + rizin
146 0x0052eb20 51 shell_read_optional_presentation_extents4 bootstrap thiscall inferred ghidra-headless 4 Reads an optional four-float extent block from the active presentation-batch record when byte flag [this+0x25] is set; copies dwords at +0x26 +0x2a +0x2e and +0x32 into caller outparams for the presentation-extents helper at 0x547d10. ghidra + rizin
147 0x0052eca0 43 shell_get_next_presentation_batch_record bootstrap thiscall inferred ghidra-headless 4 Returns the next 0x45-byte presentation-batch record for the active item family rooted at [this+0x14] if current index [this+0x21] plus one is still below the family count at [+0x14]; otherwise returns null. ghidra + rizin
148 0x00524780 1252 shell_emit_ranked_overlay_cell_items bootstrap thiscall inferred ghidra-headless 3 Processes one ranked-overlay cell list for 0x0052a2f0. It samples shell range thresholds through 0x00533180 and 0x00533160 filters cell items by distance and intensity derives an alpha-biased packed color from the caller input and emits accepted items into the current vertex24 span through layout helper 0x005468c0. ghidra + rizin + llvm-objdump
149 0x00533ba0 39 shell_grid_get_nearby_presentation_cell bootstrap thiscall inferred ghidra-headless 4 Returns one tile-grid cell from the nearby-presentation layer rooted at [this+0x1671]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1671]. ghidra + rizin + llvm-objdump
150 0x00533cd0 39 shell_grid_get_static_vertex24_cell bootstrap thiscall inferred ghidra-headless 4 Returns one tile-grid cell from the fixed-geometry vertex24 layer rooted at [this+0x167d]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x167d]. ghidra + rizin + llvm-objdump
151 0x00533db0 30 shell_grid_get_geographic_label_cell bootstrap thiscall inferred ghidra-headless 4 Returns one tile-grid cell from the geographic-label layer rooted at [this+0x1675]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1675]. ghidra + rizin + llvm-objdump
152 0x00533e30 32 shell_grid_get_animated_quad_cell bootstrap thiscall inferred ghidra-headless 4 Returns one tile-grid cell from the animated-quad presentation layer rooted at [this+0x1681]. The helper converts world coordinates into 16x16 tile coordinates multiplies by the grid width stored at [this+0x15d9] and indexes the cell-pointer table at [this+0x1681]. ghidra + rizin + llvm-objdump
153 0x00533e50 32 shell_grid_get_ranked_overlay_cell bootstrap thiscall inferred ghidra-headless 4 Returns one tile-grid cell from the ranked secondary overlay layer rooted at [this+0x1685]. The helper uses the same 16x16 tile addressing and grid width field at [this+0x15d9] as the other shell cell-grid accessors and currently feeds 0x0052a2f0. ghidra + rizin + llvm-objdump
154 0x00539fb0 924 shell_emit_geographic_label_frame_vertex24_records bootstrap thiscall inferred ghidra-headless 4 Expands the current geographic-label item into cached frame vertex24 records inside the caller buffer. The helper patches packed alpha into up to sixteen prebuilt 0x18-byte records copies additional 24-byte frame blocks from fixed item offsets and returns the emitted vertex count for the label border or backing geometry. ghidra + rizin + llvm-objdump
155 0x0053a440 14 shell_set_geographic_label_item_alpha bootstrap thiscall inferred ghidra-headless 4 Stores an 8-bit alpha input into the high-byte color field at [this+0x5b] for the current geographic-label item before frame or text emission. ghidra + rizin + llvm-objdump
156 0x0053a960 723 shell_emit_geographic_label_text_span bootstrap thiscall inferred ghidra-headless 4 Builds and emits one geographic-label text span for the current cell item. The helper calls the item vtable at +0x10 to materialize a null-terminated display string up to 0x12c bytes computes placement from item float fields and shell service state checks visibility through the shell bundle and forwards the resolved text payload into the presentation path through 0x005519f0. The item family aligns with gpdLabelDB and 2DLabel.imb rather than the parallel city assets. ghidra + rizin + llvm-objdump
157 0x00543f10 853 layout_state_bind_presentation_asset_bundle bootstrap thiscall inferred ghidra-headless 4 Initial bind-time asset loader for the layout state's presentation node at [this+0x25df]; pulls a fixed presentation bundle through the node vtable at +0x5c and +0x60 including standalone assets stored around 0x2643 0x2647 0x264b 0x264f 0x2653 0x265b 0x265f and 0x2663 plus a 64-entry asset bank at 0x31ab while advancing an internal asset-offset cursor at [this+0x2543]. ghidra + rizin
158 0x00554830 142 attachment_object_init_named_asset bootstrap thiscall inferred ghidra-headless 3 Initializes one named attachment object from a caller-supplied asset string and placement parameters. The helper copies the asset name into the local object buffer at [this+0x10] stores attachment selectors at [this+0x130] and [this+0x138] optionally derives a cached scale pair at [this+0x120] and [this+0x124] and then finalizes object state through 0x005545d0. ghidra + rizin + llvm-objdump
159 0x005455e0 224 layout_state_set_slot_triplet_lo bootstrap thiscall inferred ghidra-headless 4 Updates the first three cached per-slot presentation scalars in the 24-byte slot table at [this+0x2597+slot*24]. In notify mode it compares against the cached values and forwards only changed fields into the bound presentation node through vtable slot +0xfc with subproperty ids 1 through 3. ghidra + rizin + llvm-objdump
160 0x005456d0 240 layout_state_set_slot_triplet_hi bootstrap thiscall inferred ghidra-headless 4 Updates the second three cached per-slot presentation scalars in the same 24-byte slot table at [this+0x2597+slot*24]. In notify mode it compares against the cached values and forwards only changed fields into the bound presentation node through vtable slot +0xfc with subproperty ids 4 through 6. ghidra + rizin + llvm-objdump
161 0x005458f0 169 layout_state_read_segment_record_window bootstrap thiscall inferred ghidra-headless 4 Gates the 32-byte segment-record table at [this+0x2643]; queries record bounds then copies a start-to-end or wrapped window into scratch storage at [this+0x2657] through vtable slot +0x2c while toggling byte flag [this+0x254e]. The downstream shell path treats each 0x20-byte record as two vec3 blocks plus two trailing scalars. ghidra + rizin
162 0x005459a0 69 layout_state_read_segment_record_block bootstrap thiscall inferred ghidra-headless 4 Reads one 32-byte-indexed segment-record block from the same [this+0x2643] table into scratch storage at [this+0x2657] through vtable slot +0x2c using a fixed 0x2800-byte transfer span. ghidra + rizin
163 0x00545b10 57 layout_state_read_vertex24_block bootstrap thiscall inferred ghidra-headless 4 Reads one 24-byte-indexed vertex block from the presentation table at [this+0x2647] through vtable slot +0x2c using index*24 addressing and returns the copied pointer through a stack outparam. The downstream shell emitter treats each record as vec3 plus a style dword plus two trailing scalars. ghidra + rizin
164 0x00545b50 59 layout_state_read_vertex24_window bootstrap thiscall inferred ghidra-headless 4 Copies a window between two 24-byte vertex indices from [this+0x2647] into scratch storage at [this+0x2657] through vtable slot +0x2c using index*24 addressing and a fixed 0x1800-byte transfer span. The downstream shell emitter treats each record as vec3 plus a style dword plus two trailing scalars. ghidra + rizin
165 0x00545c50 67 layout_state_commit_vertex24_span bootstrap thiscall inferred ghidra-headless 4 Converts a start and end vertex index range into a triplet count by dividing the delta by three accumulates that count at [this+0x3711] and notifies the bound presentation node at [this+0x25df] through vtable slot +0x118 with primitive-type argument 4. ghidra + rizin
166 0x00546a30 333 layout_state_rebuild_variant_asset_cache bootstrap thiscall inferred ghidra-headless 3 Releases any loaded entries in the 64-slot presentation asset bank rooted at 0x31ab then rebuilds the paired-key metadata table at 0x266b tracking active entries count at [this+0x2667] and sibling or reuse links for later keyed lookups. ghidra + rizin
167 0x005467a0 50 layout_state_enable_presentation_gate bootstrap thiscall inferred ghidra-headless 4 Ensures the presentation node gate property 0x1c is enabled once for the layout state when the template flag at [[this+0x83c]+0x2e] permits it by setting [this+0x2549] and forwarding the toggle into the node at [this+0x25df]. ghidra + rizin
168 0x00547d10 288 layout_state_apply_presentation_extents4 bootstrap thiscall inferred ghidra-headless 4 Applies a four-float extent or quad block onto presentation property 0x18 for the bound node at [this+0x25df]. If all four inputs are nonpositive it clears the property through vtable slot +0xfc; otherwise it builds a 0x10-field stack block with the four caller values and a unit scalar then commits it through node slots +0xfc and +0x94. ghidra + rizin + llvm-objdump
169 0x00547f20 177 layout_state_apply_gamma_ramp_scalar bootstrap thiscall inferred ghidra-headless 4 Builds a 256-entry three-channel gamma-ramp buffer from the caller scalar and uploads it through vtable slot +0x48 on the bound presentation node at [this+0x25df]. The helper clamps each 16-bit ramp entry stores the accepted scalar in the subordinate state block at [[this+0x83c]+0x2f] and respects shell capability guards under 0x006d4024 before touching the display device. ghidra + rizin + llvm-objdump
170 0x00548da0 1328 layout_state_refresh_presentation_batches bootstrap thiscall inferred ghidra-headless 4 Walks the active presentation-batch list and refreshes the bound node state for each selected item. The routine applies batch extents through 0x00547d10 pushes style and gate properties including packed color property 0x3c updates per-slot triplets through 0x005455e0 and 0x005456d0 and emits segment-record or vertex24 spans from the current batch family before advancing to the next record. ghidra + rizin + llvm-objdump
171 0x005492d0 3747 layout_state_probe_d3d8_capabilities bootstrap thiscall inferred ghidra-headless 4 Creates a Direct3D8 probe object and walks adapter or device capability queries for the layout-state presentation path. The routine caches probed texture-memory style fields into shell globals under 0x006d4024 including the values later reported as Texture SRAM and Texture VRAM consults the shell memory-budget helpers 0x0051fa40 and 0x0051fa60 refreshes the gamma ramp through 0x00547f20 when needed and assigns a local renderer capability tier at [this+0x04]. ghidra + rizin + llvm-objdump + strings
172 0x0054a280 626 layout_state_apply_presentation_properties bootstrap thiscall inferred ghidra-headless 4 Pushes visibility color and mode-dependent scalar properties from the layout state into the bound presentation node at [this+0x25df]; toggles gate property 0x1c writes packed color property 0x22 from bytes 0x2510..0x2512 updates mode properties 0x23 through 0x26 from template flags and caller-supplied scalars and caches the leading scalar at [this+0x25b3]. ghidra + rizin
173 0x0054bab0 89 layout_state_bind_segment_record_table bootstrap thiscall inferred ghidra-headless 4 Binds the current 32-byte segment-record table at [this+0x2643] onto the presentation node if it changed since the last bind. The helper drives node property 0x112 through vtable slots +0x130 and +0x14c with record size 0x20 and clears the local dirty byte at [this+0x263b]. ghidra + rizin + llvm-objdump
174 0x0054bb70 90 layout_state_bind_vertex24_table bootstrap thiscall inferred ghidra-headless 4 Binds the current 24-byte vertex24 table at [this+0x2647] onto the presentation node if it changed since the last bind. The helper drives node property 0x142 through vtable slots +0x130 and +0x14c with record size 0x18 and clears the local dirty byte at [this+0x263b]. ghidra + rizin + llvm-objdump
175 0x0054bc10 592 shell_init_layout_state_defaults bootstrap thiscall inferred ghidra-headless 4 Initializes the large subordinate layout-state object allocated by 0x0055e2b0; seeds default float and flag fields points [this+0x83c] at a shell-bundle template block near 0x006d4024+0x11468a optionally copies a 0x72c-byte preset table and notifies the shell bundle service at [0x006d4024+0x28]. ghidra + rizin
176 0x0054bea0 1399 layout_state_apply_interpolated_pose bootstrap thiscall inferred ghidra-headless 4 Applies an interpolated pose and palette sample on the subordinate layout-state object using the controller counters passed by callers; clamps the time window blends preset tables at offsets 0x840 through 0x86f updates color bytes at 0x2510 through 0x2512 invokes the bound presentation node at [this+0x25df] and finishes through 0x0054a280. ghidra + rizin
177 0x0054f640 83 shell_step_global_presentation_phase_scalar shell cdecl inferred ghidra-headless 2 Steps the shared presentation-phase scalar stored at 0x00d93850 downward by a small constant then clamps the returned value against fixed lower-bound constants. Callout-marker world-anchor and other presentation helpers use this as a common time-varying scalar after one of the nearby setters has seeded the global phase. ghidra + rizin + llvm-objdump
178 0x0054f700 12 shell_set_global_presentation_phase_scalar shell cdecl inferred ghidra-headless 3 Stores one caller-supplied float into the shared presentation-phase scalar at 0x00d93850. Mouse-cursor geographic-label and other presentation helpers seed this global before later batch or marker helpers consume it through 0x0054f640. ghidra + rizin + llvm-objdump
179 0x0054f710 729 shell_queue_callout_segment_marker shell cdecl inferred ghidra-headless 2 Queues one short world-space callout segment or marker packet using the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34]. The helper derives scaled endpoint deltas from the caller inputs applies flag-controlled clamps from arg_14h and emits three type-0x01 deferred messages through shell_enqueue_deferred_message_type1. ghidra + rizin + llvm-objdump
180 0x0054f9f0 281 shell_queue_callout_frame_segments shell cdecl inferred ghidra-headless 4 Builds a four-segment callout frame around one projected extent box. The helper samples the same shell zoom and reciprocal scale tables under 0x006d4024 computes the four box legs from the caller extent inputs and emits each side through shell_queue_callout_segment_marker. ghidra + rizin + llvm-objdump
181 0x0054fb10 699 shell_queue_callout_leader_path shell cdecl inferred ghidra-headless 3 Builds one longer world-space callout leader path between two points. It derives slope and angle terms from the caller inputs recursively reuses itself or 0x0054f710 for shorter segments chooses style branches from distance and flag tests and enqueues the resulting type-0x01 deferred messages. shell_publish_text_callout_presentation uses this helper for text-associated leader geometry. ghidra + rizin + llvm-objdump
182 0x0054fdd0 256 shell_queue_presentation_batch_pair shell cdecl inferred ghidra-headless 2 Queues a two-record presentation batch through the shell deferred-message path. One branch emits a single trailing type-0x04 record while the other brackets two type-0x04 payload posts with direct type-0x05 and type-0x06 begin-end records; both legs seed their animated scalar through shell_step_global_presentation_phase_scalar before routing through the shell bundle at 0x006d4024. ghidra + rizin + llvm-objdump
183 0x0054fed0 440 shell_queue_presentation_batch_quad shell cdecl inferred ghidra-headless 2 Queues a four-record presentation batch through the same deferred-message family. It posts a type-0x05 begin record emits four type-0x04 payload records with refreshed phase scalars from shell_step_global_presentation_phase_scalar and finally closes the batch with a type-0x06 end record. The current high-level callers build this from four related point or extent tuples. ghidra + rizin + llvm-objdump
184 0x005519f0 902 shell_publish_text_callout_presentation shell cdecl inferred ghidra-headless 3 Publishes one styled text or callout presentation payload through the active shell bundle at 0x006d4024. It accepts text placement and style inputs conditionally emits a leader path through 0x0054fb10 allocates backing text resources through 0x0051f0b0 and 0x00543c10 sets presentation flags from the mode arguments and finalizes the payload through 0x0051fc20. Geographic-label text and mouse-cursor presentation both feed this helper. ghidra + rizin + llvm-objdump + strings
185 0x00552160 56 world_anchor_measure_projected_half_width shell cdecl inferred ghidra-headless 3 Measures one absolute projected half-width-like extent from the caller world-anchor object. It chooses the X or Z span depending on orientation byte [this+0x24] scales by the owner coefficients at +0x2e or +0x32 multiplies by local width scalar [this+0x1c] and returns the absolute result for later cursor or marker placement code. ghidra + rizin + llvm-objdump
186 0x005521a0 56 world_anchor_measure_projected_half_height shell cdecl inferred ghidra-headless 3 Measures one absolute projected half-height-like extent from the caller world-anchor object. It chooses the complementary axis span using the same orientation byte [this+0x24] scales by owner coefficients at +0x2e or +0x32 multiplies by local height scalar [this+0x20] and returns the absolute result for later cursor or marker placement code. ghidra + rizin + llvm-objdump
187 0x005521e0 894 world_anchor_project_screen_extent_pair shell cdecl inferred ghidra-headless 3 Projects one world-anchor object into a paired screen-space extent result. The helper samples the shell zoom table under 0x006d4024 computes integer-scaled axis spans from the anchor geometry converts them through multiple clamp or reciprocal stages and writes two output integers through the caller pointers before later marker builders use the results for anchor presentation sizing. ghidra + rizin + llvm-objdump
188 0x00552560 916 shell_queue_world_anchor_marker shell cdecl inferred ghidra-headless 3 Builds one world-anchor marker packet from the caller point object and optional scale or style inputs. It samples anchor extents from the object fields converts them through 0x0053dde0 0x0053ddf0 and world_anchor_project_screen_extent_pair consults the shell zoom table rooted at [0x006d4024+0x11421e] and [0x006d4024+0x34] and finally enqueues one type-0x01 deferred message through shell_enqueue_deferred_message_type1. mouse_cursor_update_frame_state uses it for one branch of cursor world-relative presentation. ghidra + rizin + llvm-objdump
189 0x00552900 1304 shell_queue_projected_world_anchor_quad shell cdecl inferred ghidra-headless 3 Builds one oriented projected quad around the caller world-anchor object. It derives four projected corner points from the anchor extents and orientation computes edge and diagonal lengths through 0x0051db80 samples the shared presentation phase through shell_step_global_presentation_phase_scalar refines screen-space bounds through world_anchor_project_screen_extent_pair and finally emits two type-0x04 deferred-message posts through shell_enqueue_deferred_message_type4. ghidra + rizin + llvm-objdump
190 0x00554d70 248 billboard_item_build_anchor_point_cache bootstrap thiscall inferred ghidra-headless 3 Builds or refreshes the cached point list for one billboard item at [this+0x1dd]. When source points exist at [this+0x10] it transforms them through the owner object matrix near [this+0x0c]+0xce; otherwise it seeds a one-point fallback from the baked vector at [this+0xfe..0x106]. ghidra + rizin + llvm-objdump
191 0x00554e70 680 shell_emit_ranked_sprite_billboard_item bootstrap thiscall inferred ghidra-headless 4 Emits one ranked sprite-billboard item into the current vertex24 span. The helper computes a distance-weighted fade against shell and world state stores the derived scalar at [item+0xdc] and then walks either the item's linked child list at [item+0x4] or the cached anchor list at [item+0x1dd] to write textured quad geometry through 0x005662a0. ghidra + rizin + llvm-objdump
192 0x00555740 49 billboard_item_refresh_child_sprite_colors bootstrap thiscall inferred ghidra-headless 3 Refreshes packed child-sprite colors for one billboard item by iterating the linked child list at [this+0x4] recomputing each child color through 0x005554f0 and storing the 24-bit result at [child+0x70]. ghidra + rizin + llvm-objdump
193 0x00555780 1739 sprite_billboard_spawn_particle_instance bootstrap thiscall inferred ghidra-headless 4 Builds one emitted sprite-billboard instance from the template item. It randomizes local offsets through fields [this+0x7c..0x90] optionally samples anchor points from the owner matrix or cached path data chooses atlas uv bounds from [this+0x110..0x124] applies scale and fade terms from [this+0x94..0x108] recomputes packed colors through 0x005554f0 and finalizes the instance through 0x00565e80 and 0x00565f40. ghidra + rizin + llvm-objdump
194 0x00555e50 1808 sprite_billboard_update_particle_emitter bootstrap thiscall inferred ghidra-headless 4 Advances one sprite-billboard emitter template and spawns new instances through 0x00555780. The routine updates emitter clocks and travel bounds in [this+0x68..0xc8] applies burst or repeat controls through [this+0x1ed..0x1f9] walks up to [this+0x34] spawn lanes resolves anchor positions from cached or owner-derived points and refreshes the active emitter origin at [this+0xc0] and [this+0xc4]. ghidra + rizin + llvm-objdump
195 0x0055d430 6 system_get_total_physical_memory_bytes support cdecl inferred ghidra-headless 4 Returns the cached total physical-memory byte count from the shared MEMORYSTATUS block at 0x00d9754c. The graphics preset bundle uses this value as one of its coarse runtime capability probes after the cache has been refreshed through GlobalMemoryStatus nearby. ghidra + rizin + llvm-objdump
196 0x0055d440 17 system_refresh_available_physical_memory_bytes support cdecl inferred ghidra-headless 4 Refreshes the shared MEMORYSTATUS block at 0x00d97548 through GlobalMemoryStatus and returns the resulting available physical-memory byte count from dwAvailPhys. This is the active memory-availability probe companion to 0x0055d430. ghidra + rizin + llvm-objdump + strings
197 0x0055d460 81 os_is_non_nt_platform support cdecl inferred ghidra-headless 4 Calls GetVersionExA and returns true only when the platform id is not VER_PLATFORM_WIN32_NT. The graphics preset bundle inverts this result into an NT-family capability flag before finalizing several display-runtime bytes under 0x006d4024. ghidra + rizin + llvm-objdump + strings
198 0x0055d8d0 138 display_get_primary_adapter_descriptor support cdecl inferred ghidra-headless 4 Enumerates display devices through USER32.EnumDisplayDevicesA until it finds the primary adapter flag then copies the adapter DeviceString field into the global buffer at 0x00d97448 and returns that buffer. When enumeration fails it leaves the descriptor empty and still returns the same shared buffer pointer. The graphics preset matcher at 0x00484a60 consumes this descriptor text directly. ghidra + rizin + llvm-objdump + strings
199 0x005a0f70 209 stream_cipher_xor_in_place support cdecl inferred rizin 4 Applies one stateful stream-cipher pass in place over the caller buffer in ECX for the caller byte count in EDX using the 0x102-byte cipher state block passed on the stack. The helper mutates the two state bytes at offsets `+0x100` and `+0x101` and uses the 0x100-byte permutation table at the start of the state block to XOR every byte in the buffer. Current grounded callers are the multiplayer transport text-stream receive and send paths. rizin + llvm-objdump
200 0x005a18a0 292 string_copy_bounded_zerofill support cdecl inferred ghidra-headless 4 Shared bounded string-copy helper that copies up to count bytes from source to destination stops after the first NUL byte and zero-fills the remaining span before returning the destination pointer. The graphics preset matcher uses it to stage the primary adapter descriptor into a local probe buffer before substring token scans ghidra + rizin + llvm-objdump
201 0x00556620 305 sprite_billboard_manager_reset bootstrap thiscall inferred ghidra-headless 3 Releases the shared sprite-billboard manager state including emitter slots at [this+0x10] queued templates at [this+0x18] and owned resource handles or containers before zeroing the manager pointers again. ghidra + rizin + llvm-objdump
202 0x00556770 420 sprite_billboard_manager_init_pools bootstrap thiscall inferred ghidra-headless 4 Initializes the shared sprite-billboard manager when the shell first needs emitter templates. It allocates the long-lived emitter arrays and container objects at [this+0x10] [this+0x18] [this+0x8] [this+0x4] and [this+0x0] with a default capacity of 0xc350 slots unless the caller overrides it. ghidra + rizin + llvm-objdump
203 0x00556920 814 sprite_billboard_init_emitter_template bootstrap thiscall inferred ghidra-headless 4 Initializes one sprite-billboard emitter template from optional source geometry color flags and atlas bounds. It copies source points or seeds a fallback anchor path stores owner position seeds default fade and timing fields across [this+0x94..0xd8] computes atlas uv steps from [this+0xe0..0xec] into [this+0x110..0x124] and optionally prewarms the spawn list through 0x00554ce0 when the caller flags request it. ghidra + rizin + llvm-objdump
204 0x00556c50 143 sprite_billboard_manager_create_template_node bootstrap thiscall inferred ghidra-headless 4 Allocates or reuses one manager node then creates a fresh sprite-billboard template through 0x00556920 with flag 0x400 forced on. The helper stores the new template at [node+0x4] and queues the node into the manager container at [this+0x8]. ghidra + rizin + llvm-objdump
205 0x00556ce0 160 sprite_billboard_manager_clone_template_node bootstrap thiscall inferred ghidra-headless 4 Looks up one existing manager node and either returns its current template or clones a new sprite-billboard template from it through 0x00556920. On the first clone path it prewarms the source template through 0x00554ce0 and then queues the new node into the manager container at [this+0x4]. ghidra + rizin + llvm-objdump
206 0x00556e10 54 intrusive_queue_push_back support cdecl inferred ghidra-headless 4 Allocates one intrusive-queue node then appends the caller payload pointer to the tail of the container. The helper writes the payload at [node+0x00] links the previous tail through [node+0x04] and [tail+0x08] updates the head and tail slots when needed and increments the queued-node count at [this+0x0c]. ghidra + rizin + llvm-objdump
207 0x00556ef0 6 intrusive_queue_rewind_iterator support cdecl inferred ghidra-headless 4 Resets one intrusive-queue iterator by copying the container head pointer at [this+0x00] into the current-iterator slot at [this+0x04]. The helper is reused broadly across shell presentation and gameplay container walkers before repeated next-node calls. ghidra + rizin + llvm-objdump
208 0x00556f00 19 intrusive_queue_next_iterator_node support cdecl inferred ghidra-headless 4 Returns the current intrusive-queue iterator node from [this+0x04] then advances the iterator to the linked next pointer at [node+0x08]. When the iterator is exhausted it returns null without mutating any payload state. ghidra + rizin + llvm-objdump
209 0x00556f90 13 intrusive_queue_peek_tail_payload support cdecl inferred ghidra-headless 4 Returns the payload pointer stored in the current tail node at [this+0x08]. When the container is empty it returns null without mutating the queue state. ghidra + rizin + llvm-objdump
210 0x00557010 159 intrusive_queue_clear_owned_nodes support cdecl inferred ghidra-headless 3 Specialized intrusive-queue clear path for containers with an auxiliary owner or context pointer at [this+0x14]. It iterates the owned node chain through the queue iterator helpers releases nested payload state unlinks each node and decrements the queue count before returning to the outer container clear helper. ghidra + rizin + llvm-objdump
211 0x005570b0 80 intrusive_queue_clear_and_release support cdecl inferred ghidra-headless 4 Clears and releases every node in one intrusive queue container. When [this+0x14] is present it routes through intrusive_queue_clear_owned_nodes; otherwise it walks the linked nodes directly releases them zeroes the head iterator and tail slots and resets the queued-node count at [this+0x0c]. ghidra + rizin + llvm-objdump
212 0x00559520 166 surface_init_rgba_pixel_buffer support thiscall inferred ghidra-headless 3 Initializes or refreshes a small 0xec-byte RGBA pixel-buffer object from caller-supplied image data and dimensions. On first use it allocates the backing object through 0x0053b070 stores width and height at [this+0xa2] and [this+0xa6] seeds the inner surface through 0x00543980 and 0x00541970 then copies width*height*4 bytes from the source buffer before finalizing through 0x005438d0. Current callers use it from the PaintTerrain preview path and the Multiplayer.win map-preview branch. ghidra + rizin + llvm-objdump + strings
213 0x00565110 600 shell_rebuild_layout_state_and_optional_texture_report shell thiscall inferred ghidra-headless 3 Rebuilds the active shell layout-state branch when the current mode requires a deeper reset and optionally publishes the texture budget report through 0x00527650. The routine checks the current layout mode through 0x00545e00 tears down and recreates layout-state services through 0x0055dd80 and 0x0055e2b0 optionally notifies global shell services and when the caller flag is set emits the report then commits one layout refresh step through 0x00545d60. ghidra + rizin + llvm-objdump + strings
214 0x0058d7a0 55 multiplayer_transport_set_local_name shell thiscall inferred ghidra-headless 3 Updates the local identity string stored in the session-event transport object. When the transport is already configured through [this+0x44] and the incoming name pointer is non-null and non-empty it copies up to 0x40 bytes into [this+0x04] clears byte [this+0x43] and then forwards the same name into the lower transport update path through 0x0058f330. ghidra + rizin + llvm-objdump
215 0x0058d830 40 multiplayer_transport_disconnect shell thiscall inferred ghidra-headless 3 Disconnects the session-event transport object from its current live route. The helper flips the internal active state through 0x005965d0 and 0x005961b0 calls the shared teardown block at 0x0058d810 and finally clears byte [this+0x60] and the copied local name at [this+0xaf4]. ghidra + rizin + llvm-objdump
216 0x0058d860 59 multiplayer_transport_release_worker_and_reset_runtime_state shell cdecl inferred rizin 3 Small runtime-reset wrapper for the outer session-event transport object. When the owned worker pointer at [this] is present it first tears that worker down through multiplayer_transport_worker_shutdown_gracefully then clears the worker pointer the configured flag byte at [this+0x04] the text-stream owner slots at [this+0x44] and [this+0x48] reruns 0x00593370 and the shared reset block at 0x0058d810 and finally clears the live route and deferred-runtime fields at [this+0x180c] [this+0x1810] and [this+0x1edc]. rizin + llvm-objdump
217 0x0058d960 7 multiplayer_transport_select_status_route shell thiscall inferred ghidra-headless 3 Thin route-selector wrapper for the session-event transport. It forwards the requested small route id in EDX into multiplayer_transport_set_mode_q_flag which updates [this+0x560] formats the underlying `MODE %s -q` or `MODE %s +q` command text and reconfigures the transport-side callback plumbing. ghidra + rizin + llvm-objdump
218 0x0058d970 89 multiplayer_transport_subscribe_field_callback_set shell thiscall inferred ghidra-headless 3 Registers one field-subscription callback set on the session-event transport. When the transport is active byte [this+0x60] is set it stores the caller metadata at [this+0x176c] and [this+0x1770] then forwards the field-id list string callback and context into multiplayer_transport_register_field_subscription_bundle; on failure it falls back through multiplayer_transport_enqueue_field_snapshot_record. ghidra + rizin + llvm-objdump
219 0x0058d9e0 55 multiplayer_transport_send_selector_text shell thiscall inferred ghidra-headless 3 Sends one caller-supplied text pointer through a selector-specific transport slot. The helper looks up the selector entry from the handler table rooted at [this+0x390] and when both the text pointer and slot are valid forwards the string plus caller flag into the lower send helper at 0x0058e7e0 using the descriptor block at [this+0x80+selector*0x101]. ghidra + rizin + llvm-objdump
220 0x0058da60 75 multiplayer_transport_register_selector_callback shell thiscall inferred ghidra-headless 3 Registers or dispatches one selector callback against the transport slot table rooted at [this+0x390]. When the selected slot is absent it directly invokes the supplied callback with mode -1 and null payloads; otherwise it packages the caller context on the stack and walks the registered slot through 0x00594ac0 using helper 0x0058da20. ghidra + rizin + llvm-objdump
221 0x0058db00 23 multiplayer_transport_request_status_pump shell thiscall inferred ghidra-headless 3 Marks the session-event transport status path dirty by setting [this+0xb44] to 1 and then calling multiplayer_transport_service_status_pump when the transport is active. ghidra + rizin + llvm-objdump
222 0x0058db20 53 multiplayer_transport_clear_status_pump shell thiscall inferred ghidra-headless 3 Clears the session-event transport status-pump flag at [this+0xb44] then reruns multiplayer_transport_service_status_pump. When the transport still owns the auxiliary object at [this+0xaf0] it follows up with either 0x00597370 or 0x00597350 depending on whether selector slot [this+0x398] is present. ghidra + rizin + llvm-objdump
223 0x0058db60 5 multiplayer_transport_force_status_flush shell thiscall inferred ghidra-headless 3 Tail-call wrapper into 0x00597370 for the active session-event transport object. The shell flush path uses it immediately before multiplayer_transport_flush_and_maybe_shutdown. ghidra + rizin + llvm-objdump
224 0x0058dc30 22 multiplayer_transport_is_route_mode_active_nonterminal shell cdecl inferred ghidra-headless 3 Tiny predicate over the route-mode field at [this+0x18b8]. It returns false when the mode is zero or terminal mode `5` and true for the other active route modes. Current grounded callers use it to decide whether route callbacks can run inline or whether route work must be re-enqueued. ghidra + rizin + llvm-objdump
225 0x0058de90 95 multiplayer_transport_shutdown shell thiscall inferred ghidra-headless 3 Shuts down the session-event transport object and either marks deferred-close state or tears the object down immediately. It preserves [this+0x178c] across the common shutdown helper at 0x0058de50 disconnects active routes through multiplayer_transport_disconnect and when no outstanding work remains drops into the reset path at 0x0058d8a0; otherwise it latches deferred-close flag [this+0x1ee0]. ghidra + rizin + llvm-objdump
226 0x0058def0 40 multiplayer_transport_flush_and_maybe_shutdown shell thiscall inferred ghidra-headless 3 Flushes the transport state through 0x0058d8d0 with selector -1 and when deferred-close flag [this+0x1ee0] is set and the outstanding-work count at [this+0x1808] has reached zero immediately falls into multiplayer_transport_shutdown. ghidra + rizin + llvm-objdump
227 0x0058df20 131 multiplayer_transport_submit_text_record shell thiscall inferred ghidra-headless 3 Submits one prepared text record through the session-event transport using a caller-supplied callback wrapper. The helper allocates a transient transport record through multiplayer_transport_next_work_sequence sends it through multiplayer_transport_try_submit_text_record_fastpath and when that fast path declines packages the caller callback mode and payload into 0x00593170. When the caller requested immediate draining it also services the transport queue through 0x0058d8d0 and 0x0058d720 and may fall into multiplayer_transport_shutdown when deferred close is armed. ghidra + rizin + llvm-objdump
228 0x0058e100 230 multiplayer_transport_publish_fixed_token_message shell thiscall inferred ghidra-headless 3 Publishes one fixed-token status message through selector `2` on the session-event transport. The helper requires the transport to be active and fully configured builds a formatted status line from the caller token plus internal fields such as [this+0x282] and [this+0x54] sends that line through multiplayer_transport_send_selector_text sets [this+0xb44] to 1 reruns the status pump and when appropriate nudges the downstream mode helper at 0x00595650 or the auxiliary object paths 0x00597350 and 0x00597370. ghidra + rizin + llvm-objdump + strings
229 0x0058e200 211 multiplayer_transport_register_callback_table shell thiscall inferred ghidra-headless 3 Registers or refreshes the session-event transport callback table and descriptor block. When the transport is not yet fully configured it copies the local name into [this+0x04] stores the callback-table pointers at [this+0x4c] and [this+0x5c] sets [this+0x44] active and forwards the descriptor block plus caller metadata into multiplayer_transport_attach_callback_table_descriptor. It then routes the resolved table through multiplayer_transport_dispatch_callback_table_binding and optionally drains queued work through 0x0058d8d0 and 0x0058d720 before honoring deferred-close state. ghidra + rizin + llvm-objdump
230 0x0058e2e0 38 multiplayer_transport_reset_and_maybe_shutdown shell thiscall inferred ghidra-headless 3 Resets the common transport state through 0x0058de50 and when deferred-close flag [this+0x1ee0] is armed and the outstanding-work count at [this+0x1808] has reached zero immediately falls into multiplayer_transport_shutdown. ghidra + rizin + llvm-objdump
231 0x0058e370 33 multiplayer_transport_is_request_pending shell cdecl inferred ghidra-headless 3 Returns true while the caller transport request still appears in either the queued request collection at [this+0x550] or the secondary active-work collection checked through 0x0059c540. Immediate-drain callers use it as the loop predicate after pumping queued text and sleeping for 10 ms. ghidra + rizin + llvm-objdump
232 0x0058e3f0 137 multiplayer_transport_drain_request_text_queue shell cdecl inferred ghidra-headless 3 Immediate-drain helper for one transport request. When request kind [req+0x20] is `1` it walks queued transport text lines under [this+0x1c] republishes them through 0x0059b790 and notifies the small observer table through 0x0058e310 until the queue is empty. When request kind `2` drains it also publishes `Disconnected`. Both paths refresh timeout state through 0x00598030 and finish by forwarding the request into 0x0059c470. ghidra + rizin + llvm-objdump + strings
233 0x0058e480 105 multiplayer_transport_worker_shutdown_gracefully shell cdecl inferred rizin 3 Graceful shutdown wrapper for one multiplayer transport worker. If the callback object at `[this+0x538]` and its owner slot `[this+0x544]` are present it first emits a final owner notification through the callback vtable using fallback text at `0x005c87a8`. When the owned text-stream socket at `[this+0x1c]` is still live it appends `QUIT :Later!` through multiplayer_transport_text_stream_append_crlf_line and services one I/O step through multiplayer_transport_text_stream_service_io before destroying the registered-name store at `[this+0x548]`, the pending-template dispatch store at `[this+0x54c]`, the text-stream object at `[this+0x1c]`, and finally the worker backing block itself. rizin + llvm-objdump + strings
234 0x0058e650 80 multiplayer_transport_sanitize_identifier shell cdecl inferred ghidra-headless 4 Normalizes a caller-supplied identifier string into the destination buffer by replacing leading punctuation and any later disallowed characters with underscores while preserving acceptable bytes from the source. Current grounded callers use it for the randomized `RT3Player%d` retry name and for locally submitted session-event text records. ghidra + rizin + llvm-objdump + strings
235 0x0058e6b0 98 multiplayer_transport_set_mode_q_flag shell thiscall inferred ghidra-headless 4 Updates the transport mode-q flag tracked at [this+0x560]. When the requested value changes it formats either `MODE %s -q` or `MODE %s +q` against the active name buffer at [this+0x36c] stores the new flag and for mode `0` refreshes the downstream callback plumbing through 0x0059e070 and 0x0059de00 using helper 0x0058e6a0. ghidra + rizin + llvm-objdump + strings
236 0x0058e8c0 37 multiplayer_transport_publish_topic_status_line shell thiscall inferred ghidra-headless 3 Formats and publishes one `TOPIC %s :%s` status line through the active transport text buffer at [this+0x1c]. When the caller text is null it falls back to the shared empty sample at 0x005c87a8. Current grounded caller is multiplayer_transport_handle_names_query_response. ghidra + rizin + llvm-objdump + strings
237 0x0058e8f0 56 multiplayer_transport_publish_mode_key_status_line shell thiscall inferred ghidra-headless 3 Formats and publishes one mode-key status line through the active transport text buffer at [this+0x1c]. Depending on the caller flag it emits either `MODE %s +k %s` or `MODE %s -k %s`. Current grounded caller is multiplayer_transport_handle_bound_route_request. ghidra + rizin + llvm-objdump + strings
238 0x0058e930 53 multiplayer_transport_publish_mode_level_status_line shell thiscall inferred ghidra-headless 3 Formats and publishes one mode-level status line through the active transport text buffer at [this+0x1c]. Depending on whether the caller level value is nonzero it emits either `MODE %s +l %d` or `MODE %s -l`. Current grounded caller is multiplayer_transport_handle_names_query_response. ghidra + rizin + llvm-objdump + strings
239 0x0058e970 36 multiplayer_transport_invoke_registered_name_query_callback shell cdecl inferred ghidra-headless 3 Small callback shim used by the registered-name fast path. It loads the caller callback object from the dispatch frame and invokes its entry method with success flag `1`; the queried sample string; and the collected callback-entry arrays produced by multiplayer_transport_collect_registered_name_callback_entries. ghidra + rizin + llvm-objdump
240 0x0058e9a0 177 multiplayer_transport_submit_names_query_with_callback shell thiscall inferred ghidra-headless 3 Builds and submits one `NAMES %s` query against the active transport text buffer at [this+0x1c]. When the caller sample is already present it bypasses transport submission through multiplayer_transport_dispatch_registered_name_query_fastpath. Otherwise it validates the sample through multiplayer_transport_has_registered_name packages the request through multiplayer_transport_enqueue_names_query_record and when immediate draining is requested loops through multiplayer_transport_drain_request_text_queue system_sleep_milliseconds and multiplayer_transport_is_request_pending. Current grounded callers are multiplayer_transport_handle_bound_route_request and multiplayer_transport_handle_selector_text_route_request. ghidra + rizin + llvm-objdump + strings
241 0x0058eb70 212 multiplayer_transport_append_getkey_command shell cdecl inferred rizin 3 Formats one `GETKEY %s %s 0 :` command into a temporary 0x200-byte stack buffer and appends it to the owned transport text stream through multiplayer_transport_text_stream_append_crlf_line. After the fixed header it walks the caller string-vector argument and appends each additional item separated by backslashes. Current grounded caller is the synchronous submit wrapper at 0x0058ec50. rizin + llvm-objdump + strings
242 0x0058ec50 140 multiplayer_transport_submit_getkey_command_and_wait shell cdecl inferred rizin 3 Synchronous `GETKEY` submit wrapper for the multiplayer transport worker. It resolves the query name from the caller string or falls back to [this+0x36c] primes one transient request through 0x0058eb30 emits the command text through multiplayer_transport_append_getkey_command and then loops through multiplayer_transport_drain_request_text_queue system_sleep_milliseconds and multiplayer_transport_is_request_pending until the request completes. rizin + llvm-objdump + strings
243 0x0058ece0 197 multiplayer_transport_append_setchankey_or_setckey_command shell cdecl inferred rizin 3 Formats either `SETCHANKEY %s :` or `SETCKEY %s %s :` into a temporary 0x200-byte stack buffer and appends the resulting line to the owned transport text stream through multiplayer_transport_text_stream_append_crlf_line. The two-token `SETCKEY` form is selected when the optional caller key string at arg_210h is present and non-empty; otherwise the helper emits the simpler channel-key form. rizin + llvm-objdump + strings
244 0x0058edb0 367 multiplayer_transport_append_setchankey_pair_list_command shell cdecl inferred rizin 2 Builds one larger backslash-delimited channel-key payload and appends it to the owned transport text stream through multiplayer_transport_text_stream_append_crlf_line. The helper formats normalized `\\%s\\%s` pair fragments in a 0x200-byte stack buffer converts backslashes to forward slashes in one staging path handles wildcard samples through the `*` token at 0x005e1e1c and is the main text builder beneath the synchronous submit wrapper at 0x0058ef20. rizin + llvm-objdump + strings
245 0x0058ef20 199 multiplayer_transport_submit_setchankey_pair_list_command_and_wait shell cdecl inferred rizin 2 Synchronous channel-key submit wrapper for the multiplayer transport worker. It primes one transient request through 0x0058eb30 emits the larger backslash-delimited key payload through multiplayer_transport_append_setchankey_pair_list_command dispatches the caller result path through 0x005983b0 or 0x005984c0 depending on the staged optional arguments and then loops through multiplayer_transport_drain_request_text_queue system_sleep_milliseconds and multiplayer_transport_is_request_pending until the request completes. rizin + llvm-objdump + strings
246 0x0058eff0 78 multiplayer_transport_is_valid_nick_string shell cdecl inferred rizin 4 Validates one transport nick string. It rejects null or empty strings rejects a leading digit or `-` through 0x005a53f2 and then scans every remaining byte against the allowed nick-character table at 0x005e1c70. It returns 1 when the full string is acceptable and 0 otherwise. rizin + llvm-objdump + strings
247 0x0058f040 90 multiplayer_transport_dispatch_or_release_callback_binding shell cdecl inferred rizin 3 Generic dispatcher for one optional transport callback-binding structure. When binding field [this+0x0c] is present it packages the caller mode from EDX together with binding fields [this+0x18] and [this+0x36c] into opcode 0x1a through 0x0059b790. Otherwise it clears [this+0x04] and if callback pointer [this+0x14] is installed invokes it directly with the owner cookie at [this+0x18] and a zero status value. rizin + llvm-objdump + strings
248 0x0058f380 64 tracked_heap_alloc_with_header support cdecl inferred ghidra-headless 4 Allocates one caller-sized heap block through the shared allocator at 0x005a125d stores the payload size in a 4-byte header immediately before the returned pointer and updates the global allocation counters at 0x00dba4c8 through 0x00dba4d0. Callers treat the returned value as a payload pointer just past the size header. rizin + llvm-objdump
249 0x0058f3c0 43 tracked_heap_free_with_header support cdecl inferred ghidra-headless 4 Releases one heap block previously returned by tracked_heap_alloc_with_header. It reads the stored payload size from the 4-byte header decrements the shared allocation counters at 0x00dba4c8 and 0x00dba4cc and frees the underlying base pointer through 0x005a1145. rizin + llvm-objdump
250 0x0058f3f0 94 tracked_heap_resize_with_header support cdecl inferred ghidra-headless 4 Resizes one header-tracked heap block to a new payload size. Null plus nonzero size falls through to tracked_heap_alloc_with_header; nonnull plus zero size frees through tracked_heap_free_with_header; and the main path reallocates through 0x005a5922 while preserving and re-accounting the payload size tracked in the 4-byte header. rizin + llvm-objdump
251 0x0058f460 8 system_sleep_milliseconds support cdecl inferred ghidra-headless 4 Tiny wrapper over `Sleep` that forwards the caller millisecond delay in `ecx`. Current grounded callers use it as the 10 ms backoff inside immediate transport-drain loops. rizin + llvm-objdump
252 0x005928a0 189 multiplayer_transport_enqueue_opcode_record shell cdecl inferred ghidra-headless 3 Common allocator and queue-submit helper for session-event transport opcode records. It allocates a zeroed caller-sized record through tracked_heap_alloc_with_header invokes the opcode-specific initializer from the handler table at 0x005e2004 plus opcode times 0x10 packages the resulting payload together with caller metadata into 0x0059e4d0 and increments [this+0x1800] on success. Allocation or initializer failure releases the temporary record through tracked_heap_free_with_header and returns -1. ghidra + rizin + llvm-objdump
253 0x00592a40 40 multiplayer_transport_dispatch_callback_table_binding shell cdecl inferred ghidra-headless 2 Small binding-dispatch wrapper over multiplayer_transport_enqueue_opcode_record with opcode `4`. Current grounded callers use it after preparing callback-table descriptor fields from a live transport registration object and then continue through the common transport cleanup or release path. ghidra + rizin + llvm-objdump
254 0x00592a70 109 multiplayer_transport_probe_or_enqueue_route_record shell cdecl inferred ghidra-headless 2 Small route-probe wrapper over multiplayer_transport_enqueue_opcode_record. It first calls multiplayer_transport_is_route_mode_active_nonterminal and when that succeeds with caller mode `2` directly invokes the supplied callback; otherwise it falls back to an 0x08-byte opcode `1` record built from the caller callback and payload fields. ghidra + rizin + llvm-objdump
255 0x00592ae0 111 multiplayer_transport_enqueue_descriptor_block_record shell cdecl inferred ghidra-headless 2 Copies one caller-supplied seven-dword descriptor block into a local buffer and enqueues it through multiplayer_transport_enqueue_opcode_record as a 0x1c-byte opcode `2` record. Current grounded callers come from the deeper callback-table registration path. ghidra + rizin + llvm-objdump
256 0x00592b50 226 multiplayer_transport_enqueue_field_snapshot_record shell cdecl inferred ghidra-headless 3 Builds and enqueues one field-snapshot transport record through multiplayer_transport_enqueue_opcode_record using opcode `3` and a 0x14-byte payload. Depending on the caller mode it can first remove prior matching entries through 0x005929f0 then normalizes the `hostname` field against `(No Name)` samples the `gamemode` field and compares it against `openstaging` computes a 0 to 100 progress scalar from counters around [this+0x1734] [this+0x1740] and [this+0x1774] and packages the subscribed callback pointers from [this+0x176c] and [this+0x1770]. ghidra + rizin + llvm-objdump + strings
257 0x00592c40 54 multiplayer_transport_enqueue_callback_binding_record shell cdecl inferred ghidra-headless 2 Builds and enqueues one 0x08-byte opcode `4` callback-binding record through multiplayer_transport_enqueue_opcode_record. The helper uses the registered callback-table pointer at [this+0x4c] and is the direct worker beneath multiplayer_transport_dispatch_callback_table_binding. ghidra + rizin + llvm-objdump
258 0x00592c80 80 multiplayer_transport_enqueue_callback_slot9_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x10-byte opcode `9` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x1790] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
259 0x00592cd0 85 multiplayer_transport_enqueue_callback_slot10_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x14-byte opcode `10` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x1794] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
260 0x00592d30 62 multiplayer_transport_enqueue_callback_slot11_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x04-byte opcode `11` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x1798] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
261 0x00592d70 77 multiplayer_transport_enqueue_callback_slot12_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that copies a caller-supplied seven-dword block and enqueues it as a 0x20-byte opcode `12` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x179c] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
262 0x00592dc0 72 multiplayer_transport_enqueue_callback_slot13_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x0c-byte opcode `13` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17a0] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
263 0x00592e10 72 multiplayer_transport_enqueue_callback_slot14_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x10-byte opcode `14` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17a4] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
264 0x00592e60 64 multiplayer_transport_enqueue_callback_slot15_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x08-byte opcode `15` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17a8] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
265 0x00592ea0 64 multiplayer_transport_enqueue_callback_slot16_record shell cdecl inferred ghidra-headless 2 Gated callback-slot wrapper that enqueues one 0x08-byte opcode `16` record through multiplayer_transport_enqueue_opcode_record when byte [this+0x17ac] is set. The record is built around the callback-side state rooted near [this+0x17f8]. ghidra + rizin + llvm-objdump
266 0x00593460 87 multiplayer_transport_mark_selector_slot_records_stale shell cdecl inferred ghidra-headless 3 Scans the queued transport request collection at [this+0x1780] for records of type `1` or `2` whose selector-slot field at +0x1c matches the requested slot id. Matching records are marked stale by setting byte or dword field +0x38 to one. Current grounded caller is multiplayer_transport_reset_selector_slot. ghidra + rizin + llvm-objdump
267 0x00593790 351 multiplayer_transport_handle_names_query_response shell cdecl inferred ghidra-headless 3 Completion callback for multiplayer_transport_submit_names_query_with_callback. If the request is already stale at +0x38 it just unlinks through 0x5933a0. On nonzero result it can update route-binding state through multiplayer_transport_is_route_mode_active_nonterminal and multiplayer_transport_try_connect_status_route_once seeds selector slot `2` through multiplayer_transport_init_selector_slot upserts returned name records through multiplayer_transport_upsert_selector_name_entry publishes `TOPIC` and `MODE` lines through multiplayer_transport_publish_topic_status_line and multiplayer_transport_publish_mode_level_status_line and may promote one deferred route binding into [this+0x1ec8]. On zero result it resets selector slot `2` and falls back to multiplayer_transport_probe_or_enqueue_route_record before unlinking the request. ghidra + rizin + llvm-objdump + strings
268 0x005938f0 145 multiplayer_transport_handle_bound_route_request shell cdecl inferred ghidra-headless 3 Completion callback for multiplayer_transport_submit_bound_route_request. If the request is already stale at +0x38 it just unlinks through 0x5933a0. On nonzero result it can publish [req+0x24] through multiplayer_transport_publish_mode_key_status_line and then schedules multiplayer_transport_handle_names_query_response through multiplayer_transport_submit_names_query_with_callback. On zero result it resets selector slot `2` and falls back to multiplayer_transport_probe_or_enqueue_route_record before unlinking the request. ghidra + rizin + llvm-objdump
269 0x00594690 76 multiplayer_transport_mark_selector_slot_views_dirty shell cdecl inferred ghidra-headless 2 Marks one selector slot dirty in the transport-side view state rooted at [this+0xac8]. It sets slot-specific dirty bits at +0xa0 and +0xa4 when backing arrays at [this+0xad0] or [this+0xadc] are populated and also sets +0xa8 for selector slot `2`. Current grounded callers are multiplayer_transport_set_selector_slot_flags and multiplayer_transport_upsert_selector_name_entry. ghidra + rizin + llvm-objdump
270 0x00594bd0 97 multiplayer_transport_set_selector_slot_flags shell cdecl inferred ghidra-headless 3 Updates one selector-slot flag dword at [entry+0x5c] after resolving the current selector entry through 0x00594a40. When selector index `2` flips bit `1` it forwards the new bit value through multiplayer_transport_enqueue_callback_slot15_record and then notifies the shared selector-change callback path through 0x00593250 with selector id old flags and new flags. ghidra + rizin + llvm-objdump
271 0x00594c40 103 multiplayer_transport_parse_selector_mode_letters shell cdecl inferred ghidra-headless 3 Parses one selector-mode letter string into a small bitmask by probing for the letters `s` `r` `g` `a` and `h`. Current grounded callers merge this mask into the selector-slot flags that live at [entry+0x5c]. ghidra + rizin + llvm-objdump + strings
272 0x00594cb0 65 multiplayer_transport_merge_selector_mode_mask shell cdecl inferred ghidra-headless 3 Resolves one selector entry through 0x00594a40 parses the caller mode-letter string through multiplayer_transport_parse_selector_mode_letters preserves the current presence bits 0x20 and 0x40 from [entry+0x5c] and commits the merged result through multiplayer_transport_set_selector_slot_flags. ghidra + rizin + llvm-objdump + strings
273 0x00594d00 72 multiplayer_transport_set_selector_presence_mask shell cdecl inferred ghidra-headless 3 Overwrites the selector presence bits 0x20 and 0x40 in [entry+0x5c] from one caller byte mask while preserving the rest of the selector-slot flags. The helper then commits the new value through multiplayer_transport_set_selector_slot_flags. ghidra + rizin + llvm-objdump
274 0x00594f20 142 multiplayer_transport_upsert_selector_name_entry shell cdecl inferred ghidra-headless 3 Looks up or creates one selector-name entry for the requested selector slot. It resolves the current slot entry through 0x594a40 allocates a new entry through 0x594e70 when no match exists marks the selector index active at [entry+0x40+slot*4] increments the per-slot generation counter at [this+0xab8+slot*4] applies the caller flag bits 0x20 and 0x40 into [entry+0x5c+slot*4] and then marks the slot views dirty through multiplayer_transport_mark_selector_slot_views_dirty. Current grounded callers come from multiplayer_transport_handle_names_query_response and multiplayer_transport_handle_selector_update_response. ghidra + rizin + llvm-objdump
275 0x005950d0 101 multiplayer_transport_reset_selector_tables shell cdecl inferred ghidra-headless 4 Resets the three selector registration tables rooted at [this+0x80] [this+0x390] and [this+0x39c] together with state at [this+0x9a8] and [this+0x9ac]. When [this+0xab0] is set it preserves selector slot `0`; otherwise it clears all three selector slots. ghidra + rizin + llvm-objdump
276 0x00595140 89 multiplayer_transport_set_selector_name shell cdecl inferred ghidra-headless 4 Copies one selector name into the fixed 0x101-byte selector-name slot at [this+0x80+index*0x101] when the caller string fits. It then marks the selector present at [this+0x384+index*4] and clears the paired transient pointer at [this+0x99c+index*4]. ghidra + rizin + llvm-objdump
277 0x005951a0 67 multiplayer_transport_find_selector_name shell cdecl inferred ghidra-headless 4 Scans the three selector-name slots rooted at [this+0x80] for an exact string match and returns the matching selector index through the caller pointer. The callback-slot wrapper family uses this helper before enqueueing several selector-bound opcode records. ghidra + rizin + llvm-objdump
278 0x005951f0 579 multiplayer_transport_service_status_pump shell cdecl inferred ghidra-headless 3 Central session-event transport status-pump and route-service loop. It inspects selector presence under [this+0x384] and [this+0x390] builds temporary selector-mode masks through multiplayer_transport_parse_selector_mode_letters emits status text and field updates through multiplayer_transport_append_setchankey_or_setckey_command multiplayer_transport_dispatch_field_snapshot_mode and related helpers and drives the deeper route-state machine through multiplayer_transport_init_selector_slot multiplayer_transport_reset_selector_slot 0x005965d0 0x0059f3c0 and related helpers. ghidra + rizin + llvm-objdump + strings
279 0x00595440 98 multiplayer_transport_init_selector_slot shell cdecl inferred ghidra-headless 3 Initializes one selector slot under [this+0x384] and [this+0x390]. It copies caller text or the default sample at 0x005c87a8 into the fixed selector buffer at [slot+0x39c] clears byte [slot+0x59b] reruns multiplayer_transport_service_status_pump and then notifies multiplayer_transport_submit_profile_key_query_bundle_default for the refreshed selector slot. ghidra + rizin + llvm-objdump + strings
280 0x005954b0 238 multiplayer_transport_reset_selector_slot shell cdecl inferred ghidra-headless 3 Resets one selector slot under [this+0x384] and [this+0x390]. When the slot is active it tears the current selector object down through 0x593460 optionally republishes caller text through 0x58e7a0 refreshes selector bookkeeping through 0x5950a0 and clears the active and present flags before returning. ghidra + rizin + llvm-objdump
281 0x00595620 35 multiplayer_transport_release_route_binding shell cdecl inferred ghidra-headless 3 Releases the current route binding stored at [this+0x1ec8]. It detaches the binding from the descriptor object at [this+0x1ed0] through 0x58f3c0 unlinks it through 0x5933a0 and clears [this+0x1ec8]. ghidra + rizin + llvm-objdump
282 0x00595650 688 multiplayer_transport_set_route_mode shell cdecl inferred ghidra-headless 3 Main route-mode state machine for the session-event transport. It latches the requested small mode at [this+0x18b8] and dispatches modes `0` through `5` across live-route teardown selector-slot init or reset am-rating route seeding live-route connect and route-binding release paths. The branch uses multiplayer_transport_release_live_route multiplayer_transport_try_seed_am_rating_route_table multiplayer_transport_try_connect_live_route and multiplayer_transport_release_route_binding to converge on the next stable mode. ghidra + rizin + llvm-objdump + strings
283 0x005958e0 156 multiplayer_transport_try_stage_route_callback_payload shell cdecl inferred ghidra-headless 2 Builds one staged route-callback payload from the caller route object and transport-local text buffer at [this+0x60]. It extracts several caller fields through the 0x58d1f0 0x58d240 0x58d220 and 0x58d250 or 0x58d200 helpers packs them through multiplayer_transport_format_gsp_payload submits the staged text through multiplayer_transport_submit_selector_text_route_request and on success stores the cloned callback payload returned by multiplayer_transport_clone_staged_callback_payload at [this+0xb50]. ghidra + rizin + llvm-objdump + strings
284 0x00595980 84 multiplayer_transport_handle_route_status_result shell cdecl inferred ghidra-headless 2 Completion callback used by multiplayer_transport_submit_route_status_request. When the callback result is nonzero it compares the live status counters at [this+0xac0] and [this+0xb48] and advances the route-mode state machine through mode `2` or modes `3` or `4`. When the callback result is zero it sets [this+0x1ed8] and re-enters multiplayer_transport_set_route_mode using the current am-rating route state at [this+0x1ed4]. ghidra + rizin + llvm-objdump
285 0x005959e0 81 multiplayer_transport_submit_route_status_request shell cdecl inferred ghidra-headless 3 Submits one route-status request for the current binding at [this+0x1ec8]. It gathers the binding fields at +0x2c and +0x30 together with the local counter at [this+0xb48] and default sample text at 0x005c87a8 then sends that request through 0x593980 using multiplayer_transport_handle_route_status_result as the completion callback. Failure sets [this+0x1ed8] so the route-mode setter can fall back immediately. ghidra + rizin + llvm-objdump
286 0x00596270 70 multiplayer_transport_clone_staged_callback_payload shell cdecl inferred ghidra-headless 3 Clones one staged route-callback payload block by allocating a same-sized object through 0x58d5b0 copying the first nine dwords and then registering a cleanup callback through 0x58fa00 with shim 0x596260. Current grounded caller is multiplayer_transport_try_stage_route_callback_payload. ghidra + rizin + llvm-objdump
287 0x00597720 96 multiplayer_transport_format_gsp_payload shell cdecl inferred ghidra-headless 3 Formats one transport text payload with the `#GSP!%s!%c%s%c` template at 0x005e2358. Depending on whether the global formatter state at 0x00dba4c4 is present it builds either a 0x58-byte or 0x4d-byte intermediate fragment through 0x597590 or 0x5976c0 and then emits the final string through 0x5a19c4. Current grounded callers are multiplayer_transport_submit_bound_route_request and multiplayer_transport_try_stage_route_callback_payload. ghidra + rizin + llvm-objdump + strings
288 0x00593980 382 multiplayer_transport_submit_bound_route_request shell cdecl inferred ghidra-headless 3 Builds and submits one bound-route request using the current transport text buffers and a caller-supplied binding id or fallback route id. It formats the request payload through multiplayer_transport_format_gsp_payload allocates a type `1` transient request record through 0x5934e0 stores route and callback metadata on that record publishes selector `2` text through multiplayer_transport_set_selector_name and finally submits the request through 0x58e720 using multiplayer_transport_handle_bound_route_request. A nonempty caller text sample sets [this+0xb4c]. ghidra + rizin + llvm-objdump + strings
289 0x00593b00 161 multiplayer_transport_handle_selector_update_response shell cdecl inferred ghidra-headless 3 Follow-up callback used by multiplayer_transport_handle_selector_text_route_request. When the callback succeeds it initializes or repopulates selector slot [req+0x1c] through multiplayer_transport_init_selector_slot and multiplayer_transport_upsert_selector_name_entry. When it fails it resets that selector slot. Both paths finish by enqueueing a route record through multiplayer_transport_probe_or_enqueue_route_record and unlinking the request through 0x5933a0. ghidra + rizin + llvm-objdump
290 0x00593bb0 144 multiplayer_transport_handle_selector_text_route_request shell cdecl inferred ghidra-headless 3 Completion callback for multiplayer_transport_submit_selector_text_route_request. If the request is already stale at +0x38 it clears the transient state through 0x5962c0 and unlinks the request. On nonzero result it schedules multiplayer_transport_handle_selector_update_response through multiplayer_transport_submit_names_query_with_callback. On zero result it resets selector slot [req+0x1c] and falls back to multiplayer_transport_probe_or_enqueue_route_record before unlinking the request. ghidra + rizin + llvm-objdump
291 0x00593c40 177 multiplayer_transport_submit_selector_text_route_request shell cdecl inferred ghidra-headless 3 Builds and submits one selector-text route request. It validates the caller text defaults the sample text to 0x005c87a8 allocates a type `2` transient request record through 0x5934e0 stores the selector id at +0x1c refreshes selector naming through 0x59fc80 and multiplayer_transport_set_selector_name and then submits the request through 0x58e720 using multiplayer_transport_handle_selector_text_route_request. ghidra + rizin + llvm-objdump + strings
292 0x00595a40 245 multiplayer_transport_dispatch_field_snapshot_mode shell cdecl inferred ghidra-headless 3 Dispatches several session-field snapshot update modes into multiplayer_transport_enqueue_field_snapshot_record. Depending on the mode it can enqueue hostname or gamemode snapshots clear the progress scalar at [this+0x1774] reset the callback payload to zero or copy one dword from [eax+0x490] into [this+0x54] while updating the local field cache rooted at [this+0x1724]. ghidra + rizin + llvm-objdump + strings
293 0x00595b60 25 multiplayer_transport_enqueue_field_snapshot_mode1_if_enabled shell cdecl inferred ghidra-headless 2 Tiny field-snapshot wrapper that enqueues one mode-1 field snapshot only when the caller enable flag is zero. The helper is a thin front end over multiplayer_transport_enqueue_field_snapshot_record. ghidra + rizin + llvm-objdump
294 0x00595b80 50 multiplayer_transport_clear_progress_field_cache shell cdecl inferred ghidra-headless 3 Clears the progress-related field cache rooted at [this+0xba0] and then clears the local field cache at [this+0x1724]. It finishes by forwarding mode `3` into 0x005929a0 to remove the matching queued field-snapshot records. ghidra + rizin + llvm-objdump + strings
295 0x00595bc0 272 multiplayer_transport_enqueue_capacity_descriptor_record shell cdecl inferred ghidra-headless 3 Builds and enqueues one descriptor-block transport record tied to the capacity or progress cache at [this+0x1778]. One branch forwards cached descriptor fields directly through multiplayer_transport_enqueue_descriptor_block_record while the live branch samples hostname openstaging gamemode and numplayers strings from the current transport object before enqueueing the same opcode-2 descriptor record. ghidra + rizin + llvm-objdump + strings
296 0x00595ce0 22 multiplayer_transport_clear_capacity_descriptor_cache shell cdecl inferred ghidra-headless 3 Clears the auxiliary capacity-descriptor cache when [this+0xba0] is present by forwarding the embedded object at [this+0xba4] into 0x00590740. Current grounded callers use this before disconnect or larger route-state cleanup. ghidra + rizin + llvm-objdump
297 0x00595d60 84 multiplayer_transport_check_openstaging_capacity_gate shell cdecl inferred ghidra-headless 2 Checks whether the current transport object still matches the cached openstaging-like descriptor and whether numplayers remains below maxplayers. When the cached route object at [this+0x1ecc] already matches the current transport identifiers it returns success immediately; otherwise it compares the current maxplayers and numplayers fields and on success falls into 0x00592710 for the caller's route transition path. ghidra + rizin + llvm-objdump + strings
298 0x00595dc0 79 multiplayer_transport_try_transition_after_capacity_gate shell cdecl inferred ghidra-headless 2 Rejects when [this+0x1e8c] or selector slot [this+0x38c] is busy then runs multiplayer_transport_check_openstaging_capacity_gate refreshes route-side state through 0x5973b0 and 0x5954b0 forwards the caller event into 0x5958e0 and on success transitions through 0x595650 mode `0`. ghidra + rizin + llvm-objdump
299 0x00595e10 321 multiplayer_transport_dispatch_route_event_mode shell cdecl inferred ghidra-headless 2 Dispatches route-event modes for the callback branch rooted at [this+0x18bc]. Depending on the mode it may update [this+0x18bc] or [this+0x1e7c] reuse multiplayer_transport_try_transition_after_capacity_gate force mode `2` through 0x595650 or copy a selected descriptor pointer into [this+0x54]. Current surrounding evidence ties this branch to the `gsi_am_rating` route table. ghidra + rizin + llvm-objdump
300 0x00595f70 237 multiplayer_transport_dispatch_am_rating_route_callback shell cdecl inferred ghidra-headless 3 Callback handler for the `gsi_am_rating` route branch rooted at [this+0x18bc]. Mode `0` forwards directly into multiplayer_transport_try_transition_after_capacity_gate while mode `2` prunes stale route entries against multiplayer_transport_check_openstaging_capacity_gate updates surviving entries through 0x58d130 with the `gsi_am_rating` token and either forces mode `2` or forwards the surviving head entry into 0x5958e0 before transitioning through 0x595650 mode `0`. ghidra + rizin + llvm-objdump + strings
301 0x00596060 48 multiplayer_transport_reset_am_rating_route_state shell cdecl inferred ghidra-headless 3 Small reset helper for the active `gsi_am_rating` route state. When [this+0xba0] is set it clears the route callback table at [this+0x18bc] resets [this+0x1ec4] to zero and clears the auxiliary route cache at [this+0x1e7c]. ghidra + rizin + llvm-objdump + strings
302 0x00596090 272 multiplayer_transport_init_route_callback_tables shell cdecl inferred ghidra-headless 3 Initializes route callback tables at [this+0xba4] [this+0x1724] [this+0x1164] [this+0x18bc] and [this+0x1e7c]. Installs handlers 0x00595a40 0x00595b60 0x00595bc0 0x00595e10 and multiplayer_transport_dispatch_am_rating_route_callback seeds default selector text from static tables and sets [this+0xba0]. ghidra + rizin + llvm-objdump
303 0x005961b0 92 multiplayer_transport_teardown_route_callback_tables shell cdecl inferred ghidra-headless 4 Clears progress and capacity caches destroys the callback tables at [this+0xba4] [this+0x1164] and [this+0x18bc] clears the related caches at [this+0x1724] and [this+0x1e7c] and resets [this+0x1ec4] to zero. ghidra + rizin + llvm-objdump
304 0x005962e0 583 multiplayer_transport_register_field_subscription_bundle shell cdecl inferred ghidra-headless 3 Builds one field-subscription bundle from the field-id list optional suffix text and selector-name table. Rebuilds the callback table at [this+0xba4] seeds the local field cache at [this+0x1724] installs the subscription block through 0x590ed0 sets [this+0x1774] on success and enqueues an immediate mode-3 field snapshot through multiplayer_transport_enqueue_field_snapshot_record. ghidra + rizin + llvm-objdump
305 0x00596530 101 multiplayer_transport_try_seed_am_rating_route_table shell cdecl inferred ghidra-headless 2 Used by the larger route-mode setter around 0x595650. It first calls multiplayer_transport_reset_am_rating_route_state then rebuilds one mode `4` route entry in the callback table at [this+0x18bc] from the stored descriptor at [this+0x1ed0]. Success clears [this+0x1ed4] sets [this+0x1ec4] to one and failure reverts through multiplayer_transport_reset_am_rating_route_state before setting [this+0x1ed4]. ghidra + rizin + llvm-objdump + strings
306 0x005965a0 44 multiplayer_transport_try_connect_status_route_once shell cdecl inferred ghidra-headless 3 Single-shot wrapper for the auxiliary status-route object at [this+0xaf0]. When the in-flight latch at [this+0xb40] is already set it returns false immediately. Otherwise it sets that latch and forwards the caller route id into multiplayer_transport_try_connect_status_route then booleanizes the result. Current grounded caller is multiplayer_transport_handle_names_query_response. ghidra + rizin + llvm-objdump
307 0x00596da0 497 multiplayer_transport_submit_profile_key_query_bundle shell cdecl inferred rizin 2 Wrapper above the transport key-command builders that stages a small named-key query bundle around the strings `username` and `b_flags`. It allocates temporary key-name arrays and callback-entry tables submits the first request through multiplayer_transport_submit_getkey_command_and_wait folds returned key results into transport-owned callback state through 0x0058f8f0 and 0x0058fa00 and then follows with the larger channel-key submission path through multiplayer_transport_submit_setchankey_pair_list_command_and_wait when the staged key set is nonempty. rizin + llvm-objdump + strings
308 0x00596fa0 19 multiplayer_transport_submit_profile_key_query_bundle_with_context shell cdecl inferred rizin 2 Thin wrapper over multiplayer_transport_submit_profile_key_query_bundle that preserves the caller selector or route context in `edx` and forwards the stack-supplied context pointer as the extra bundle argument. Current grounded use is through the local callback table rooted at 0x0059f8b0. rizin + llvm-objdump
309 0x00596fc0 14 multiplayer_transport_submit_profile_key_query_bundle_default shell cdecl inferred rizin 3 Thin wrapper over multiplayer_transport_submit_profile_key_query_bundle that preserves the caller selector slot in `edx` and forces a null extra-context argument. Current grounded caller is multiplayer_transport_init_selector_slot and the same wrapper is also installed through the local callback table rooted at 0x0059fb60. rizin + llvm-objdump
310 0x00596fd0 441 multiplayer_transport_dispatch_status_route_event shell cdecl inferred rizin 3 Main local callback dispatcher for the auxiliary status-route object. It gates on [this+0x398] [this+0xb44] and flag bits in [this+0xb38] then maps route event ids through the local table at 0x005970c4 into selector text publication openstaging publication boolean status publication and callback forwarding paths. The dispatcher publishes through multiplayer_transport_send_selector_text and multiplayer_transport_publish_fixed_token_message and can also invoke the owner callback at [this+0x17dc] with payload [this+0x17f8]. rizin + llvm-objdump + strings
311 0x00597350 30 multiplayer_transport_release_status_route shell cdecl inferred ghidra-headless 3 Releases the auxiliary status-route object stored at [this+0xaf0] through 0x58cfd0 and clears the owner slot afterward. Status-pump cleanup fixed-token publishing and the auxiliary route connect helper use this before rebuilding status-route state. ghidra + rizin + llvm-objdump
312 0x005973d0 170 multiplayer_transport_try_connect_status_route shell cdecl inferred ghidra-headless 3 Attempts to connect or rebuild the auxiliary status-route object at [this+0xaf0]. It first tears any existing status route down through multiplayer_transport_release_status_route then builds a callback table from the local handler set rooted at multiplayer_transport_dispatch_status_route_event through 0x5972c0 chooses either the default route id `0x1964` or the caller route id and connects through 0x58cc40 or 0x58c9b0. On success it copies [this+0x9a8] into [this+0xb3c] wires the created route object through 0x58bc90 using callback 0x597330 and clears [this+0xb38]. ghidra + rizin + llvm-objdump + strings
313 0x005973b0 30 multiplayer_transport_release_live_route shell cdecl inferred ghidra-headless 4 Releases the current live route object stored at [this+0x1ecc] through 0x58cfd0 and clears the owner slot afterward. The route-mode setter and connect helper use it before rebuilding or switching live route state. ghidra + rizin + llvm-objdump
314 0x00597480 261 multiplayer_transport_try_connect_live_route shell cdecl inferred ghidra-headless 3 Attempts to connect or rebuild the current live route object at [this+0x1ecc]. It first clears any existing live route through multiplayer_transport_release_live_route then formats a local identifier from [this+0x60] and 0x005dccfc chooses either the default route id `0x1964` or the binding-specific id and connects through 0x58cc40 or 0x58c9b0. On success it updates [this+0x1ed8] and preserves the new live route state for the route-mode setter. ghidra + rizin + llvm-objdump + strings
315 0x00598230 67 multiplayer_transport_enqueue_names_query_record shell cdecl inferred ghidra-headless 3 Allocates one 0x10-byte transient names-query work item zeroes its four dword fields and submits it through 0x5980f0 as request kind `3` using the caller-provided sample or callback context pointer. The helper returns the allocated work item on success and null on allocation or submit failure. Current grounded caller is multiplayer_transport_submit_names_query_with_callback. ghidra + rizin + llvm-objdump
316 0x0058f0a0 99 multiplayer_transport_append_user_and_optional_nick_commands shell cdecl inferred rizin 3 Builds the initial identity command bundle for one multiplayer transport worker. It appends `USER %s %s %s :%s` to the owned text stream using worker text fields at [this+0x3ac] [this+0x42c] and [this+0x4b0] together with the fallback host `127.0.0.1` then checks the current nick through multiplayer_transport_is_valid_nick_string and either falls through multiplayer_transport_dispatch_or_release_callback_binding with mode `1` or appends `NICK %s` directly through the same text-stream path. rizin + llvm-objdump + strings
317 0x0058f920 72 hashed_entry_table_upsert support cdecl inferred rizin 4 Generic hashed-entry-table upsert over a bucket array of contiguous vectors. It computes the bucket index through the table hash callback at [this+0x0c] looks for an existing matching entry through hashed_entry_table_lookup and when found overwrites that slot through generic_vector_overwrite_with_callback; otherwise it appends the caller record into the selected bucket vector through 0x0059e4d0. rizin + llvm-objdump
318 0x0058f970 69 hashed_entry_table_remove support cdecl inferred rizin 4 Generic hashed-entry-table remove over a bucket array of contiguous vectors. It hashes the caller key into one bucket and erases the matching slot through generic_vector_erase_with_callback when present; otherwise it returns false. rizin + llvm-objdump
319 0x0058f9c0 63 hashed_entry_table_lookup support cdecl inferred rizin 4 Generic hashed-entry-table lookup over a bucket array of contiguous vectors. It hashes the caller key into one bucket resolves the matching index through generic_vector_find_index and returns the matched entry pointer or null. rizin + llvm-objdump
320 0x0058f110 465 multiplayer_transport_worker_init shell cdecl inferred rizin 3 Initializes one heap-backed multiplayer transport worker and its owned text-stream and store state. It zeroes the `0x5e4`-byte worker copies caller identifier strings into the fixed buffers at `[this+0x00]`, `[this+0x36c]`, `[this+0x3ac]`, `[this+0x42c]`, and `[this+0x4b0]`, copies one 5-dword descriptor block into `[this+0x534]`, seeds the state fields at `[this+0x04]` and `[this+0x558]`, initializes the registered-name store at `[this+0x548]`, the pending-template dispatch store at `[this+0x54c]`, and the owned text-stream object at `[this+0x1c]`, and tears partial state back down on failure. rizin + llvm-objdump
321 0x0058f2f0 60 multiplayer_transport_worker_create shell cdecl inferred rizin 3 Thin allocation wrapper for multiplayer_transport_worker_init. It allocates one `0x5e4`-byte worker block through tracked_heap_alloc_with_header and then forwards the descriptor pointer already staged in `EDX` plus the caller argument bundle into multiplayer_transport_worker_init. rizin + llvm-objdump
322 0x0059d430 47 string_hash_sum_mod support cdecl inferred rizin 3 Small string-hash helper that accumulates one normalized integer value per input byte through 0x005a5900 and returns the running sum modulo the caller divisor. Current grounded callers use it as the bucket-selector callback for registered-name entry tables. rizin + llvm-objdump
323 0x0059d470 57 multiplayer_transport_lookup_registered_name shell cdecl inferred ghidra-headless 3 Copies one caller string into a stack-local buffer and looks it up against the registered-name store rooted at [this+0x548] through hashed_entry_table_lookup. It returns the matched entry pointer or null. Current grounded callers are multiplayer_transport_has_registered_name and the deeper names-query payload helper family. ghidra + rizin + llvm-objdump
324 0x0059d520 91 multiplayer_transport_init_registered_name_store shell thiscall inferred rizin 4 Initializes the transport-side registered-name store by allocating the hashed bucket table at [this+0x548] with 7 buckets and a 0x1e0-byte entry shape through 0x0058f840 and then allocating the companion flat entry vector at [this+0x54c] through 0x0059e0b0. On allocation failure it tears any partial state back down. rizin + llvm-objdump
325 0x0059d580 35 multiplayer_transport_destroy_registered_name_store shell thiscall inferred rizin 4 Destroys the transport-side registered-name store by releasing the hashed bucket table at [this+0x548] through 0x0058f8b0 and the companion flat entry vector at [this+0x54c] through generic_vector_destroy when present. rizin + llvm-objdump
326 0x0059d610 81 multiplayer_transport_contains_registered_name_entry shell cdecl inferred rizin 3 Linear membership check over the flat registered-name entry vector at [this+0x54c]. It compares each live entry against the caller key through 0x005a57cf and returns true on the first exact match. rizin + llvm-objdump
327 0x0059d670 240 multiplayer_transport_upsert_registered_name_entry shell cdecl inferred rizin 3 Builds one temporary 0x1e0-byte registered-name entry on the stack from the caller descriptor and name string; allocates the entry-owned callback table through 0x0058f840; removes any older flat-vector entry with the same key from [this+0x54c]; and then inserts or replaces the canonical entry in the hashed registered-name store at [this+0x548] through hashed_entry_table_upsert. rizin + llvm-objdump
328 0x0059d760 103 multiplayer_transport_remove_registered_name_entry shell cdecl inferred rizin 4 Copies the caller name into a stack-local temporary key; removes any matching entry from the flat registered-name vector at [this+0x54c]; and then removes the canonical hashed-store entry from [this+0x548] through hashed_entry_table_remove. rizin + llvm-objdump
329 0x0058fa00 49 generic_callback_list_for_each support cdecl inferred ghidra-headless 4 Generic callback-list walker over one `[items count]` style callback collection. It uses generic_vector_for_each to visit every entry pointer and forwards the caller context through the supplied callback shim unchanged. Transport registration and the registered-name fast path reuse it to fan out one callback over all registered entries. rizin + llvm-objdump
330 0x0059e110 3 generic_vector_count support cdecl inferred rizin 4 Returns the current element count from dword [this+0x00] for one contiguous vector-style container. rizin + llvm-objdump
331 0x0059e120 10 generic_vector_index_ptr support cdecl inferred rizin 4 Computes one element pointer as base [this+0x14] plus index times stride [this+0x08]. Most higher-level vector helpers funnel slot access through this helper. rizin + llvm-objdump
332 0x0059e130 58 generic_vector_erase support cdecl inferred rizin 4 Removes one indexed element from a contiguous vector. When the erased slot is not already the tail it memmoves the trailing span down and then decrements the element count at [this+0x00]. rizin + llvm-objdump
333 0x0059e170 21 generic_vector_sort support cdecl inferred rizin 4 Sorts the backing element range at [this+0x14] through the shared qsort-style helper using the current count and stride from the vector header. rizin + llvm-objdump
334 0x0059e190 49 generic_vector_for_each support cdecl inferred rizin 4 Forward iterator for one contiguous vector. It walks indices `0..count-1` resolves each slot through generic_vector_index_ptr and invokes the caller callback with the shared context argument. rizin + llvm-objdump
335 0x0059e1d0 42 generic_vector_for_each_reverse support cdecl inferred rizin 4 Reverse iterator for one contiguous vector. It walks indices `count-1..0` and invokes the caller callback on each resolved slot pointer. rizin + llvm-objdump
336 0x0059e200 61 generic_vector_find_first support cdecl inferred rizin 4 Scans the vector from the front and returns the first element pointer whose caller predicate returns zero. When no match is found it returns null. rizin + llvm-objdump
337 0x0059e2f0 19 generic_vector_invoke_element_callback support cdecl inferred rizin 4 Invokes the optional per-element callback stored at [this+0x10] for one indexed slot when that callback pointer is nonnull. Erase overwrite and destroy helpers reuse it before mutating storage. rizin + llvm-objdump
338 0x0059e310 31 generic_vector_store_at support cdecl inferred rizin 4 Copies one caller-supplied element record into the indexed slot resolved through generic_vector_index_ptr using the current element stride from the vector header. rizin + llvm-objdump
339 0x0059e330 49 generic_vector_destroy support cdecl inferred rizin 4 Walks all live elements through generic_vector_invoke_element_callback then frees the backing storage at [this+0x14] and finally releases the vector object itself through tracked_heap_free_with_header. rizin + llvm-objdump
340 0x0059e370 87 generic_vector_insert_copy_at support cdecl inferred rizin 4 Ensures capacity grows through 0x0059e090 when full increments the count shifts the tail upward when inserting before the end and copies the caller element record into the requested slot through generic_vector_store_at. rizin + llvm-objdump
341 0x0059e3d0 22 generic_vector_erase_with_callback support cdecl inferred rizin 4 Calls generic_vector_invoke_element_callback for the indexed slot and then removes that slot through generic_vector_erase. Current grounded callers use it for registered-name and callback-entry teardown paths. rizin + llvm-objdump
342 0x0059e3f0 33 generic_vector_overwrite_with_callback support cdecl inferred rizin 4 Invokes generic_vector_invoke_element_callback for one indexed slot and then copies the caller replacement record back into that same slot through generic_vector_store_at. Hashed entry-table upsert uses it when replacing an existing matching record. rizin + llvm-objdump
343 0x0059e420 137 generic_vector_find_index support cdecl inferred rizin 4 Returns the index of one matching element within the contiguous vector or `-1` when none is found. Depending on the caller flag it uses either the linear comparator scan at 0x0059e240 or the ordered search helper at 0x0059e290 and derives the final index from the matched element pointer and stride. rizin + llvm-objdump
344 0x0059d7f0 86 multiplayer_transport_collect_registered_name_callback_entries shell cdecl inferred ghidra-headless 3 Callback collector used by the registered-name fast path. For each callback entry in the name entry's callback list it grows two parallel pointer arrays in the caller scratch frame through tracked_heap_resize_with_header and appends the callback entry pointer plus its `[entry+0xdc]` payload pointer. Current grounded caller is multiplayer_transport_dispatch_registered_name_query_fastpath through generic_callback_list_for_each. ghidra + rizin + llvm-objdump
345 0x0059d850 114 multiplayer_transport_dispatch_registered_name_query_fastpath shell cdecl inferred ghidra-headless 3 Fast path for multiplayer_transport_submit_names_query_with_callback when the queried sample already exists in the registered-name table. It resolves the name entry through multiplayer_transport_lookup_registered_name collects entry-owned callback state through multiplayer_transport_collect_registered_name_callback_entries and invokes the caller callback through multiplayer_transport_invoke_registered_name_query_callback without enqueueing a transport names-query record. Temporary callback arrays are released through tracked_heap_free_with_header on exit. ghidra + rizin + llvm-objdump
346 0x0059d8d0 15 multiplayer_transport_has_registered_name shell cdecl inferred ghidra-headless 3 Boolean wrapper over multiplayer_transport_lookup_registered_name. It returns true when the caller string resolves to one registered-name entry in the transport-side table and false otherwise. Current grounded caller is multiplayer_transport_submit_names_query_with_callback. ghidra + rizin + llvm-objdump
347 0x0059d8e0 64 multiplayer_transport_try_read_registered_name_header_block shell cdecl inferred rizin 4 Looks up one registered-name entry and when the header-valid flag at `[entry+0x154]` is set copies the 7-dword header block at `[entry+0x138]` into the caller buffer and returns true. Otherwise it returns false without mutating the destination. rizin + llvm-objdump
348 0x0059d920 48 multiplayer_transport_set_registered_name_header_block shell cdecl inferred rizin 4 Looks up one registered-name entry copies 7 caller-supplied dwords into the header block at `[entry+0x138]` and sets the paired valid flag at `[entry+0x154]` to one. rizin + llvm-objdump
349 0x0059d950 112 multiplayer_transport_set_registered_name_status_text shell cdecl inferred rizin 3 Looks up one registered-name entry frees the prior heap string at `[entry+0x158]` and replaces it with a heap copy of the caller text or the shared empty string when the caller passes null. The helper currently looks like the main per-name status or topic text setter for the registered-name store. rizin + llvm-objdump
350 0x0059d9c0 32 multiplayer_transport_mark_registered_name_dirty shell cdecl inferred rizin 3 Looks up one registered-name entry and sets the dword dirty or active flag at `[entry+0x15c]` to one. rizin + llvm-objdump
351 0x0059d9e0 32 multiplayer_transport_get_registered_name_dirty shell cdecl inferred rizin 3 Looks up one registered-name entry and returns the current dword dirty or active flag stored at `[entry+0x15c]` or zero when the entry is absent. rizin + llvm-objdump
352 0x0059da00 64 multiplayer_transport_set_registered_name_display_text shell cdecl inferred rizin 3 Looks up one registered-name entry copies up to 0x80 bytes of caller text into the embedded buffer at `[entry+0x160]` through string_copy_bounded_zerofill and clears the trailing byte flag at `[entry+0x1df]`. This is a second inline text field distinct from the heap string at `[entry+0x158]`. rizin + llvm-objdump
353 0x0059da40 208 multiplayer_transport_upsert_registered_name_callback_entry shell cdecl inferred rizin 4 Looks up one registered-name entry zeroes a temporary 0xe0-byte nested callback-entry record copies the secondary key string into the local record and when both payload blocks are provided copies 0x18 bytes into `[record+0x80]` and 0x40 bytes into `[record+0x98]` sets the local active flag at `[record+0xd8]` and stores one caller dword at `[record+0xdc]` before upserting the record into the entry-owned callback table at `[entry+0x134]` through hashed_entry_table_upsert. rizin + llvm-objdump
354 0x0059db10 80 multiplayer_transport_remove_registered_name_callback_entry shell cdecl inferred rizin 4 Looks up one registered-name entry copies the caller secondary key into a stack-local temporary and removes the matching nested callback-entry record from the entry-owned callback table at `[entry+0x134]` through hashed_entry_table_remove. rizin + llvm-objdump
355 0x0059db90 96 multiplayer_transport_dispatch_registered_name_callback_entry shell cdecl inferred rizin 3 Fans one callback descriptor over the transport-side registered-name store. It copies the primary name into a stack-local key builds a small dispatch frame and visits all registered-name entries through generic_callback_list_for_each where helper 0x0059db60 resolves the matching nested callback-entry record and invokes the descriptor function pointer at `[desc+0x08]` with the descriptor owner context plus the secondary key plus the payload cookie plus the owning registered-name entry. rizin + llvm-objdump
356 0x0059dcb0 48 multiplayer_transport_update_registered_name_callback_key shell cdecl inferred rizin 3 Visits every registered-name entry through generic_callback_list_for_each and runs helper 0x0059dbf0 to rewrite one nested callback-entry key. The helper removes the existing nested record from `[entry+0x134]` copies the replacement key into the local record reinserts it through hashed_entry_table_upsert and conditionally emits transport opcode 8 through 0x0059b790 when the name entry is marked dirty and has owner callbacks installed. rizin + llvm-objdump
357 0x0059dce0 256 multiplayer_transport_update_registered_name_callback_flags shell cdecl inferred rizin 4 Looks up one registered-name entry then resolves one nested callback-entry record by secondary key from the entry-owned callback table at `[entry+0x134]`. Depending on the caller mode flag it ORs or clears the caller bitmask against `[subentry+0xdc]` and when the parent entry has transport callbacks installed publishes an opcode-11 update through 0x0059b790 carrying the primary name plus the secondary key plus the new flag mask. rizin + llvm-objdump
358 0x0059de00 64 multiplayer_transport_dispatch_registered_name_callbacks shell cdecl inferred rizin 3 If the owning transport is active at `[*this]` it walks the full registered-name store through generic_callback_list_for_each and helper 0x0059dde0 increments a dispatch count and invokes the caller-provided callback function for each live registered-name entry. rizin + llvm-objdump
359 0x0059de40 96 multiplayer_transport_stage_registered_name_callback_payload shell cdecl inferred rizin 3 Resolves one nested callback-entry record by secondary key from the caller registered-name entry then copies a 0x18-byte payload block into `[subentry+0x80]` and a 0x40-byte payload block into `[subentry+0x98]` null-terminates both copied regions and sets the active flag at `[subentry+0xd8]` to one. rizin + llvm-objdump
360 0x0059dea0 96 multiplayer_transport_stage_registered_name_callback_payload_for_name shell cdecl inferred rizin 3 Looks up one primary registered-name entry then fans helper multiplayer_transport_stage_registered_name_callback_payload across the registered-name store through generic_callback_list_for_each using the caller secondary key plus the two payload buffers. Current grounded role is a primary-name keyed payload staging wrapper for nested callback-entry records. rizin + llvm-objdump
361 0x0059df00 96 multiplayer_transport_try_resolve_registered_name_callback_payload shell cdecl inferred rizin 4 Fast resolver for one nested callback-entry payload. When the descriptor either has no selector string or matches the shared two-byte default token at 0x005e1e1c it looks up the nested callback-entry record by key from `[entry+0x134]` and if the entry is active at `[subentry+0xd8]` marks the descriptor successful and returns pointers to the staged payload blocks at `[subentry+0x80]` and `[subentry+0x98]`. rizin + llvm-objdump
362 0x005934c0 30 multiplayer_transport_next_work_sequence shell thiscall inferred ghidra-headless 3 Returns the next monotonically increasing transport work-sequence value by incrementing dword [this+0x177c] and clamping negative wraparound back to zero. Current grounded callers use the returned value when allocating transient transport records for text submission registration and related async work. ghidra + rizin + llvm-objdump
363 0x00593650 229 multiplayer_transport_attach_callback_table_descriptor shell cdecl inferred ghidra-headless 3 Builds one transport-side callback-table descriptor from the caller table pointers and metadata. The helper allocates a temporary registration object through 0x005934e0 installs callback vectors from the 0x0059f5c0 and 0x0059f650 tables copies the caller transport pointer into the local stack frame and finishes by linking the result through 0x0058f2f0 and 0x005933a0. The current grounded caller is multiplayer_transport_register_callback_table. ghidra + rizin + llvm-objdump
364 0x00593d60 66 multiplayer_transport_try_submit_text_record_fastpath shell cdecl inferred ghidra-headless 3 Attempts the fast submission path for one prepared transport text record. It allocates a type-9 transient record through 0x005934e0 and when that succeeds forwards the caller callback and payload through 0x0058e510 with callback shim 0x00593d00. The current grounded caller is multiplayer_transport_submit_text_record. ghidra + rizin + llvm-objdump
365 0x00598d50 496 multiplayer_transport_handle_registered_name_callback_bind_record_mode1 shell cdecl inferred rizin 3 Owner-side wrapper for record mode 1 in the registered-name branch. It parses the mode prefix from the secondary key string at record field `+0x08` checks whether the primary name matches the local transport name at `[this+0x36c]` and either seeds one local registered-name entry through multiplayer_transport_upsert_registered_name_entry plus multiplayer_transport_set_registered_name_status_text or upserts one nested callback-entry record through multiplayer_transport_upsert_registered_name_callback_entry and emits follow-up opcode 6 or opcode 12 notifications when the target name entry is already marked dirty. rizin + llvm-objdump
366 0x00598f40 255 multiplayer_transport_handle_registered_name_callback_remove_record_mode1 shell cdecl inferred rizin 3 Owner-side removal wrapper for registered-name record mode 1. It resolves the primary and secondary key strings from the caller record removes the matching nested callback-entry through multiplayer_transport_remove_registered_name_callback_entry and then emits opcode 7 or opcode 12 notifications from the current registered-name owner callbacks when the target entry is dirty. rizin + llvm-objdump
367 0x00599040 308 multiplayer_transport_handle_registered_name_callback_remove_record_mode23 shell cdecl inferred rizin 3 Owner-side removal wrapper for registered-name record modes 2 and 3. It removes one nested callback-entry record by secondary key and then branches on whether the primary name matches the local transport name. The local-owner branch can emit opcode 5 and remove the whole registered-name entry through multiplayer_transport_remove_registered_name_entry while the remote branch emits opcode 7 subtype notifications through the installed owner callbacks. rizin + llvm-objdump
368 0x00599180 160 multiplayer_transport_publish_registered_name_callback_remove_mode1 shell cdecl inferred rizin 3 Small publish helper for registered-name callback-removal mode 1. It removes the named nested callback-entry and then emits the same owner callback notifications as the wider mode-1 removal path through opcode 7 and opcode 12 when the target entry is dirty and callback-enabled. rizin + llvm-objdump
369 0x00599230 25 multiplayer_transport_dispatch_registered_name_callback_remove_mode1 shell cdecl inferred rizin 3 Dispatch shim for registered-name callback-removal mode 1. When the input record kind equals 1 it forwards the primary name and one mode-1 removal helper descriptor into multiplayer_transport_dispatch_registered_name_callback_entry so the removal helper runs against each matching registered-name entry. rizin + llvm-objdump
370 0x00599250 160 multiplayer_transport_publish_registered_name_callback_remove_mode3 shell cdecl inferred rizin 3 Small publish helper for registered-name callback-removal mode 3. It removes the named nested callback-entry and emits the mode-3 owner callback notifications through opcode 7 and opcode 12 when the target registered-name entry is dirty and callback-enabled. rizin + llvm-objdump
371 0x00599300 25 multiplayer_transport_dispatch_registered_name_callback_remove_mode3 shell cdecl inferred rizin 3 Dispatch shim for registered-name callback-removal mode 3. When the input record kind equals 2 it forwards the primary name and one mode-3 removal helper descriptor into multiplayer_transport_dispatch_registered_name_callback_entry. rizin + llvm-objdump
372 0x00599320 93 multiplayer_transport_handle_registered_name_display_text_record_mode2 shell cdecl inferred rizin 4 Owner-side wrapper for registered-name display-text record mode 2. It copies the record string into the inline display buffer through multiplayer_transport_set_registered_name_display_text and when the target registered-name entry has an installed owner callback emits opcode 9 carrying the primary name and copied display text. rizin + llvm-objdump
373 0x00599380 253 multiplayer_transport_apply_registered_name_update_bundle shell cdecl inferred rizin 4 Applies one parsed update bundle to an existing registered-name entry. It walks the decoded element list from 0x00598630 and uses the element tags to route updates into multiplayer_transport_update_registered_name_callback_flags multiplayer_transport_set_registered_name_status_text and the header read or write pair multiplayer_transport_try_read_registered_name_header_block plus multiplayer_transport_set_registered_name_header_block before releasing the decoded bundle object. rizin + llvm-objdump
374 0x005997f0 177 multiplayer_transport_handle_registered_name_display_text_record_mode3 shell cdecl inferred rizin 3 Owner-side wrapper for registered-name display-text record mode 3. It stores the supplied display text into the inline registered-name buffer and either resolves one pending template node through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node or falls back to emitting opcode 9 through the installed owner callback for the target registered-name entry. rizin + llvm-objdump
375 0x005998b0 171 multiplayer_transport_handle_registered_name_display_text_clear_record shell cdecl inferred rizin 3 Owner-side wrapper for clearing registered-name display text. It builds a small mode-2 template with the shared empty string and either satisfies that request through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node or emits opcode 9 with the empty display text through the installed owner callback for the target registered-name entry. rizin + llvm-objdump
376 0x00599960 144 multiplayer_transport_handle_pending_template_pair_record_mode3 shell cdecl inferred llvm-objdump 3 Structural mode-3 wrapper over the pending-template path. It builds one single-entry pending-template query from the pair of caller strings then resolves a matching node through multiplayer_transport_find_pending_template_node and dispatches it through multiplayer_transport_dispatch_pending_template_node. When no pending node exists it falls back to the transport-side callback at `[this+0x04]` through multiplayer_transport_dispatch_or_release_callback_binding. llvm-objdump
377 0x005999f0 412 multiplayer_transport_handle_registered_name_callback_payload_record_mode8 shell cdecl inferred rizin 3 Owner-side wrapper for registered-name record mode 8. It stages the supplied nested callback-entry payload blocks through multiplayer_transport_stage_registered_name_callback_payload_for_name and then walks the returned template nodes to emit higher-level follow-up notifications including opcode 0x16 and opcode 0x17 based on the decoded template kinds and the marker characters found in the staged payload text through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node. rizin + llvm-objdump
378 0x00599c40 96 multiplayer_transport_copy_backslash_segment shell cdecl inferred llvm-objdump 4 Copies one backslash-delimited segment from the caller text into a freshly allocated heap string and writes the consumed byte count back through the out-parameter. Higher-level pending-template handlers reuse it to split multi-segment payloads before dispatch or callback fallback. llvm-objdump
379 0x00599ca0 320 multiplayer_transport_handle_segment_list_template_record_mode4 shell cdecl inferred llvm-objdump 3 Mode-4 pending-template wrapper for template kind 0x0c. It resolves one pending node through multiplayer_transport_find_pending_template_node splits the caller payload into a temporary heap string list with multiplayer_transport_copy_backslash_segment and then either dispatches that list through multiplayer_transport_dispatch_pending_template_node or falls back to emitting opcode 0x1e through the node-owned callback path before freeing the temporary segments. llvm-objdump
380 0x00599de0 128 multiplayer_transport_handle_pair_template_record_mode4 shell cdecl inferred llvm-objdump 3 Compact mode-4 pending-template wrapper for template kind 0x0c. After multiplayer_transport_find_pending_template_node succeeds it forwards two dword values from the matched node-owned payload block into one simple dispatch descriptor and completes the request through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
381 0x00599e60 768 multiplayer_transport_handle_segment_broadcast_template_record_mode5 shell cdecl inferred llvm-objdump 3 Structural mode-5 pending-template wrapper over split payload broadcasting. One branch matches a fixed token and walks the registered-name owner callback list to emit opcode 0x1d once per backslash-delimited segment. The other branch resolves one template-kind 0x0d pending node builds a temporary split-string array with multiplayer_transport_copy_backslash_segment optionally appends node-owned paired strings and then either dispatches the finished descriptor through multiplayer_transport_dispatch_pending_template_node or falls back to opcode 0x1f through the node callback path. llvm-objdump
382 0x0059a160 128 multiplayer_transport_handle_triplet_template_record_mode4 shell cdecl inferred llvm-objdump 3 Compact mode-4 pending-template wrapper for template kind 0x0d. After multiplayer_transport_find_pending_template_node succeeds it forwards the caller primary string plus two dword fields from the matched node payload block through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
383 0x0059a1e0 1024 multiplayer_transport_handle_segment_pair_template_record_mode4 shell cdecl inferred llvm-objdump 3 Structural mode-4 sibling of the split-payload template path for template kind 0x0e. One branch matches the fixed auxiliary token and emits opcode 0x1d once per backslash-delimited segment through the installed registered-name owner callbacks. The other branch resolves one pending node builds a temporary split-string array with multiplayer_transport_copy_backslash_segment appends paired node-owned strings and completes the request through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
384 0x0059a650 64 multiplayer_transport_mark_pending_template_kind1_ready shell cdecl inferred llvm-objdump 3 Small pending-template helper that looks up one kind-1 node through multiplayer_transport_find_pending_template_node and sets the first dword in its payload block to one when present. llvm-objdump
385 0x0059a690 448 multiplayer_transport_stage_pending_template_triplet_record_mode4 shell cdecl inferred llvm-objdump 3 Mode-4 helper for pending-template kind 1. It resolves one kind-1 node through multiplayer_transport_find_pending_template_node duplicates the caller strings plus one normalized helper string into heap storage emits opcode 0x0e through 0x0059b790 using the node-owned callback metadata and appends the three staged values into the node payload's parallel pointer arrays for later dispatch. llvm-objdump
386 0x0059a850 112 multiplayer_transport_dispatch_pending_template_quintuple_helper shell cdecl inferred llvm-objdump 3 Small helper that resolves one kind-5 pending-template node through multiplayer_transport_find_pending_template_node and forwards the four dword payload fields stored at `[node+0x1c+0x04..0x10]` through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
387 0x0059a8c0 272 multiplayer_transport_handle_registered_name_update_bundle_record_mode3plus shell cdecl inferred llvm-objdump 3 Owner-side registered-name update handler for record kinds 3 and above. It decodes one update bundle through 0x00598630 and 0x00598860 tries the registered-name header read or write path through multiplayer_transport_try_read_registered_name_header_block plus multiplayer_transport_set_registered_name_header_block publishes opcode 0x0a when the target entry already has owner callbacks and then completes any waiting kind-5 pending-template node through multiplayer_transport_find_pending_template_node plus multiplayer_transport_dispatch_pending_template_node. llvm-objdump
388 0x0059a9d0 320 multiplayer_transport_handle_pending_template_triplet_record_mode6 shell cdecl inferred llvm-objdump 3 Mode-6 pending-template wrapper that looks up either a kind-4 or kind-7 node through multiplayer_transport_find_pending_template_node. The kind-4 branch copies three caller strings into the node-owned payload slots while the kind-7 branch formats a derived string through 0x0059cbd0 and completes the request through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
389 0x0059ab10 256 multiplayer_transport_handle_token_list_template_record_mode3 shell cdecl inferred llvm-objdump 3 Mode-3 pending-template helper for kind 4. It parses the caller text into a token list with 0x005a3db9 trims leading `-` `@` and `+` markers duplicates each token into heap storage and appends the cleaned strings into the node-owned dynamic vector after multiplayer_transport_find_pending_template_node succeeds. llvm-objdump
390 0x0059ac10 144 multiplayer_transport_dispatch_extended_template_record_mode3 shell cdecl inferred llvm-objdump 3 Mode-3 helper for kind-4 pending-template nodes. After multiplayer_transport_find_pending_template_node succeeds it builds one extended dispatch descriptor from the caller string a boolean derived from the first payload dword and the remaining four dwords stored in the node payload block then completes the request through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
391 0x0059aca0 176 multiplayer_transport_append_string_template_record_mode8 shell cdecl inferred llvm-objdump 3 Helper for pending-template kind 8. It resolves one node through multiplayer_transport_find_pending_template_node grows the node-owned pointer vector through tracked_heap_resize_with_header duplicates the caller string and appends that heap string to the vector. llvm-objdump
392 0x0059ad50 112 multiplayer_transport_dispatch_string_vector_template_record_mode3 shell cdecl inferred llvm-objdump 3 Mode-3 dispatch helper for pending-template kind 8. It resolves one node through multiplayer_transport_find_pending_template_node then forwards the caller key together with the node-owned string-count and string-vector pointers through multiplayer_transport_dispatch_pending_template_node. llvm-objdump
393 0x0059adc0 96 multiplayer_transport_handle_local_name_record_mode2 shell cdecl inferred llvm-objdump 4 Mode-2 transport-state setter for the local name buffer at `[this+0x36c]`. It copies the caller string into that fixed buffer clears state dword `[this+0x04]` sets active flag `[this+0x00]` and when the transport owner callback at `[this+0x14]` is installed invokes it with mode `1` and the owner cookie at `[this+0x18]`. llvm-objdump
394 0x0059ae20 176 multiplayer_transport_handle_transport_text_pair_record_mode3 shell cdecl inferred llvm-objdump 3 Mode-3 transport-state setter for a pair of fixed text buffers. It copies the caller strings into the fixed buffers at `[this+0x564]` and `[this+0x140]` updates the associated length or dirty fields through helpers 0x005a1050 and 0x005a0d00 marks `[this+0x13c]` active and refreshes the transport-side status line rooted at `[this+0x1c]` through 0x0059caf0. llvm-objdump
395 0x0059aed0 112 multiplayer_transport_handle_normalized_pair_template_record_mode3 shell cdecl inferred llvm-objdump 3 Mode-3 wrapper that normalizes the secondary caller string through 0x005a1ea5 then resolves one kind-0x10 pending-template node through multiplayer_transport_find_pending_template_node and completes it through multiplayer_transport_dispatch_pending_template_node with the normalized value plus the original secondary string. llvm-objdump
396 0x00597920 56 multiplayer_transport_find_pending_template_kind0c_by_key shell cdecl inferred llvm-objdump 4 Searches the linked pending-template list rooted at `[this+0x550]` for the first kind-0x0c node whose payload string at `[node+0x1c+0x08]` exactly matches the caller key. It returns the matched node or null. llvm-objdump
397 0x0059af40 186 multiplayer_transport_dispatch_fallback_template_record_mode3 shell cdecl inferred llvm-objdump 3 Mode-3 fallback wrapper over the pending-template path. It first queries for either a kind-1 or kind-5 node keyed by the caller string through multiplayer_transport_find_pending_template_node and dispatches the matching node through multiplayer_transport_dispatch_pending_template_node with a minimal descriptor. When neither node exists it falls back to multiplayer_transport_find_pending_template_kind0c_by_key and completes that node with an empty descriptor instead. llvm-objdump
398 0x0059b000 103 multiplayer_transport_dispatch_kind1_string_template_record_mode6 shell cdecl inferred llvm-objdump 3 Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `6` and the original string payload. llvm-objdump
399 0x0059b070 103 multiplayer_transport_dispatch_kind1_string_template_record_mode2 shell cdecl inferred llvm-objdump 3 Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `2` and the original string payload. llvm-objdump
400 0x0059b0e0 103 multiplayer_transport_dispatch_kind1_string_template_record_mode3 shell cdecl inferred llvm-objdump 3 Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `3` and the original string payload. llvm-objdump
401 0x0059b150 103 multiplayer_transport_dispatch_kind1_string_template_record_mode4 shell cdecl inferred llvm-objdump 3 Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `4` and the original string payload. llvm-objdump
402 0x0059b1c0 103 multiplayer_transport_dispatch_kind1_string_template_record_mode5 shell cdecl inferred llvm-objdump 3 Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `5` and the original string payload. llvm-objdump
403 0x0059b230 103 multiplayer_transport_dispatch_kind1_string_template_record_mode8 shell cdecl inferred llvm-objdump 3 Fixed-mode wrapper for kind-1 pending-template nodes. It resolves the caller string through multiplayer_transport_find_pending_template_node and completes the matched node through multiplayer_transport_dispatch_pending_template_node with dispatch mode `8` and the original string payload. llvm-objdump
404 0x0059b2a0 1 multiplayer_transport_noop_cleanup_callback shell cdecl inferred llvm-objdump 2 Trivial no-op cleanup callback that returns immediately. Current grounded role is as a placeholder callback target in the transport cleanup layer. llvm-objdump
405 0x0059b2b0 17 multiplayer_transport_release_optional_callback_binding shell cdecl inferred llvm-objdump 2 Small cleanup helper that checks the optional callback binding stored at `[this+0x04]` and when present forwards it into multiplayer_transport_dispatch_or_release_callback_binding with mode `1`. llvm-objdump
406 0x0059b2d0 8 multiplayer_transport_free_template_entry_owner_string shell cdecl inferred llvm-objdump 3 Small element cleanup helper that releases the owner string pointer stored at `[entry+0x14]` through tracked_heap_free_with_header. The companion pending-template container uses it as the per-element cleanup callback when destroying its flat vector. llvm-objdump
407 0x0059b2e0 1239 multiplayer_transport_destroy_pending_template_dispatch_record shell cdecl inferred llvm-objdump 3 Type-switched destructor for one pending-template dispatch record. It reads the record kind at `[record+0x00]` and frees the owned payload graph under `[record+0x08]` through tracked_heap_free_with_header including nested string arrays and paired pointer vectors for the more complex template kinds before finally releasing the top-level payload block itself. llvm-objdump
408 0x0059b710 40 multiplayer_transport_init_pending_template_dispatch_store shell thiscall inferred llvm-objdump 3 Initializes the companion flat pending-template dispatch store at `[this+0x55c]` by allocating a stride-0x18 contiguous vector through 0x0059e0b0 and installing multiplayer_transport_free_template_entry_owner_string as the per-element cleanup callback. Returns true on success. llvm-objdump
409 0x0059b740 74 multiplayer_transport_destroy_pending_template_dispatch_store shell thiscall inferred llvm-objdump 3 Destroys the companion flat pending-template dispatch store at `[this+0x55c]`. It walks every live element through multiplayer_transport_destroy_pending_template_dispatch_record and then releases the backing vector through generic_vector_destroy. llvm-objdump
410 0x0059c220 458 multiplayer_transport_dispatch_pending_template_dispatch_record shell unknown inferred rizin 3 Switch-driven dispatcher for one flat pending-template dispatch-store record after the store manager has removed it from the vector. It reads the record kind at `[record+0x00]` invokes the record-owned callback at `[record+0x04]` with a payload tuple rooted at `[record+0x08]` and the owner string or selector at `[record+0x0c]` and then destroys the record through multiplayer_transport_destroy_pending_template_dispatch_record. Case `16` also resolves the registered-name dirty flag through 0x0059d9c0 before invoking the callback. rizin + llvm-objdump
411 0x0059c470 203 multiplayer_transport_service_pending_template_dispatch_store shell unknown inferred rizin 3 Services the flat pending-template dispatch store at `[this+0x55c]`. It walks every live 0x18-byte entry; entries whose owner string at `[entry+0x14]` no longer resolves through multiplayer_transport_has_registered_name are destroyed and erased immediately, while surviving entries are dispatched only when their registered-name dirty flag is nonzero and the optional filter value in EDX is zero or matches `[entry+0x10]`. Dispatching copies the 0x18-byte record to stack storage, erases the vector slot, and forwards the copied record into multiplayer_transport_dispatch_pending_template_dispatch_record. rizin + llvm-objdump
412 0x0059c540 70 multiplayer_transport_find_pending_template_dispatch_record_index shell unknown inferred rizin 4 Searches the flat pending-template dispatch store at `[this+0x55c]` for the first record whose selector or request field at `[entry+0x10]` matches the caller key. It returns the zero-based vector index on success or `-1` when no record matches. rizin + llvm-objdump
413 0x0059c590 21 multiplayer_transport_has_pending_template_dispatch_record shell unknown inferred rizin 4 Boolean wrapper over multiplayer_transport_find_pending_template_dispatch_record_index. It returns true when the flat pending-template dispatch store currently contains one record for the caller key and false otherwise. rizin + llvm-objdump
414 0x0059c5b0 40 growable_text_buffer_init support unknown inferred rizin 3 Initializes one heap-backed growable text buffer structure. It clears the used-length field at `[buf+0x04]`, seeds the initial capacity at `[buf+0x08]` to `0x2000`, allocates a `0x2001`-byte NUL-terminated backing block through tracked_heap_alloc_with_header, stores that pointer at `[buf+0x00]`, and returns true on success. rizin + llvm-objdump
415 0x0059c5e0 3 growable_text_buffer_free support unknown inferred rizin 4 Small wrapper that frees the heap-backed buffer pointer stored at `[buf+0x00]` through tracked_heap_free_with_header. rizin + llvm-objdump
416 0x0059c5f0 65 growable_text_buffer_reserve_append support unknown inferred rizin 4 Ensures that one growable text buffer has room to append the requested byte count in ECX while preserving a trailing NUL terminator. When `[buf+0x04] + requested` would exceed capacity `[buf+0x08]` it rounds the new capacity up in 0x2000-byte chunks resizes the backing block through tracked_heap_resize_with_header stores the new pointer at `[buf+0x00]` and updates `[buf+0x08]` before returning success or failure. rizin + llvm-objdump
417 0x0059c670 76 multiplayer_transport_text_stream_init shell thiscall inferred rizin 3 Initializes one multiplayer transport text-stream object. It zeroes the 0x350-byte state block seeds socket `[this+0x00]` to `-1` and allocates two growable text buffers at `[this+0x108]` and `[this+0x114]` through growable_text_buffer_init. Failure to allocate the second buffer frees the first and returns false. rizin + llvm-objdump
418 0x0059c790 194 multiplayer_transport_text_stream_destroy shell thiscall inferred rizin 4 Destroys one multiplayer transport text-stream object. If socket `[this+0x00]` is live it shuts it down with `shutdown(..., 2)` and `closesocket`, marks state `[this+0x04]` as closed, frees the two growable text buffers at `[this+0x108]` and `[this+0x114]`, releases the fixed pointer fields at `[this+0x328]` through `[this+0x344]`, then walks and frees the pointer vector rooted at `[this+0x348]` before freeing that vector itself. rizin + llvm-objdump
419 0x0059c860 300 multiplayer_transport_select_socket_ready_flags shell cdecl inferred rizin 4 Small `select` wrapper for one transport socket. It takes the socket on the stack plus up to three optional out-pointers for read write and exception readiness, builds the requested `fd_set` structures on the stack, calls `select(0x40, ...)` with a null timeout, and stores `1` or `0` into each requested out-slot depending on whether `__WSAFDIsSet` reports that socket as ready. rizin + llvm-objdump
420 0x0059c990 113 multiplayer_transport_text_stream_send_pump shell thiscall inferred rizin 4 Attempts to flush queued bytes from the transport text-stream send buffer at `[this+0x114]`. While buffered length `[this+0x118]` remains nonzero it probes writability through multiplayer_transport_select_socket_ready_flags, sends up to `min(len, 0x400)` bytes with `send`, slides any remaining buffered bytes down through `0x0059c640`, and continues until the socket is no longer writable or the buffer is empty. rizin + llvm-objdump
421 0x0059ca10 190 multiplayer_transport_text_stream_recv_pump shell thiscall inferred rizin 3 Receives available socket text into the transport text-stream receive buffer at `[this+0x108]`. It first probes readability through multiplayer_transport_select_socket_ready_flags then repeatedly reserves 0x1000 bytes through growable_text_buffer_reserve_append calls `recv` into the free tail of the buffer optionally applies the stream-cipher helper at 0x005a0f70 when `[this+0x120]` is armed advances the used-length field at `[this+0x10c]` NUL-terminates the buffer and loops while readability remains set. Socket errors store closed-state value `2` into `[this+0x04]`. rizin + llvm-objdump
422 0x0059cad0 25 multiplayer_transport_text_stream_service_io shell thiscall inferred rizin 4 Services one multiplayer transport text-stream I/O step unless state `[this+0x04]` is already closed. It first flushes queued outbound bytes through multiplayer_transport_text_stream_send_pump and then pumps inbound socket text through multiplayer_transport_text_stream_recv_pump. rizin + llvm-objdump
423 0x0059caf0 216 multiplayer_transport_text_stream_append_crlf_line shell thiscall inferred rizin 4 Appends one caller text line plus `\\r\\n` to the transport text-stream send buffer at `[this+0x114]`. It ignores requests when state `[this+0x04]` is already closed, reserves `strlen(text) + 2` bytes through growable_text_buffer_reserve_append, copies the bytes into the current tail tracked by `[this+0x118]`, appends CRLF, and updates the used-length field. When the stream-cipher gate at `[this+0x120]` is armed it post-processes the newly appended span through 0x005a0f70 using the send-side cipher state rooted at `[this+0x226]`. rizin + llvm-objdump
424 0x00597880 159 multiplayer_transport_find_pending_template_node shell cdecl inferred rizin 4 Searches the linked pending-template list rooted at `[this+0x550]` for the first node whose caller-provided query tuple array matches the node kind and its primary and secondary string selectors. When it finds a match it refreshes the node timeout field at `[node+0x04]` from GetTickCount plus 0xea60 and returns that node pointer otherwise it returns null. rizin + llvm-objdump
425 0x005979d0 1164 multiplayer_transport_dispatch_pending_template_node shell cdecl inferred rizin 3 Consumes one pending-template node and one caller dispatch descriptor. Depending on the node kind it emits one or more transport notifications through 0x0059b790 using the node-owned strings arrays and callback state then releases the node-owned heap strings arrays and child lists before unlinking the node from the pending-template list. Higher-level registered-name wrappers reuse it as the common completion path after multiplayer_transport_find_pending_template_node succeeds. rizin + llvm-objdump
426 0x005996c0 304 multiplayer_transport_handle_pending_template_record_mode3 shell cdecl inferred llvm-objdump 3 Structural mode-3 wrapper over the pending-template path for registered-name updates. It normalizes the caller selector string against the shared default token at 0x005e1e1c builds a four-way pending-template query and dispatches the matched node through multiplayer_transport_dispatch_pending_template_node. Depending on the matched node kind it can mark the registered-name entry dirty through multiplayer_transport_mark_registered_name_dirty or forward the node-owned payload fields into the dispatch descriptor. llvm-objdump
427 0x00565c90 208 shell_queue_indexed_world_anchor_marker shell cdecl inferred ghidra-headless 3 Variant world-anchor marker emitter that selects one indexed entry from the owner table at +0x24 using byte [this+0xd8] derives scale and packed color from the entry fields and enqueues the resulting type-0x01 deferred message through shell_enqueue_deferred_message_type1. ghidra + rizin + llvm-objdump
428 0x005662a0 964 shell_emit_sprite_billboard_quad_vertex24 bootstrap thiscall inferred ghidra-headless 4 Expands one sprite billboard into six vertex24 records forming two textured triangles. It derives an alpha byte from item timing flags at [this+0x48] [this+0x4c] and [this+0x5c] combines that alpha with packed color [this+0x70] scales a prepared four-corner basis by [this+0x44] and writes six 24-byte vertices using atlas uv pairs from [this+0x2c..0x38]. ghidra + rizin + llvm-objdump
429 0x00566670 84 shell_prepare_sprite_billboard_basis bootstrap thiscall inferred ghidra-headless 3 Builds the temporary four-corner sprite-billboard basis used by 0x005662a0 from the current shell transform state and writes the result into global scratch vectors around 0x00d97ae0 and 0x00d97b98. ghidra + rizin + llvm-objdump
430 0x0055e2b0 179 shell_create_layout_state bootstrap thiscall inferred ghidra-headless 4 Allocates a 0x3715-byte layout-state object for the shell controller stores it at [this+0x2d] seeds the dirty flags invokes 0x0054bc10 with owner state and a template byte from the shell bundle then binds the first presentation asset bundle through 0x00543f10 before later update hooks run. ghidra + rizin
431 0x005679b0 569 shell_emit_animated_quad_vertex24 bootstrap thiscall inferred ghidra-headless 4 Expands one cell-list item into four `vertex24` corner records with a time-varying color phase. The helper derives an 8-step brightness cycle from GetTickCount plus item field [this+0x3a] combines that phase with per-corner bytes at +0x35 through +0x38 and mask bytes at +0x31 through +0x34 and writes four 24-byte vertices from the quad corner positions stored across +0x00..+0x2c. ghidra + rizin + llvm-objdump
432 0x00567c70 103 shell_stream_primary_cell_quad_list bootstrap thiscall inferred ghidra-headless 4 Streams the primary quad-item list rooted at [this+0x1c] into the caller's `vertex24` buffer. It seeds the shared color input through 0x00d97bbc iterates each list entry through 0x005679b0 and advances the destination pointer by count*0x90 for four vertices per item. ghidra + rizin + llvm-objdump
433 0x00567ce0 105 shell_stream_alternate_cell_quad_list bootstrap thiscall inferred ghidra-headless 4 Streams the alternate quad-item list rooted at [this+0x20] into the caller's `vertex24` buffer using the same quad writer at 0x005679b0. Unlike the primary path it forwards an extra caller-supplied selector value into each emitted quad before advancing the destination pointer by count*0x90. ghidra + rizin + llvm-objdump
434 0x005a644d 81 __heap_init startup cdecl inferred ghidra-headless 4 Initializes the CRT heap path via ___heap_select and ___sbh_heap_init before later allocations occur. ghidra + rizin
435 0x005abd49 111 startup_init_tls_state startup unknown inferred ghidra-headless 3 Initializes per-thread startup state: mt locks plus TLS slot allocation and current-thread bookkeeping. ghidra + rizin
436 0x005abf1b 510 startup_init_file_handle_table startup cdecl inferred ghidra-headless 4 Allocates and seeds the CRT file descriptor table then consumes STARTUPINFO handles and classifies inherited std handles. ghidra + rizin
437 0x005aca5d 61 startup_run_init_callback_table startup unknown inferred ghidra-headless 3 Walks a startup callback table and invokes non-null entries before continuing the CRT path. ghidra + rizin
438 0x005ad12d 199 __setenvp startup cdecl inferred ghidra-headless 4 Builds the process envp array by counting environment strings and splitting name/value entries around '='. ghidra + rizin
439 0x005ad360 162 startup_build_argv startup cdecl inferred ghidra-headless 3 Initializes the multibyte table and uses a two-pass helper to count and copy argv entries from the process command line. ghidra + rizin
440 0x005ad402 290 ___crtGetEnvironmentStringsA startup cdecl inferred ghidra-headless 4 Copies the Windows environment block into CRT-owned storage before envp construction. ghidra + rizin

View file

@ -0,0 +1,122 @@
root_name,root_address,address,depth,name,size_bytes,calling_convention,signature_source,signature,parent_address,call_site
"bootstrap","0x00484440","0x00484440","0","FUN_00484440","323","unknown","DEFAULT","undefined FUN_00484440()","",""
"bootstrap","0x00484440","0x0046c230","1","FUN_0046c230","80","unknown","DEFAULT","undefined FUN_0046c230()","0x00484440","0x00484556"
"bootstrap","0x00484440","0x0047bbd0","1","FUN_0047bbd0","3","unknown","DEFAULT","undefined FUN_0047bbd0()","0x00484440","0x004844f7"
"bootstrap","0x00484440","0x0047bbe0","1","FUN_0047bbe0","1","unknown","DEFAULT","undefined FUN_0047bbe0()","0x00484440","0x0048453c"
"bootstrap","0x00484440","0x00481d00","1","FUN_00481d00","612","unknown","DEFAULT","undefined FUN_00481d00()","0x00484440","0x00484466"
"bootstrap","0x00484440","0x00481fd0","1","FUN_00481fd0","348","unknown","DEFAULT","undefined FUN_00481fd0()","0x00484440","0x004844ce"
"bootstrap","0x00484440","0x004840e0","1","FUN_004840e0","863","unknown","DEFAULT","undefined FUN_004840e0()","0x00484440","0x00484518"
"bootstrap","0x00484440","0x00518d50","1","FUN_00518d50","21","unknown","DEFAULT","undefined FUN_00518d50()","0x00484440","0x0048445d"
"bootstrap","0x00484440","0x0051d870","1","FUN_0051d870","21","unknown","DEFAULT","undefined FUN_0051d870()","0x00484440","0x00484453"
"bootstrap","0x00484440","0x0053b010","1","FUN_0053b010","11","unknown","DEFAULT","undefined FUN_0053b010()","0x00484440","0x0048446b"
"bootstrap","0x00484440","0x0053b020","1","FUN_0053b020","70","unknown","DEFAULT","undefined FUN_0053b020()","0x00484440","0x0048456e"
"bootstrap","0x00484440","0x0053b070","1","_malloc","5","__cdecl","IMPORTED","void * _malloc(size_t _Size)","0x00484440","0x004844c0"
"bootstrap","0x00484440","0x0053b080","1","_free","5","__cdecl","IMPORTED","void _free(void * _Memory)","0x00484440","0x00484527"
"bootstrap","0x00484440","0x0054e6d0","1","FUN_0054e6d0","42","unknown","DEFAULT","undefined FUN_0054e6d0()","0x00484440","0x004844b6"
"bootstrap","0x00484440","0x0054e700","1","FUN_0054e700","11","unknown","DEFAULT","undefined FUN_0054e700()","0x00484440","0x00484578"
"bootstrap","0x00484440","0x0055d3a0","1","FUN_0055d3a0","1","unknown","DEFAULT","undefined FUN_0055d3a0()","0x00484440","0x00484573"
"bootstrap","0x00484440","0x0055da40","1","FUN_0055da40","424","unknown","DEFAULT","undefined FUN_0055da40()","0x00484440","0x00484458"
"bootstrap","0x00484440","0x00461070","2","FUN_00461070","171","unknown","DEFAULT","undefined FUN_00461070()","0x004840e0","0x004843f5"
"bootstrap","0x00484440","0x00461120","2","FUN_00461120","485","unknown","DEFAULT","undefined FUN_00461120()","0x004840e0","0x00484217"
"bootstrap","0x00484440","0x00462560","2","FUN_00462560","16","unknown","DEFAULT","undefined FUN_00462560()","0x004840e0","0x00484135"
"bootstrap","0x00484440","0x004625b0","2","FUN_004625b0","7009","unknown","DEFAULT","undefined FUN_004625b0()","0x004840e0","0x00484276"
"bootstrap","0x00484440","0x00464130","2","FUN_00464130","62","unknown","DEFAULT","undefined FUN_00464130()","0x004840e0","0x00484426"
"bootstrap","0x00484440","0x004683f0","2","FUN_004683f0","34","unknown","DEFAULT","undefined FUN_004683f0()","0x004840e0","0x004843bd"
"bootstrap","0x00484440","0x00468760","2","FUN_00468760","144","unknown","DEFAULT","undefined FUN_00468760()","0x004840e0","0x00484295"
"bootstrap","0x00484440","0x0046bc40","2","FUN_0046bc40","563","unknown","DEFAULT","undefined FUN_0046bc40()","0x0046c230","0x0046c231"
"bootstrap","0x00484440","0x00474ce0","2","FUN_00474ce0","197","unknown","DEFAULT","undefined FUN_00474ce0()","0x004840e0","0x00484369"
"bootstrap","0x00484440","0x00474db0","2","FUN_00474db0","111","unknown","DEFAULT","undefined FUN_00474db0()","0x004840e0","0x004843af"
"bootstrap","0x00484440","0x004821d0","2","FUN_004821d0","1019","unknown","DEFAULT","undefined FUN_004821d0()","0x004840e0","0x0048427d"
"bootstrap","0x00484440","0x00482c90","2","FUN_00482c90","123","unknown","DEFAULT","undefined FUN_00482c90()","0x004840e0","0x00484160"
"bootstrap","0x00484440","0x00482ec0","2","FUN_00482ec0","1359","unknown","DEFAULT","undefined FUN_00482ec0()","0x004840e0","0x004842e8"
"bootstrap","0x00484440","0x00483f70","2","FUN_00483f70","352","unknown","DEFAULT","undefined FUN_00483f70()","0x004840e0","0x0048439d"
"bootstrap","0x00484440","0x00484910","2","FUN_00484910","105","unknown","DEFAULT","undefined FUN_00484910()","0x004840e0","0x004842c6"
"bootstrap","0x00484440","0x00484980","2","FUN_00484980","212","unknown","DEFAULT","undefined FUN_00484980()","0x004840e0","0x00484152"
"bootstrap","0x00484440","0x00484d70","2","FUN_00484d70","702","unknown","DEFAULT","undefined FUN_00484d70()","0x004840e0","0x0048426a"
"bootstrap","0x00484440","0x00518de0","2","FUN_00518de0","353","unknown","DEFAULT","undefined FUN_00518de0()","0x00481fd0","0x00482026"
"bootstrap","0x00484440","0x005193f0","2","FUN_005193f0","4956","unknown","DEFAULT","undefined FUN_005193f0()","0x00481fd0","0x004820e4"
"bootstrap","0x00484440","0x0051cf80","2","FUN_0051cf80","920","unknown","DEFAULT","undefined FUN_0051cf80()","0x00481fd0","0x004820d8"
"bootstrap","0x00484440","0x0051d890","2","FUN_0051d890","13","unknown","DEFAULT","undefined FUN_0051d890()","0x004840e0","0x00484324"
"bootstrap","0x00484440","0x0051d8a0","2","FUN_0051d8a0","28","unknown","DEFAULT","undefined FUN_0051d8a0()","0x004840e0","0x0048422f"
"bootstrap","0x00484440","0x0051d900","2","FUN_0051d900","155","unknown","DEFAULT","undefined FUN_0051d900()","0x00481fd0","0x004820f0"
"bootstrap","0x00484440","0x0051e980","2","FUN_0051e980","246","unknown","DEFAULT","undefined FUN_0051e980()","0x00481fd0","0x0048211b"
"bootstrap","0x00484440","0x0051f0f0","2","FUN_0051f0f0","3","unknown","DEFAULT","undefined FUN_0051f0f0()","0x004840e0","0x0048438a"
"bootstrap","0x00484440","0x0051ff90","2","FUN_0051ff90","24","unknown","DEFAULT","undefined FUN_0051ff90()","0x004840e0","0x00484178"
"bootstrap","0x00484440","0x00521060","2","FUN_00521060","805","unknown","DEFAULT","undefined FUN_00521060()","0x004840e0","0x004841c2"
"bootstrap","0x00484440","0x00521390","2","FUN_00521390","486","unknown","DEFAULT","undefined FUN_00521390()","0x004840e0","0x00484406"
"bootstrap","0x00484440","0x00521590","2","FUN_00521590","37","unknown","DEFAULT","undefined FUN_00521590()","0x0046c230","0x0046c242"
"bootstrap","0x00484440","0x00521920","2","FUN_00521920","103","unknown","DEFAULT","undefined FUN_00521920()","0x004840e0","0x004843f0"
"bootstrap","0x00484440","0x005309d0","2","FUN_005309d0","36","unknown","DEFAULT","undefined FUN_005309d0()","0x00481fd0","0x004820d3"
"bootstrap","0x00484440","0x00531750","2","FUN_00531750","29","unknown","DEFAULT","undefined FUN_00531750()","0x004840e0","0x0048434c"
"bootstrap","0x00484440","0x00532260","2","FUN_00532260","163","unknown","DEFAULT","undefined FUN_00532260()","0x004840e0","0x0048431f"
"bootstrap","0x00484440","0x0053ae70","2","FUN_0053ae70","337","unknown","DEFAULT","undefined FUN_0053ae70()","0x0053b020","0x0053b021"
"bootstrap","0x00484440","0x0053c930","2","FUN_0053c930","143","unknown","DEFAULT","undefined FUN_0053c930()","0x004840e0","0x004841fd"
"bootstrap","0x00484440","0x0053f000","2","FUN_0053f000","240","unknown","DEFAULT","undefined FUN_0053f000()","0x004840e0","0x004842f8"
"bootstrap","0x00484440","0x0054e660","2","FUN_0054e660","100","unknown","DEFAULT","undefined FUN_0054e660()","0x0054e700","0x0054e706"
"bootstrap","0x00484440","0x00557b70","2","FUN_00557b70","70","unknown","DEFAULT","undefined FUN_00557b70()","0x0046c230","0x0046c266"
"bootstrap","0x00484440","0x0055ccc0","2","FUN_0055ccc0","78","unknown","DEFAULT","undefined FUN_0055ccc0()","0x0055da40","0x0055da7d"
"bootstrap","0x00484440","0x0055cd40","2","FUN_0055cd40","203","unknown","DEFAULT","undefined FUN_0055cd40()","0x0055da40","0x0055dae3"
"bootstrap","0x00484440","0x0055ce60","2","FUN_0055ce60","1027","unknown","DEFAULT","undefined FUN_0055ce60()","0x0055da40","0x0055dbd6"
"bootstrap","0x00484440","0x0055d2f0","2","FUN_0055d2f0","160","unknown","DEFAULT","undefined FUN_0055d2f0()","0x0055da40","0x0055da73"
"bootstrap","0x00484440","0x005a1145","2","_free","104","__cdecl","IMPORTED","void _free(void * _Memory)","0x0053b020","0x0053b032"
"bootstrap","0x00484440","0x005a299e","2","FUN_005a299e","13","unknown","DEFAULT","undefined FUN_005a299e()","0x00518d50","0x00518d52"
"bootstrap","0x00484440","0x005a4376","2","FUN_005a4376","20","unknown","DEFAULT","undefined FUN_005a4376()","0x0055da40","0x0055db48"
"bootstrap","0x00484440","0x005a440d","2","__close","144","__cdecl","IMPORTED","int __close(int _FileHandle)","0x00481fd0","0x00482085"
"bootstrap","0x00484440","0x005a4c57","2","FID_conflict:__open","69","__cdecl","IMPORTED","int FID_conflict:__open(char * _Filename, int _OpenFlag, ...)","0x00481fd0","0x00482035"
"entry","0x005a313b","0x005a313b","0","entry","423","unknown","DEFAULT","undefined entry()","",""
"entry","0x005a313b","0x00484440","1","FUN_00484440","323","unknown","DEFAULT","undefined FUN_00484440()","0x005a313b","0x005a32b7"
"entry","0x005a313b","0x005a15e0","1","__chkstk","61","unknown","DEFAULT","undefined __chkstk()","0x005a313b","0x005a314e"
"entry","0x005a313b","0x005a2d64","1","FUN_005a2d64","101","unknown","DEFAULT","undefined FUN_005a2d64()","0x005a313b","0x005a3277"
"entry","0x005a313b","0x005a2e9c","1","FUN_005a2e9c","17","unknown","DEFAULT","undefined FUN_005a2e9c()","0x005a313b","0x005a32c7"
"entry","0x005a313b","0x005a2ebe","1","FUN_005a2ebe","15","unknown","DEFAULT","undefined FUN_005a2ebe()","0x005a313b","0x005a32cc"
"entry","0x005a313b","0x005a30f2","1","__amsg_exit","34","__cdecl","IMPORTED","void __amsg_exit(int param_1)","0x005a313b","0x005a323a"
"entry","0x005a313b","0x005a3117","1","fast_error_exit","36","__cdecl","DEFAULT","undefined fast_error_exit()","0x005a313b","0x005a3210"
"entry","0x005a313b","0x005a644d","1","__heap_init","81","__cdecl","IMPORTED","int __heap_init(void)","0x005a313b","0x005a3204"
"entry","0x005a313b","0x005a7124","1","__SEH_prolog","59","unknown","DEFAULT","undefined __SEH_prolog()","0x005a313b","0x005a3142"
"entry","0x005a313b","0x005a715f","1","__SEH_epilog","17","unknown","DEFAULT","undefined __SEH_epilog()","0x005a313b","0x005a3307"
"entry","0x005a313b","0x005abd49","1","FUN_005abd49","111","unknown","DEFAULT","undefined FUN_005abd49()","0x005a313b","0x005a3216"
"entry","0x005a313b","0x005abf1b","1","FUN_005abf1b","510","unknown","DEFAULT","undefined FUN_005abf1b()","0x005a313b","0x005a322f"
"entry","0x005a313b","0x005aca5d","1","FUN_005aca5d","61","unknown","DEFAULT","undefined FUN_005aca5d()","0x005a313b","0x005a3227"
"entry","0x005a313b","0x005ad0c4","1","FUN_005ad0c4","105","unknown","DEFAULT","undefined FUN_005ad0c4()","0x005a313b","0x005a3297"
"entry","0x005a313b","0x005ad12d","1","__setenvp","199","__cdecl","IMPORTED","int __setenvp(void)","0x005a313b","0x005a3266"
"entry","0x005a313b","0x005ad360","1","FUN_005ad360","162","unknown","DEFAULT","undefined FUN_005ad360()","0x005a313b","0x005a3255"
"entry","0x005a313b","0x005ad402","1","___crtGetEnvironmentStringsA","290","__cdecl","IMPORTED","LPVOID ___crtGetEnvironmentStringsA(void)","0x005a313b","0x005a324b"
"entry","0x005a313b","0x0046c230","2","FUN_0046c230","80","unknown","DEFAULT","undefined FUN_0046c230()","0x00484440","0x00484556"
"entry","0x005a313b","0x0047bbd0","2","FUN_0047bbd0","3","unknown","DEFAULT","undefined FUN_0047bbd0()","0x00484440","0x004844f7"
"entry","0x005a313b","0x0047bbe0","2","FUN_0047bbe0","1","unknown","DEFAULT","undefined FUN_0047bbe0()","0x00484440","0x0048453c"
"entry","0x005a313b","0x00481d00","2","FUN_00481d00","612","unknown","DEFAULT","undefined FUN_00481d00()","0x00484440","0x00484466"
"entry","0x005a313b","0x00481fd0","2","FUN_00481fd0","348","unknown","DEFAULT","undefined FUN_00481fd0()","0x00484440","0x004844ce"
"entry","0x005a313b","0x004840e0","2","FUN_004840e0","863","unknown","DEFAULT","undefined FUN_004840e0()","0x00484440","0x00484518"
"entry","0x005a313b","0x00518d50","2","FUN_00518d50","21","unknown","DEFAULT","undefined FUN_00518d50()","0x00484440","0x0048445d"
"entry","0x005a313b","0x0051d870","2","FUN_0051d870","21","unknown","DEFAULT","undefined FUN_0051d870()","0x00484440","0x00484453"
"entry","0x005a313b","0x0053b010","2","FUN_0053b010","11","unknown","DEFAULT","undefined FUN_0053b010()","0x00484440","0x0048446b"
"entry","0x005a313b","0x0053b020","2","FUN_0053b020","70","unknown","DEFAULT","undefined FUN_0053b020()","0x00484440","0x0048456e"
"entry","0x005a313b","0x0053b070","2","_malloc","5","__cdecl","IMPORTED","void * _malloc(size_t _Size)","0x00484440","0x004844c0"
"entry","0x005a313b","0x0053b080","2","_free","5","__cdecl","IMPORTED","void _free(void * _Memory)","0x00484440","0x00484527"
"entry","0x005a313b","0x0054e6d0","2","FUN_0054e6d0","42","unknown","DEFAULT","undefined FUN_0054e6d0()","0x00484440","0x004844b6"
"entry","0x005a313b","0x0054e700","2","FUN_0054e700","11","unknown","DEFAULT","undefined FUN_0054e700()","0x00484440","0x00484578"
"entry","0x005a313b","0x0055d3a0","2","FUN_0055d3a0","1","unknown","DEFAULT","undefined FUN_0055d3a0()","0x00484440","0x00484573"
"entry","0x005a313b","0x0055da40","2","FUN_0055da40","424","unknown","DEFAULT","undefined FUN_0055da40()","0x00484440","0x00484458"
"entry","0x005a313b","0x005a10b9","2","FUN_005a10b9","23","unknown","DEFAULT","undefined FUN_005a10b9()","0x005a2d64","0x005a2d6d"
"entry","0x005a313b","0x005a1145","2","_free","104","__cdecl","IMPORTED","void _free(void * _Memory)","0x005ad402","0x005ad4b4"
"entry","0x005a313b","0x005a125d","2","_malloc","18","__cdecl","IMPORTED","void * _malloc(size_t _Size)","0x005abf1b","0x005abf25"
"entry","0x005a313b","0x005a2cb0","2","___onexitinit","40","unknown","DEFAULT","undefined ___onexitinit()","0x005a2d64","0x005a2d8d"
"entry","0x005a313b","0x005a2d10","2","_atexit","18","__cdecl","IMPORTED","int _atexit(_func_4879 * param_1)","0x005a2d64","0x005a2d9f"
"entry","0x005a313b","0x005a2d22","2","___crtExitProcess","47","__cdecl","IMPORTED","void ___crtExitProcess(int param_1)","0x005a3117","0x005a3133"
"entry","0x005a313b","0x005a2dc9","2","FUN_005a2dc9","211","unknown","DEFAULT","undefined FUN_005a2dc9()","0x005a2e9c","0x005a2ea4"
"entry","0x005a313b","0x005a2ead","2","__exit","17","__cdecl","IMPORTED","void __exit(int _Code)","0x005a30f2","0x005a310e"
"entry","0x005a313b","0x005a5714","2","_calloc","175","__cdecl","IMPORTED","void * _calloc(size_t _Count, size_t _Size)","0x005abd49","0x005abd72"
"entry","0x005a313b","0x005a6433","2","___heap_select","26","unknown","DEFAULT","undefined ___heap_select()","0x005a644d","0x005a646d"
"entry","0x005a313b","0x005a649e","2","__mtinitlocks","73","__cdecl","IMPORTED","int __mtinitlocks(void)","0x005abd49","0x005abd49"
"entry","0x005a313b","0x005a6601","2","___sbh_heap_init","72","unknown","DEFAULT","undefined ___sbh_heap_init()","0x005a644d","0x005a6481"
"entry","0x005a313b","0x005aa9e0","2","_memcpy","672","__cdecl","IMPORTED","void * _memcpy(void * _Dst, void * _Src, size_t _Size)","0x005ad402","0x005ad50c"
"entry","0x005a313b","0x005abcba","2","FUN_005abcba","30","unknown","DEFAULT","undefined FUN_005abcba()","0x005abd49","0x005abd62"
"entry","0x005a313b","0x005abe90","2","_strlen","139","__cdecl","IMPORTED","size_t _strlen(char * _Str)","0x005ad12d","0x005ad153"
"entry","0x005a313b","0x005ac3b0","2","FUN_005ac3b0","7","unknown","DEFAULT","undefined FUN_005ac3b0()","0x005ad12d","0x005ad1a9"
"entry","0x005a313b","0x005acdb0","2","FUN_005acdb0","375","unknown","DEFAULT","undefined FUN_005acdb0()","0x005a3117","0x005a3129"
"entry","0x005a313b","0x005acf27","2","__FF_MSGBANNER","57","__cdecl","IMPORTED","void __FF_MSGBANNER(void)","0x005a3117","0x005a3120"
"entry","0x005a313b","0x005ad1f4","2","FUN_005ad1f4","364","unknown","DEFAULT","undefined FUN_005ad1f4()","0x005ad360","0x005ad3b4"
"entry","0x005a313b","0x005b082f","2","___crtInitCritSecAndSpinCount","103","unknown","DEFAULT","undefined ___crtInitCritSecAndSpinCount()","0x005abf1b","0x005ac05a"
"entry","0x005a313b","0x005b1297","2","___initmbctable","30","unknown","DEFAULT","undefined ___initmbctable()","0x005ad360","0x005ad372"
"entry","0x005a313b","0x005b1a31","2","FUN_005b1a31","17","unknown","DEFAULT","undefined FUN_005b1a31()","0x005ad0c4","0x005ad0f9"
"entry","0x005a313b","0x005b1bdb","2","FUN_005b1bdb","86","unknown","DEFAULT","undefined FUN_005b1bdb()","0x005a2d64","0x005a2dbb"
1 root_name root_address address depth name size_bytes calling_convention signature_source signature parent_address call_site
2 bootstrap 0x00484440 0x00484440 0 FUN_00484440 323 unknown DEFAULT undefined FUN_00484440()
3 bootstrap 0x00484440 0x0046c230 1 FUN_0046c230 80 unknown DEFAULT undefined FUN_0046c230() 0x00484440 0x00484556
4 bootstrap 0x00484440 0x0047bbd0 1 FUN_0047bbd0 3 unknown DEFAULT undefined FUN_0047bbd0() 0x00484440 0x004844f7
5 bootstrap 0x00484440 0x0047bbe0 1 FUN_0047bbe0 1 unknown DEFAULT undefined FUN_0047bbe0() 0x00484440 0x0048453c
6 bootstrap 0x00484440 0x00481d00 1 FUN_00481d00 612 unknown DEFAULT undefined FUN_00481d00() 0x00484440 0x00484466
7 bootstrap 0x00484440 0x00481fd0 1 FUN_00481fd0 348 unknown DEFAULT undefined FUN_00481fd0() 0x00484440 0x004844ce
8 bootstrap 0x00484440 0x004840e0 1 FUN_004840e0 863 unknown DEFAULT undefined FUN_004840e0() 0x00484440 0x00484518
9 bootstrap 0x00484440 0x00518d50 1 FUN_00518d50 21 unknown DEFAULT undefined FUN_00518d50() 0x00484440 0x0048445d
10 bootstrap 0x00484440 0x0051d870 1 FUN_0051d870 21 unknown DEFAULT undefined FUN_0051d870() 0x00484440 0x00484453
11 bootstrap 0x00484440 0x0053b010 1 FUN_0053b010 11 unknown DEFAULT undefined FUN_0053b010() 0x00484440 0x0048446b
12 bootstrap 0x00484440 0x0053b020 1 FUN_0053b020 70 unknown DEFAULT undefined FUN_0053b020() 0x00484440 0x0048456e
13 bootstrap 0x00484440 0x0053b070 1 _malloc 5 __cdecl IMPORTED void * _malloc(size_t _Size) 0x00484440 0x004844c0
14 bootstrap 0x00484440 0x0053b080 1 _free 5 __cdecl IMPORTED void _free(void * _Memory) 0x00484440 0x00484527
15 bootstrap 0x00484440 0x0054e6d0 1 FUN_0054e6d0 42 unknown DEFAULT undefined FUN_0054e6d0() 0x00484440 0x004844b6
16 bootstrap 0x00484440 0x0054e700 1 FUN_0054e700 11 unknown DEFAULT undefined FUN_0054e700() 0x00484440 0x00484578
17 bootstrap 0x00484440 0x0055d3a0 1 FUN_0055d3a0 1 unknown DEFAULT undefined FUN_0055d3a0() 0x00484440 0x00484573
18 bootstrap 0x00484440 0x0055da40 1 FUN_0055da40 424 unknown DEFAULT undefined FUN_0055da40() 0x00484440 0x00484458
19 bootstrap 0x00484440 0x00461070 2 FUN_00461070 171 unknown DEFAULT undefined FUN_00461070() 0x004840e0 0x004843f5
20 bootstrap 0x00484440 0x00461120 2 FUN_00461120 485 unknown DEFAULT undefined FUN_00461120() 0x004840e0 0x00484217
21 bootstrap 0x00484440 0x00462560 2 FUN_00462560 16 unknown DEFAULT undefined FUN_00462560() 0x004840e0 0x00484135
22 bootstrap 0x00484440 0x004625b0 2 FUN_004625b0 7009 unknown DEFAULT undefined FUN_004625b0() 0x004840e0 0x00484276
23 bootstrap 0x00484440 0x00464130 2 FUN_00464130 62 unknown DEFAULT undefined FUN_00464130() 0x004840e0 0x00484426
24 bootstrap 0x00484440 0x004683f0 2 FUN_004683f0 34 unknown DEFAULT undefined FUN_004683f0() 0x004840e0 0x004843bd
25 bootstrap 0x00484440 0x00468760 2 FUN_00468760 144 unknown DEFAULT undefined FUN_00468760() 0x004840e0 0x00484295
26 bootstrap 0x00484440 0x0046bc40 2 FUN_0046bc40 563 unknown DEFAULT undefined FUN_0046bc40() 0x0046c230 0x0046c231
27 bootstrap 0x00484440 0x00474ce0 2 FUN_00474ce0 197 unknown DEFAULT undefined FUN_00474ce0() 0x004840e0 0x00484369
28 bootstrap 0x00484440 0x00474db0 2 FUN_00474db0 111 unknown DEFAULT undefined FUN_00474db0() 0x004840e0 0x004843af
29 bootstrap 0x00484440 0x004821d0 2 FUN_004821d0 1019 unknown DEFAULT undefined FUN_004821d0() 0x004840e0 0x0048427d
30 bootstrap 0x00484440 0x00482c90 2 FUN_00482c90 123 unknown DEFAULT undefined FUN_00482c90() 0x004840e0 0x00484160
31 bootstrap 0x00484440 0x00482ec0 2 FUN_00482ec0 1359 unknown DEFAULT undefined FUN_00482ec0() 0x004840e0 0x004842e8
32 bootstrap 0x00484440 0x00483f70 2 FUN_00483f70 352 unknown DEFAULT undefined FUN_00483f70() 0x004840e0 0x0048439d
33 bootstrap 0x00484440 0x00484910 2 FUN_00484910 105 unknown DEFAULT undefined FUN_00484910() 0x004840e0 0x004842c6
34 bootstrap 0x00484440 0x00484980 2 FUN_00484980 212 unknown DEFAULT undefined FUN_00484980() 0x004840e0 0x00484152
35 bootstrap 0x00484440 0x00484d70 2 FUN_00484d70 702 unknown DEFAULT undefined FUN_00484d70() 0x004840e0 0x0048426a
36 bootstrap 0x00484440 0x00518de0 2 FUN_00518de0 353 unknown DEFAULT undefined FUN_00518de0() 0x00481fd0 0x00482026
37 bootstrap 0x00484440 0x005193f0 2 FUN_005193f0 4956 unknown DEFAULT undefined FUN_005193f0() 0x00481fd0 0x004820e4
38 bootstrap 0x00484440 0x0051cf80 2 FUN_0051cf80 920 unknown DEFAULT undefined FUN_0051cf80() 0x00481fd0 0x004820d8
39 bootstrap 0x00484440 0x0051d890 2 FUN_0051d890 13 unknown DEFAULT undefined FUN_0051d890() 0x004840e0 0x00484324
40 bootstrap 0x00484440 0x0051d8a0 2 FUN_0051d8a0 28 unknown DEFAULT undefined FUN_0051d8a0() 0x004840e0 0x0048422f
41 bootstrap 0x00484440 0x0051d900 2 FUN_0051d900 155 unknown DEFAULT undefined FUN_0051d900() 0x00481fd0 0x004820f0
42 bootstrap 0x00484440 0x0051e980 2 FUN_0051e980 246 unknown DEFAULT undefined FUN_0051e980() 0x00481fd0 0x0048211b
43 bootstrap 0x00484440 0x0051f0f0 2 FUN_0051f0f0 3 unknown DEFAULT undefined FUN_0051f0f0() 0x004840e0 0x0048438a
44 bootstrap 0x00484440 0x0051ff90 2 FUN_0051ff90 24 unknown DEFAULT undefined FUN_0051ff90() 0x004840e0 0x00484178
45 bootstrap 0x00484440 0x00521060 2 FUN_00521060 805 unknown DEFAULT undefined FUN_00521060() 0x004840e0 0x004841c2
46 bootstrap 0x00484440 0x00521390 2 FUN_00521390 486 unknown DEFAULT undefined FUN_00521390() 0x004840e0 0x00484406
47 bootstrap 0x00484440 0x00521590 2 FUN_00521590 37 unknown DEFAULT undefined FUN_00521590() 0x0046c230 0x0046c242
48 bootstrap 0x00484440 0x00521920 2 FUN_00521920 103 unknown DEFAULT undefined FUN_00521920() 0x004840e0 0x004843f0
49 bootstrap 0x00484440 0x005309d0 2 FUN_005309d0 36 unknown DEFAULT undefined FUN_005309d0() 0x00481fd0 0x004820d3
50 bootstrap 0x00484440 0x00531750 2 FUN_00531750 29 unknown DEFAULT undefined FUN_00531750() 0x004840e0 0x0048434c
51 bootstrap 0x00484440 0x00532260 2 FUN_00532260 163 unknown DEFAULT undefined FUN_00532260() 0x004840e0 0x0048431f
52 bootstrap 0x00484440 0x0053ae70 2 FUN_0053ae70 337 unknown DEFAULT undefined FUN_0053ae70() 0x0053b020 0x0053b021
53 bootstrap 0x00484440 0x0053c930 2 FUN_0053c930 143 unknown DEFAULT undefined FUN_0053c930() 0x004840e0 0x004841fd
54 bootstrap 0x00484440 0x0053f000 2 FUN_0053f000 240 unknown DEFAULT undefined FUN_0053f000() 0x004840e0 0x004842f8
55 bootstrap 0x00484440 0x0054e660 2 FUN_0054e660 100 unknown DEFAULT undefined FUN_0054e660() 0x0054e700 0x0054e706
56 bootstrap 0x00484440 0x00557b70 2 FUN_00557b70 70 unknown DEFAULT undefined FUN_00557b70() 0x0046c230 0x0046c266
57 bootstrap 0x00484440 0x0055ccc0 2 FUN_0055ccc0 78 unknown DEFAULT undefined FUN_0055ccc0() 0x0055da40 0x0055da7d
58 bootstrap 0x00484440 0x0055cd40 2 FUN_0055cd40 203 unknown DEFAULT undefined FUN_0055cd40() 0x0055da40 0x0055dae3
59 bootstrap 0x00484440 0x0055ce60 2 FUN_0055ce60 1027 unknown DEFAULT undefined FUN_0055ce60() 0x0055da40 0x0055dbd6
60 bootstrap 0x00484440 0x0055d2f0 2 FUN_0055d2f0 160 unknown DEFAULT undefined FUN_0055d2f0() 0x0055da40 0x0055da73
61 bootstrap 0x00484440 0x005a1145 2 _free 104 __cdecl IMPORTED void _free(void * _Memory) 0x0053b020 0x0053b032
62 bootstrap 0x00484440 0x005a299e 2 FUN_005a299e 13 unknown DEFAULT undefined FUN_005a299e() 0x00518d50 0x00518d52
63 bootstrap 0x00484440 0x005a4376 2 FUN_005a4376 20 unknown DEFAULT undefined FUN_005a4376() 0x0055da40 0x0055db48
64 bootstrap 0x00484440 0x005a440d 2 __close 144 __cdecl IMPORTED int __close(int _FileHandle) 0x00481fd0 0x00482085
65 bootstrap 0x00484440 0x005a4c57 2 FID_conflict:__open 69 __cdecl IMPORTED int FID_conflict:__open(char * _Filename, int _OpenFlag, ...) 0x00481fd0 0x00482035
66 entry 0x005a313b 0x005a313b 0 entry 423 unknown DEFAULT undefined entry()
67 entry 0x005a313b 0x00484440 1 FUN_00484440 323 unknown DEFAULT undefined FUN_00484440() 0x005a313b 0x005a32b7
68 entry 0x005a313b 0x005a15e0 1 __chkstk 61 unknown DEFAULT undefined __chkstk() 0x005a313b 0x005a314e
69 entry 0x005a313b 0x005a2d64 1 FUN_005a2d64 101 unknown DEFAULT undefined FUN_005a2d64() 0x005a313b 0x005a3277
70 entry 0x005a313b 0x005a2e9c 1 FUN_005a2e9c 17 unknown DEFAULT undefined FUN_005a2e9c() 0x005a313b 0x005a32c7
71 entry 0x005a313b 0x005a2ebe 1 FUN_005a2ebe 15 unknown DEFAULT undefined FUN_005a2ebe() 0x005a313b 0x005a32cc
72 entry 0x005a313b 0x005a30f2 1 __amsg_exit 34 __cdecl IMPORTED void __amsg_exit(int param_1) 0x005a313b 0x005a323a
73 entry 0x005a313b 0x005a3117 1 fast_error_exit 36 __cdecl DEFAULT undefined fast_error_exit() 0x005a313b 0x005a3210
74 entry 0x005a313b 0x005a644d 1 __heap_init 81 __cdecl IMPORTED int __heap_init(void) 0x005a313b 0x005a3204
75 entry 0x005a313b 0x005a7124 1 __SEH_prolog 59 unknown DEFAULT undefined __SEH_prolog() 0x005a313b 0x005a3142
76 entry 0x005a313b 0x005a715f 1 __SEH_epilog 17 unknown DEFAULT undefined __SEH_epilog() 0x005a313b 0x005a3307
77 entry 0x005a313b 0x005abd49 1 FUN_005abd49 111 unknown DEFAULT undefined FUN_005abd49() 0x005a313b 0x005a3216
78 entry 0x005a313b 0x005abf1b 1 FUN_005abf1b 510 unknown DEFAULT undefined FUN_005abf1b() 0x005a313b 0x005a322f
79 entry 0x005a313b 0x005aca5d 1 FUN_005aca5d 61 unknown DEFAULT undefined FUN_005aca5d() 0x005a313b 0x005a3227
80 entry 0x005a313b 0x005ad0c4 1 FUN_005ad0c4 105 unknown DEFAULT undefined FUN_005ad0c4() 0x005a313b 0x005a3297
81 entry 0x005a313b 0x005ad12d 1 __setenvp 199 __cdecl IMPORTED int __setenvp(void) 0x005a313b 0x005a3266
82 entry 0x005a313b 0x005ad360 1 FUN_005ad360 162 unknown DEFAULT undefined FUN_005ad360() 0x005a313b 0x005a3255
83 entry 0x005a313b 0x005ad402 1 ___crtGetEnvironmentStringsA 290 __cdecl IMPORTED LPVOID ___crtGetEnvironmentStringsA(void) 0x005a313b 0x005a324b
84 entry 0x005a313b 0x0046c230 2 FUN_0046c230 80 unknown DEFAULT undefined FUN_0046c230() 0x00484440 0x00484556
85 entry 0x005a313b 0x0047bbd0 2 FUN_0047bbd0 3 unknown DEFAULT undefined FUN_0047bbd0() 0x00484440 0x004844f7
86 entry 0x005a313b 0x0047bbe0 2 FUN_0047bbe0 1 unknown DEFAULT undefined FUN_0047bbe0() 0x00484440 0x0048453c
87 entry 0x005a313b 0x00481d00 2 FUN_00481d00 612 unknown DEFAULT undefined FUN_00481d00() 0x00484440 0x00484466
88 entry 0x005a313b 0x00481fd0 2 FUN_00481fd0 348 unknown DEFAULT undefined FUN_00481fd0() 0x00484440 0x004844ce
89 entry 0x005a313b 0x004840e0 2 FUN_004840e0 863 unknown DEFAULT undefined FUN_004840e0() 0x00484440 0x00484518
90 entry 0x005a313b 0x00518d50 2 FUN_00518d50 21 unknown DEFAULT undefined FUN_00518d50() 0x00484440 0x0048445d
91 entry 0x005a313b 0x0051d870 2 FUN_0051d870 21 unknown DEFAULT undefined FUN_0051d870() 0x00484440 0x00484453
92 entry 0x005a313b 0x0053b010 2 FUN_0053b010 11 unknown DEFAULT undefined FUN_0053b010() 0x00484440 0x0048446b
93 entry 0x005a313b 0x0053b020 2 FUN_0053b020 70 unknown DEFAULT undefined FUN_0053b020() 0x00484440 0x0048456e
94 entry 0x005a313b 0x0053b070 2 _malloc 5 __cdecl IMPORTED void * _malloc(size_t _Size) 0x00484440 0x004844c0
95 entry 0x005a313b 0x0053b080 2 _free 5 __cdecl IMPORTED void _free(void * _Memory) 0x00484440 0x00484527
96 entry 0x005a313b 0x0054e6d0 2 FUN_0054e6d0 42 unknown DEFAULT undefined FUN_0054e6d0() 0x00484440 0x004844b6
97 entry 0x005a313b 0x0054e700 2 FUN_0054e700 11 unknown DEFAULT undefined FUN_0054e700() 0x00484440 0x00484578
98 entry 0x005a313b 0x0055d3a0 2 FUN_0055d3a0 1 unknown DEFAULT undefined FUN_0055d3a0() 0x00484440 0x00484573
99 entry 0x005a313b 0x0055da40 2 FUN_0055da40 424 unknown DEFAULT undefined FUN_0055da40() 0x00484440 0x00484458
100 entry 0x005a313b 0x005a10b9 2 FUN_005a10b9 23 unknown DEFAULT undefined FUN_005a10b9() 0x005a2d64 0x005a2d6d
101 entry 0x005a313b 0x005a1145 2 _free 104 __cdecl IMPORTED void _free(void * _Memory) 0x005ad402 0x005ad4b4
102 entry 0x005a313b 0x005a125d 2 _malloc 18 __cdecl IMPORTED void * _malloc(size_t _Size) 0x005abf1b 0x005abf25
103 entry 0x005a313b 0x005a2cb0 2 ___onexitinit 40 unknown DEFAULT undefined ___onexitinit() 0x005a2d64 0x005a2d8d
104 entry 0x005a313b 0x005a2d10 2 _atexit 18 __cdecl IMPORTED int _atexit(_func_4879 * param_1) 0x005a2d64 0x005a2d9f
105 entry 0x005a313b 0x005a2d22 2 ___crtExitProcess 47 __cdecl IMPORTED void ___crtExitProcess(int param_1) 0x005a3117 0x005a3133
106 entry 0x005a313b 0x005a2dc9 2 FUN_005a2dc9 211 unknown DEFAULT undefined FUN_005a2dc9() 0x005a2e9c 0x005a2ea4
107 entry 0x005a313b 0x005a2ead 2 __exit 17 __cdecl IMPORTED void __exit(int _Code) 0x005a30f2 0x005a310e
108 entry 0x005a313b 0x005a5714 2 _calloc 175 __cdecl IMPORTED void * _calloc(size_t _Count, size_t _Size) 0x005abd49 0x005abd72
109 entry 0x005a313b 0x005a6433 2 ___heap_select 26 unknown DEFAULT undefined ___heap_select() 0x005a644d 0x005a646d
110 entry 0x005a313b 0x005a649e 2 __mtinitlocks 73 __cdecl IMPORTED int __mtinitlocks(void) 0x005abd49 0x005abd49
111 entry 0x005a313b 0x005a6601 2 ___sbh_heap_init 72 unknown DEFAULT undefined ___sbh_heap_init() 0x005a644d 0x005a6481
112 entry 0x005a313b 0x005aa9e0 2 _memcpy 672 __cdecl IMPORTED void * _memcpy(void * _Dst, void * _Src, size_t _Size) 0x005ad402 0x005ad50c
113 entry 0x005a313b 0x005abcba 2 FUN_005abcba 30 unknown DEFAULT undefined FUN_005abcba() 0x005abd49 0x005abd62
114 entry 0x005a313b 0x005abe90 2 _strlen 139 __cdecl IMPORTED size_t _strlen(char * _Str) 0x005ad12d 0x005ad153
115 entry 0x005a313b 0x005ac3b0 2 FUN_005ac3b0 7 unknown DEFAULT undefined FUN_005ac3b0() 0x005ad12d 0x005ad1a9
116 entry 0x005a313b 0x005acdb0 2 FUN_005acdb0 375 unknown DEFAULT undefined FUN_005acdb0() 0x005a3117 0x005a3129
117 entry 0x005a313b 0x005acf27 2 __FF_MSGBANNER 57 __cdecl IMPORTED void __FF_MSGBANNER(void) 0x005a3117 0x005a3120
118 entry 0x005a313b 0x005ad1f4 2 FUN_005ad1f4 364 unknown DEFAULT undefined FUN_005ad1f4() 0x005ad360 0x005ad3b4
119 entry 0x005a313b 0x005b082f 2 ___crtInitCritSecAndSpinCount 103 unknown DEFAULT undefined ___crtInitCritSecAndSpinCount() 0x005abf1b 0x005ac05a
120 entry 0x005a313b 0x005b1297 2 ___initmbctable 30 unknown DEFAULT undefined ___initmbctable() 0x005ad360 0x005ad372
121 entry 0x005a313b 0x005b1a31 2 FUN_005b1a31 17 unknown DEFAULT undefined FUN_005b1a31() 0x005ad0c4 0x005ad0f9
122 entry 0x005a313b 0x005b1bdb 2 FUN_005b1bdb 86 unknown DEFAULT undefined FUN_005b1bdb() 0x005a2d64 0x005a2dbb

View file

@ -0,0 +1,14 @@
KERNEL32.dll
USER32.dll
comdlg32.dll
ADVAPI32.dll
ole32.dll
mss32.dll
binkw32.dll
d3d8.dll
DINPUT8.dll
DSOUND.dll
WS2_32.dll
VERSION.dll
WSOCK32.dll
GDI32.dll

View file

@ -0,0 +1,257 @@
dll,hint,name
KERNEL32.dll,810,SleepEx
KERNEL32.dll,446,GetTickCount
KERNEL32.dll,317,GetDriveTypeA
KERNEL32.dll,522,InterlockedIncrement
KERNEL32.dll,518,InterlockedDecrement
KERNEL32.dll,616,OutputDebugStringA
KERNEL32.dll,301,GetCurrentDirectoryA
KERNEL32.dll,257,GetComputerNameA
KERNEL32.dll,792,SetThreadPriority
KERNEL32.dll,874,WinExec
KERNEL32.dll,745,SetEnvironmentVariableA
KERNEL32.dll,51,CompareStringW
KERNEL32.dll,50,CompareStringA
KERNEL32.dll,350,GetLocaleInfoW
KERNEL32.dll,526,IsBadCodePtr
KERNEL32.dll,529,IsBadReadPtr
KERNEL32.dll,797,SetUnhandledExceptionFilter
KERNEL32.dll,304,GetCurrentProcessId
KERNEL32.dll,380,GetOEMCP
KERNEL32.dll,235,GetACP
KERNEL32.dll,744,SetEndOfFile
KERNEL32.dll,780,SetStdHandle
KERNEL32.dll,418,GetStringTypeW
KERNEL32.dll,415,GetStringTypeA
KERNEL32.dll,539,IsValidCodePage
KERNEL32.dll,541,IsValidLocale
KERNEL32.dll,161,EnumSystemLocalesA
KERNEL32.dll,349,GetLocaleInfoA
KERNEL32.dll,450,GetUserDefaultLCID
KERNEL32.dll,740,SetCurrentDirectoryA
KERNEL32.dll,321,GetEnvironmentStringsW
KERNEL32.dll,228,FreeEnvironmentStringsW
KERNEL32.dll,319,GetEnvironmentStrings
KERNEL32.dll,227,FreeEnvironmentStringsA
KERNEL32.dll,834,UnhandledExceptionFilter
KERNEL32.dll,357,GetModuleFileNameA
KERNEL32.dll,507,HeapSize
KERNEL32.dll,545,LCMapStringW
KERNEL32.dll,544,LCMapStringA
KERNEL32.dll,861,VirtualQuery
KERNEL32.dll,424,GetSystemInfo
KERNEL32.dll,859,VirtualProtect
KERNEL32.dll,219,FlushFileBuffers
KERNEL32.dll,753,SetFilePointer
KERNEL32.dll,414,GetStdHandle
KERNEL32.dll,762,SetHandleCount
KERNEL32.dll,822,TlsAlloc
KERNEL32.dll,824,TlsGetValue
KERNEL32.dll,825,TlsSetValue
KERNEL32.dll,306,GetCurrentThreadId
KERNEL32.dll,766,SetLastError
KERNEL32.dll,823,TlsFree
KERNEL32.dll,643,RaiseException
KERNEL32.dll,532,IsBadWritePtr
KERNEL32.dll,853,VirtualAlloc
KERNEL32.dll,856,VirtualFree
KERNEL32.dll,497,HeapCreate
KERNEL32.dll,499,HeapDestroy
KERNEL32.dll,428,GetSystemTimeAsFileTime
KERNEL32.dll,505,HeapReAlloc
KERNEL32.dll,336,GetFileType
KERNEL32.dll,656,ReadFile
KERNEL32.dll,689,RtlUnwind
KERNEL32.dll,253,GetCommandLineA
KERNEL32.dll,412,GetStartupInfoA
KERNEL32.dll,817,TerminateProcess
KERNEL32.dll,171,ExitProcess
KERNEL32.dll,120,DeleteFileA
KERNEL32.dll,495,HeapAlloc
KERNEL32.dll,395,GetProcessHeap
KERNEL32.dll,501,HeapFree
KERNEL32.dll,837,UnmapViewOfFile
KERNEL32.dll,77,CreateFileW
KERNEL32.dll,74,CreateFileA
KERNEL32.dll,75,CreateFileMappingA
KERNEL32.dll,197,FindFirstFileA
KERNEL32.dll,206,FindNextFileA
KERNEL32.dll,241,GetCPInfo
KERNEL32.dll,193,FindClose
KERNEL32.dll,580,MapViewOfFile
KERNEL32.dll,333,GetFileSize
KERNEL32.dll,346,GetLastError
KERNEL32.dll,886,WriteFile
KERNEL32.dll,359,GetModuleHandleA
KERNEL32.dll,393,GetProcAddress
KERNEL32.dll,558,LoadLibraryA
KERNEL32.dll,537,IsProcessorFeaturePresent
KERNEL32.dll,101,CreateThread
KERNEL32.dll,869,WaitForSingleObject
KERNEL32.dll,44,CloseHandle
KERNEL32.dll,303,GetCurrentProcess
KERNEL32.dll,382,GetPriorityClass
KERNEL32.dll,456,GetVersionExA
KERNEL32.dll,483,GlobalMemoryStatus
KERNEL32.dll,639,QueryPerformanceFrequency
KERNEL32.dll,638,QueryPerformanceCounter
KERNEL32.dll,873,WideCharToMultiByte
KERNEL32.dll,593,MultiByteToWideChar
KERNEL32.dll,514,InitializeCriticalSection
KERNEL32.dll,809,Sleep
KERNEL32.dll,118,DeleteCriticalSection
KERNEL32.dll,557,LeaveCriticalSection
KERNEL32.dll,139,EnterCriticalSection
KERNEL32.dll,348,GetLocalTime
KERNEL32.dll,923,lstrcpynA
KERNEL32.dll,471,GlobalAlloc
KERNEL32.dll,482,GlobalLock
KERNEL32.dll,920,lstrcpyA
KERNEL32.dll,489,GlobalUnlock
KERNEL32.dll,451,GetUserDefaultLangID
USER32.dll,476,MessageBoxA
USER32.dll,586,SetClipboardData
USER32.dll,151,DestroyMenu
USER32.dll,605,SetMenu
USER32.dll,194,EnableMenuItem
USER32.dll,57,CheckMenuItem
USER32.dll,312,GetMenuStringA
USER32.dll,598,SetFocus
USER32.dll,711,VkKeyScanA
USER32.dll,43,CharNextExA
USER32.dll,191,DrawTextW
USER32.dll,188,DrawTextA
USER32.dll,208,EnumDisplayDevicesA
USER32.dll,46,CharPrevExA
USER32.dll,193,EmptyClipboard
USER32.dll,499,OpenClipboard
USER32.dll,257,GetClipboardData
USER32.dll,591,SetCursorPos
USER32.dll,561,ScreenToClient
USER32.dll,671,ToAscii
USER32.dll,267,GetCursorPos
USER32.dll,349,GetSystemMetrics
USER32.dll,277,GetDoubleClickTime
USER32.dll,726,keybd_event
USER32.dll,294,GetKeyboardState
USER32.dll,279,GetForegroundWindow
USER32.dll,509,PeekMessageA
USER32.dll,161,DispatchMessageA
USER32.dll,682,TranslateMessage
USER32.dll,142,DefWindowProcA
USER32.dll,589,SetCursor
USER32.dll,440,LoadCursorFromFileA
USER32.dll,451,LoadMenuA
USER32.dll,658,ShowWindow
USER32.dll,553,ReleaseCapture
USER32.dll,580,SetCapture
USER32.dll,372,GetWindowRect
USER32.dll,1,AdjustWindowRect
USER32.dll,96,CreateWindowExA
USER32.dll,640,SetWindowLongA
USER32.dll,511,PostMessageA
USER32.dll,153,DestroyWindow
USER32.dll,691,UnregisterClassA
USER32.dll,443,LoadIconA
USER32.dll,535,RegisterClassExA
USER32.dll,654,ShowCursor
USER32.dll,66,CloseClipboard
comdlg32.dll,9,GetOpenFileNameA
ADVAPI32.dll,491,RegQueryValueExA
ADVAPI32.dll,480,RegOpenKeyA
ADVAPI32.dll,460,RegCreateKeyExA
ADVAPI32.dll,456,RegCloseKey
ADVAPI32.dll,481,RegOpenKeyExA
ADVAPI32.dll,504,RegSetValueExA
ole32.dll,16,CoCreateInstance
ole32.dll,101,CoUninitialize
ole32.dll,58,CoInitializeEx
mss32.dll,325,_AIL_start_timer@4
mss32.dll,191,_AIL_register_3D_EOS_callback@8
mss32.dll,194,_AIL_register_EOS_callback@8
mss32.dll,318,_AIL_shutdown@0
mss32.dll,125,_AIL_init_sample@4
mss32.dll,326,_AIL_startup@0
mss32.dll,331,_AIL_stop_timer@4
mss32.dll,82,_AIL_close_stream@4
mss32.dll,339,_AIL_stream_status@4
mss32.dll,201,_AIL_register_stream_callback@8
mss32.dll,315,_AIL_set_timer_frequency@8
mss32.dll,324,_AIL_start_stream@4
mss32.dll,151,_AIL_open_stream@12
mss32.dll,61,_AIL_WAV_info@8
mss32.dll,239,_AIL_set_3D_distance_factor@8
mss32.dll,29,_AIL_3D_room_type@4
mss32.dll,43,_AIL_3D_speaker_type@4
mss32.dll,344,_AIL_unlock@0
mss32.dll,146,_AIL_open_3D_provider@4
mss32.dll,260,_AIL_set_3D_speaker_type@8
mss32.dll,242,_AIL_set_3D_position@16
mss32.dll,203,_AIL_register_timer@4
mss32.dll,241,_AIL_set_3D_orientation@28
mss32.dll,312,_AIL_set_stream_volume_levels@12
mss32.dll,317,_AIL_set_timer_user@8
mss32.dll,77,_AIL_close_3D_provider@4
mss32.dll,66,_AIL_allocate_3D_sample_handle@4
mss32.dll,212,_AIL_resume_3D_sample@4
mss32.dll,327,_AIL_stop_3D_sample@4
mss32.dll,100,_AIL_end_3D_sample@4
mss32.dll,75,_AIL_close_3D_listener@4
mss32.dll,205,_AIL_release_3D_sample_handle@4
mss32.dll,257,_AIL_set_3D_sample_playback_rate@8
mss32.dll,248,_AIL_set_3D_sample_effects_level@8
mss32.dll,247,_AIL_set_3D_sample_distances@12
mss32.dll,259,_AIL_set_3D_sample_volume@8
mss32.dll,320,_AIL_start_3D_sample@4
mss32.dll,255,_AIL_set_3D_sample_occlusion@8
mss32.dll,253,_AIL_set_3D_sample_loop_count@8
mss32.dll,250,_AIL_set_3D_sample_file@8
mss32.dll,148,_AIL_open_digital_driver@16
mss32.dll,281,_AIL_set_preference@8
mss32.dll,68,_AIL_allocate_sample_handle@4
mss32.dll,290,_AIL_set_sample_playback_rate@8
mss32.dll,210,_AIL_release_timer_handle@4
mss32.dll,104,_AIL_enumerate_3D_providers@12
mss32.dll,297,_AIL_set_sample_volume_pan@12
mss32.dll,287,_AIL_set_sample_loop_count@8
mss32.dll,144,_AIL_open_3D_listener@4
mss32.dll,152,_AIL_pause_stream@8
mss32.dll,213,_AIL_resume_sample@4
mss32.dll,329,_AIL_stop_sample@4
mss32.dll,296,_AIL_set_sample_volume_levels@12
mss32.dll,101,_AIL_end_sample@4
mss32.dll,322,_AIL_start_sample@4
mss32.dll,282,_AIL_set_redist_directory@4
mss32.dll,285,_AIL_set_sample_file@12
mss32.dll,131,_AIL_lock@0
binkw32.dll,55,_BinkSetVolume@12
binkw32.dll,37,_BinkOpenMiles@4
binkw32.dll,52,_BinkSetSoundSystem@8
binkw32.dll,46,_BinkSetIOSize@4
binkw32.dll,35,_BinkOpen@8
binkw32.dll,31,_BinkGoto@12
binkw32.dll,21,_BinkDoFrame@4
binkw32.dll,34,_BinkNextFrame@4
binkw32.dll,56,_BinkWait@4
binkw32.dll,23,_BinkGetKeyFrame@12
binkw32.dll,15,_BinkClose@4
binkw32.dll,17,_BinkCopyToBuffer@28
binkw32.dll,22,_BinkGetError@0
d3d8.dll,0,Direct3DCreate8
DINPUT8.dll,0,DirectInput8Create
VERSION.dll,1,GetFileVersionInfoSizeA
VERSION.dll,0,GetFileVersionInfoA
VERSION.dll,10,VerQueryValueA
GDI32.dll,405,GetObjectA
GDI32.dll,140,DeleteDC
GDI32.dll,441,GetTextFaceA
GDI32.dll,444,GetTextMetricsA
GDI32.dll,524,SelectObject
GDI32.dll,45,CreateCompatibleDC
GDI32.dll,50,CreateDIBSection
GDI32.dll,532,SetBkMode
GDI32.dll,531,SetBkColor
GDI32.dll,570,SetTextColor
GDI32.dll,58,CreateFontIndirectA
GDI32.dll,143,DeleteObject
GDI32.dll,57,CreateFontA
1 dll hint name
2 KERNEL32.dll 810 SleepEx
3 KERNEL32.dll 446 GetTickCount
4 KERNEL32.dll 317 GetDriveTypeA
5 KERNEL32.dll 522 InterlockedIncrement
6 KERNEL32.dll 518 InterlockedDecrement
7 KERNEL32.dll 616 OutputDebugStringA
8 KERNEL32.dll 301 GetCurrentDirectoryA
9 KERNEL32.dll 257 GetComputerNameA
10 KERNEL32.dll 792 SetThreadPriority
11 KERNEL32.dll 874 WinExec
12 KERNEL32.dll 745 SetEnvironmentVariableA
13 KERNEL32.dll 51 CompareStringW
14 KERNEL32.dll 50 CompareStringA
15 KERNEL32.dll 350 GetLocaleInfoW
16 KERNEL32.dll 526 IsBadCodePtr
17 KERNEL32.dll 529 IsBadReadPtr
18 KERNEL32.dll 797 SetUnhandledExceptionFilter
19 KERNEL32.dll 304 GetCurrentProcessId
20 KERNEL32.dll 380 GetOEMCP
21 KERNEL32.dll 235 GetACP
22 KERNEL32.dll 744 SetEndOfFile
23 KERNEL32.dll 780 SetStdHandle
24 KERNEL32.dll 418 GetStringTypeW
25 KERNEL32.dll 415 GetStringTypeA
26 KERNEL32.dll 539 IsValidCodePage
27 KERNEL32.dll 541 IsValidLocale
28 KERNEL32.dll 161 EnumSystemLocalesA
29 KERNEL32.dll 349 GetLocaleInfoA
30 KERNEL32.dll 450 GetUserDefaultLCID
31 KERNEL32.dll 740 SetCurrentDirectoryA
32 KERNEL32.dll 321 GetEnvironmentStringsW
33 KERNEL32.dll 228 FreeEnvironmentStringsW
34 KERNEL32.dll 319 GetEnvironmentStrings
35 KERNEL32.dll 227 FreeEnvironmentStringsA
36 KERNEL32.dll 834 UnhandledExceptionFilter
37 KERNEL32.dll 357 GetModuleFileNameA
38 KERNEL32.dll 507 HeapSize
39 KERNEL32.dll 545 LCMapStringW
40 KERNEL32.dll 544 LCMapStringA
41 KERNEL32.dll 861 VirtualQuery
42 KERNEL32.dll 424 GetSystemInfo
43 KERNEL32.dll 859 VirtualProtect
44 KERNEL32.dll 219 FlushFileBuffers
45 KERNEL32.dll 753 SetFilePointer
46 KERNEL32.dll 414 GetStdHandle
47 KERNEL32.dll 762 SetHandleCount
48 KERNEL32.dll 822 TlsAlloc
49 KERNEL32.dll 824 TlsGetValue
50 KERNEL32.dll 825 TlsSetValue
51 KERNEL32.dll 306 GetCurrentThreadId
52 KERNEL32.dll 766 SetLastError
53 KERNEL32.dll 823 TlsFree
54 KERNEL32.dll 643 RaiseException
55 KERNEL32.dll 532 IsBadWritePtr
56 KERNEL32.dll 853 VirtualAlloc
57 KERNEL32.dll 856 VirtualFree
58 KERNEL32.dll 497 HeapCreate
59 KERNEL32.dll 499 HeapDestroy
60 KERNEL32.dll 428 GetSystemTimeAsFileTime
61 KERNEL32.dll 505 HeapReAlloc
62 KERNEL32.dll 336 GetFileType
63 KERNEL32.dll 656 ReadFile
64 KERNEL32.dll 689 RtlUnwind
65 KERNEL32.dll 253 GetCommandLineA
66 KERNEL32.dll 412 GetStartupInfoA
67 KERNEL32.dll 817 TerminateProcess
68 KERNEL32.dll 171 ExitProcess
69 KERNEL32.dll 120 DeleteFileA
70 KERNEL32.dll 495 HeapAlloc
71 KERNEL32.dll 395 GetProcessHeap
72 KERNEL32.dll 501 HeapFree
73 KERNEL32.dll 837 UnmapViewOfFile
74 KERNEL32.dll 77 CreateFileW
75 KERNEL32.dll 74 CreateFileA
76 KERNEL32.dll 75 CreateFileMappingA
77 KERNEL32.dll 197 FindFirstFileA
78 KERNEL32.dll 206 FindNextFileA
79 KERNEL32.dll 241 GetCPInfo
80 KERNEL32.dll 193 FindClose
81 KERNEL32.dll 580 MapViewOfFile
82 KERNEL32.dll 333 GetFileSize
83 KERNEL32.dll 346 GetLastError
84 KERNEL32.dll 886 WriteFile
85 KERNEL32.dll 359 GetModuleHandleA
86 KERNEL32.dll 393 GetProcAddress
87 KERNEL32.dll 558 LoadLibraryA
88 KERNEL32.dll 537 IsProcessorFeaturePresent
89 KERNEL32.dll 101 CreateThread
90 KERNEL32.dll 869 WaitForSingleObject
91 KERNEL32.dll 44 CloseHandle
92 KERNEL32.dll 303 GetCurrentProcess
93 KERNEL32.dll 382 GetPriorityClass
94 KERNEL32.dll 456 GetVersionExA
95 KERNEL32.dll 483 GlobalMemoryStatus
96 KERNEL32.dll 639 QueryPerformanceFrequency
97 KERNEL32.dll 638 QueryPerformanceCounter
98 KERNEL32.dll 873 WideCharToMultiByte
99 KERNEL32.dll 593 MultiByteToWideChar
100 KERNEL32.dll 514 InitializeCriticalSection
101 KERNEL32.dll 809 Sleep
102 KERNEL32.dll 118 DeleteCriticalSection
103 KERNEL32.dll 557 LeaveCriticalSection
104 KERNEL32.dll 139 EnterCriticalSection
105 KERNEL32.dll 348 GetLocalTime
106 KERNEL32.dll 923 lstrcpynA
107 KERNEL32.dll 471 GlobalAlloc
108 KERNEL32.dll 482 GlobalLock
109 KERNEL32.dll 920 lstrcpyA
110 KERNEL32.dll 489 GlobalUnlock
111 KERNEL32.dll 451 GetUserDefaultLangID
112 USER32.dll 476 MessageBoxA
113 USER32.dll 586 SetClipboardData
114 USER32.dll 151 DestroyMenu
115 USER32.dll 605 SetMenu
116 USER32.dll 194 EnableMenuItem
117 USER32.dll 57 CheckMenuItem
118 USER32.dll 312 GetMenuStringA
119 USER32.dll 598 SetFocus
120 USER32.dll 711 VkKeyScanA
121 USER32.dll 43 CharNextExA
122 USER32.dll 191 DrawTextW
123 USER32.dll 188 DrawTextA
124 USER32.dll 208 EnumDisplayDevicesA
125 USER32.dll 46 CharPrevExA
126 USER32.dll 193 EmptyClipboard
127 USER32.dll 499 OpenClipboard
128 USER32.dll 257 GetClipboardData
129 USER32.dll 591 SetCursorPos
130 USER32.dll 561 ScreenToClient
131 USER32.dll 671 ToAscii
132 USER32.dll 267 GetCursorPos
133 USER32.dll 349 GetSystemMetrics
134 USER32.dll 277 GetDoubleClickTime
135 USER32.dll 726 keybd_event
136 USER32.dll 294 GetKeyboardState
137 USER32.dll 279 GetForegroundWindow
138 USER32.dll 509 PeekMessageA
139 USER32.dll 161 DispatchMessageA
140 USER32.dll 682 TranslateMessage
141 USER32.dll 142 DefWindowProcA
142 USER32.dll 589 SetCursor
143 USER32.dll 440 LoadCursorFromFileA
144 USER32.dll 451 LoadMenuA
145 USER32.dll 658 ShowWindow
146 USER32.dll 553 ReleaseCapture
147 USER32.dll 580 SetCapture
148 USER32.dll 372 GetWindowRect
149 USER32.dll 1 AdjustWindowRect
150 USER32.dll 96 CreateWindowExA
151 USER32.dll 640 SetWindowLongA
152 USER32.dll 511 PostMessageA
153 USER32.dll 153 DestroyWindow
154 USER32.dll 691 UnregisterClassA
155 USER32.dll 443 LoadIconA
156 USER32.dll 535 RegisterClassExA
157 USER32.dll 654 ShowCursor
158 USER32.dll 66 CloseClipboard
159 comdlg32.dll 9 GetOpenFileNameA
160 ADVAPI32.dll 491 RegQueryValueExA
161 ADVAPI32.dll 480 RegOpenKeyA
162 ADVAPI32.dll 460 RegCreateKeyExA
163 ADVAPI32.dll 456 RegCloseKey
164 ADVAPI32.dll 481 RegOpenKeyExA
165 ADVAPI32.dll 504 RegSetValueExA
166 ole32.dll 16 CoCreateInstance
167 ole32.dll 101 CoUninitialize
168 ole32.dll 58 CoInitializeEx
169 mss32.dll 325 _AIL_start_timer@4
170 mss32.dll 191 _AIL_register_3D_EOS_callback@8
171 mss32.dll 194 _AIL_register_EOS_callback@8
172 mss32.dll 318 _AIL_shutdown@0
173 mss32.dll 125 _AIL_init_sample@4
174 mss32.dll 326 _AIL_startup@0
175 mss32.dll 331 _AIL_stop_timer@4
176 mss32.dll 82 _AIL_close_stream@4
177 mss32.dll 339 _AIL_stream_status@4
178 mss32.dll 201 _AIL_register_stream_callback@8
179 mss32.dll 315 _AIL_set_timer_frequency@8
180 mss32.dll 324 _AIL_start_stream@4
181 mss32.dll 151 _AIL_open_stream@12
182 mss32.dll 61 _AIL_WAV_info@8
183 mss32.dll 239 _AIL_set_3D_distance_factor@8
184 mss32.dll 29 _AIL_3D_room_type@4
185 mss32.dll 43 _AIL_3D_speaker_type@4
186 mss32.dll 344 _AIL_unlock@0
187 mss32.dll 146 _AIL_open_3D_provider@4
188 mss32.dll 260 _AIL_set_3D_speaker_type@8
189 mss32.dll 242 _AIL_set_3D_position@16
190 mss32.dll 203 _AIL_register_timer@4
191 mss32.dll 241 _AIL_set_3D_orientation@28
192 mss32.dll 312 _AIL_set_stream_volume_levels@12
193 mss32.dll 317 _AIL_set_timer_user@8
194 mss32.dll 77 _AIL_close_3D_provider@4
195 mss32.dll 66 _AIL_allocate_3D_sample_handle@4
196 mss32.dll 212 _AIL_resume_3D_sample@4
197 mss32.dll 327 _AIL_stop_3D_sample@4
198 mss32.dll 100 _AIL_end_3D_sample@4
199 mss32.dll 75 _AIL_close_3D_listener@4
200 mss32.dll 205 _AIL_release_3D_sample_handle@4
201 mss32.dll 257 _AIL_set_3D_sample_playback_rate@8
202 mss32.dll 248 _AIL_set_3D_sample_effects_level@8
203 mss32.dll 247 _AIL_set_3D_sample_distances@12
204 mss32.dll 259 _AIL_set_3D_sample_volume@8
205 mss32.dll 320 _AIL_start_3D_sample@4
206 mss32.dll 255 _AIL_set_3D_sample_occlusion@8
207 mss32.dll 253 _AIL_set_3D_sample_loop_count@8
208 mss32.dll 250 _AIL_set_3D_sample_file@8
209 mss32.dll 148 _AIL_open_digital_driver@16
210 mss32.dll 281 _AIL_set_preference@8
211 mss32.dll 68 _AIL_allocate_sample_handle@4
212 mss32.dll 290 _AIL_set_sample_playback_rate@8
213 mss32.dll 210 _AIL_release_timer_handle@4
214 mss32.dll 104 _AIL_enumerate_3D_providers@12
215 mss32.dll 297 _AIL_set_sample_volume_pan@12
216 mss32.dll 287 _AIL_set_sample_loop_count@8
217 mss32.dll 144 _AIL_open_3D_listener@4
218 mss32.dll 152 _AIL_pause_stream@8
219 mss32.dll 213 _AIL_resume_sample@4
220 mss32.dll 329 _AIL_stop_sample@4
221 mss32.dll 296 _AIL_set_sample_volume_levels@12
222 mss32.dll 101 _AIL_end_sample@4
223 mss32.dll 322 _AIL_start_sample@4
224 mss32.dll 282 _AIL_set_redist_directory@4
225 mss32.dll 285 _AIL_set_sample_file@12
226 mss32.dll 131 _AIL_lock@0
227 binkw32.dll 55 _BinkSetVolume@12
228 binkw32.dll 37 _BinkOpenMiles@4
229 binkw32.dll 52 _BinkSetSoundSystem@8
230 binkw32.dll 46 _BinkSetIOSize@4
231 binkw32.dll 35 _BinkOpen@8
232 binkw32.dll 31 _BinkGoto@12
233 binkw32.dll 21 _BinkDoFrame@4
234 binkw32.dll 34 _BinkNextFrame@4
235 binkw32.dll 56 _BinkWait@4
236 binkw32.dll 23 _BinkGetKeyFrame@12
237 binkw32.dll 15 _BinkClose@4
238 binkw32.dll 17 _BinkCopyToBuffer@28
239 binkw32.dll 22 _BinkGetError@0
240 d3d8.dll 0 Direct3DCreate8
241 DINPUT8.dll 0 DirectInput8Create
242 VERSION.dll 1 GetFileVersionInfoSizeA
243 VERSION.dll 0 GetFileVersionInfoA
244 VERSION.dll 10 VerQueryValueA
245 GDI32.dll 405 GetObjectA
246 GDI32.dll 140 DeleteDC
247 GDI32.dll 441 GetTextFaceA
248 GDI32.dll 444 GetTextMetricsA
249 GDI32.dll 524 SelectObject
250 GDI32.dll 45 CreateCompatibleDC
251 GDI32.dll 50 CreateDIBSection
252 GDI32.dll 532 SetBkMode
253 GDI32.dll 531 SetBkColor
254 GDI32.dll 570 SetTextColor
255 GDI32.dll 58 CreateFontIndirectA
256 GDI32.dll 143 DeleteObject
257 GDI32.dll 57 CreateFontA

View file

@ -0,0 +1,137 @@
.\Data\CargoTypes\
AZ Rail Rat
CargoCarOverlay.imb
gpdCargoTypeDB
gptGameMap
Quicksave
Detail maps
WorldMapSave
CargoModels
%1_CargoModel%2.3dp
CargoIcons
%1_CargoIcon%2.3dp
cargoSkin
railty3
>CargoMoney_DollarSign
maps
saved games
Railroad Tycoon 3
Map '% 30s' Event '% 30s' Length %d Text '%s'
; Map Briefing (Multi Player, if applicable)
; Map Briefing (Single Player)
; Map Description
; * The map description is displayed in a tight space and must stay fairly short.
; information only for the person editing the map is placed. This is not
; Scenario Text File, version 1.1
MAPS\%s.lng
maps\*.gmp
AnyCargo
AnyCargo.imb
Cargo.imb
CCargo.win
?CargoMinNum.imb
?Setup_Choose_Map_Buttons.imb
PaintSound.win
DirectSound3D Hardware Support
.\Data\GrayscaleMaps
Video.win
All players will use the HOST version of the save game.
Transfer save game to all players.
Only the host may save the game.
Control the volume of the 'ching' sound when trains arrive at a station
Save Game: %1
The text for this event will replace the default briefing text (useful if you want to change goals in the middle of a scenario).
Unable to create Direct Play interface.
Save your pennies and try again some other time.
This railroad has been liquidated by its creditors. The creditors are operating the remaining track and stations, which have a book value of %1.
The map you're trying to load is %1 X %2. Maps can be NO LARGER than 1024 on each side, and we recommend smaller sizes. Please set the size to scale to:
Unable to create saved game.
This may be because you don't have user privileges to create files (i.e. you're using a Limited User Account), or because you're trying to overwrite a saved game that is write protected.
Please note: You have saved a map that is designated as a campaign map. It WILL NOT show up in the list of scenarios to be played when the user selects 'New Scenario'.
If you want it to show up in that list, go into the editor control panel, under 'General', and uncheck the 'Campaign Scenario' checkbox, then resave it.
Disabling Hardware T & L may be useful in resolving/reducing problems with crashes/lockups/freezes. If you experience crashes within one hour or less (sometimes as little as 2 minutes) of going into the main 3D world, this option may resolve your problem (which, at its core can be caused by a variety of factors including old/incompatible drivers and firmware for video cards, motherboards and BIOS chipsets).
Disabling Hardware T & L will reduce frame rates by about 15-30% on cards that support Hardware T & L (basically most video card/chipsets made since 2001, and some older ones, too). You can roughly offset this slowdown by reducing the visual detail setting by one level.
Good. At the start of this scenario, you have $150,000 in personal cash to invest. However, starting a successful railroad requires more capital than that - usually you want at least $1 million or more in starting funds for your company.
interfejsu Direct Play.
Mapa, kt
posiada rozmiary: %1 X %2. Maksymalny rozmiar dowolnego boku mapy wynosi 1024, ale zalecamy korzysta
z mniejszych map. Prosz
wyskalowana mapa:
map
lona jako mapa do trybu kampanii. Mapa ta NIE POJAWI SI
eli chcesz, aby mapa figurowa
pnie ponownie zapisz map
ry spowodowany jest przez rozmaite czynniki, w tym niekompatybilne sterowniki kart video, p
kart video wyprodukowanych po roku 2001).
s a videok
bb videok
til si quieres cambiar los objetivos de un escenario mientras juegas en
No se puede crear interfaz Direct lay.
No se puede crear interfaz Direct Play.
El mapa que est
s intentando cargar es de %1 X %2. Los mapas NO PUEDEN medir m
os. Por favor ajusta la escala de mapa a:
n: Has guardado un mapa dise
ado como mapa de campa
en la lista de escenarios en los que jugar cuando el usuario elija 'Nuevo escenario'.
n 'Escenario de campa
scenario).
Impossibile creare interfaccia Direct Play.
La mappa che stai cercando di caricare
%1 X %2. Le mappe NON possono essere pi
Attenzione: hai salvato una mappa come mappa per una campagna. NON VERR
inclusa nella lista degli scenari che compare quando l'utente seleziona 'Nuovo scenario'.
Se vuoi che la mappa compaia in quella lista, vai nel pannello di controllo dell'editor, sotto 'Generale', togli il segno di spunta da 'Scenario campagna' e salvala di nuovo.
di fattori tra cui driver e firmware vecchio/incompatibile per la scheda video, la scheda madre e il BIOS).
il frame rate di circa il 15-30% su schede con il supporto per questa tecnologia (ovvero la maggior parte delle schede video/chipset prodotti dal 2001 e anche su alcune pi
vecchie). Puoi bilanciare questo rallentamento riducendo il dettaglio video di un livello.
er l'interface Direct Play.
Direct-Play-Interface konnte nicht erstellt werden.
rt3_debug.txt
language_debug.txt
(D3D) Used VRAM: %3 Kb
.\Saved Games\
.\Maps\
.\Data\Sound\
.\Data\GrayscaleMaps\
Illegal file - map importer only supports 24 and 32 bit .TGAs
memory bitmap
DirectSound3D 7+ Software - Pan and Volume
Software\Microsoft\Direct3D
DisableD3DXPSGP
d3d8d.dll
DebugSetMute
d3d8.dll
preprocessor directives are not supported
LoadDebugRuntime
SOFTWARE\Microsoft\Direct3D
D3DX8 Shader Assembler Version 0.91
mapname
SetCurrentDirectoryA
GetCurrentDirectoryA
OutputDebugStringA
_AIL_set_redist_directory@4
mss32.dll
_BinkGetError@0
_BinkCopyToBuffer@28
_BinkClose@4
_BinkGetKeyFrame@12
_BinkWait@4
_BinkNextFrame@4
_BinkDoFrame@4
_BinkGoto@12
_BinkSetVolume@12
_BinkOpen@8
_BinkSetIOSize@4
_BinkSetSoundSystem@8
_BinkOpenMiles@4
binkw32.dll
Direct3DCreate8
DirectInput8Create
DSOUND.dll
MapViewOfFile
CreateFileMappingA
UnmapViewOfFile
LCMapStringA
LCMapStringW
CreateFontIndirectA

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,467 @@
# Pending-Template Store Management
- Target binary: `/home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3/RT3.exe`
- Scope: companion pending-template dispatch store and its adjacent management helpers.
## Init
### `0x0059b710` `multiplayer_transport_init_pending_template_dispatch_store`
- Size: `40`
- Calling convention: `cdecl`
- Callers: 0x0058f1e0@0x0058f110:multiplayer_transport_worker_init
- Direct callees: 0x0059b722->0x0059e0b0:fcn.0059e0b0
- Data refs: 0x0059b713->0x0059b2d0
- Key constants: 0x00000080; 0x00000018
- Key strings: none
Entry excerpt:
```asm
59b6f0: subb -0x4ab8ffa7(%ebp), %dh
59b6f6: popl %ecx
59b6f7: addb %cl, -0x46ffa64b(%ebp)
59b6fd: movb $0x59, %ch
59b6ff: addb %cl, (%esi,%esi,4)
59b702: popl %ecx
59b703: addb %ch, 0x59(%esi,%esi,4)
59b707: addb %dl, -0x6f6f6f70(%eax)
59b70d: nop
59b70e: nop
59b70f: nop
59b710: pushl %esi
59b711: movl %ecx, %esi
59b713: pushl $0x59b2d0 # imm = 0x59B2D0
59b718: movl $0x80, %edx
59b71d: movl $0x18, %ecx
59b722: calll 0x59e0b0 <.text+0x19d0b0>
59b727: xorl %ecx, %ecx
59b729: testl %eax, %eax
59b72b: setne %cl
59b72e: movl %eax, 0x55c(%esi)
```
### `0x0059c5b0` `growable_text_buffer_init`
- Size: `40`
- Calling convention: `cdecl`
- Callers: 0x0059c68e@0x0059c670:multiplayer_transport_text_stream_init; 0x0059c69d@0x0059c670:multiplayer_transport_text_stream_init
- Direct callees: 0x0059c5c3->0x0058f380:tracked_heap_alloc_with_header
- Data refs: none
- Key constants: 0x00002001; 0x00002000
- Key strings: none
Entry excerpt:
```asm
59c590: pushl %edi
59c591: pushl %edx
59c592: movl %ecx, %edi
59c594: calll 0x59c540 <.text+0x19b540>
59c599: xorl %ecx, %ecx
59c59b: cmpl $-0x1, %eax
59c59e: setne %cl
59c5a1: popl %edi
59c5a2: movl %ecx, %eax
59c5a4: retl
59c5a5: nop
59c5a6: nop
59c5a7: nop
59c5a8: nop
59c5a9: nop
59c5aa: nop
59c5ab: nop
59c5ac: nop
59c5ad: nop
59c5ae: nop
59c5af: nop
59c5b0: movl $0x2001, %ecx # imm = 0x2001
59c5b5: movl $0x0, 0x4(%esi)
59c5bc: movl $0x2000, 0x8(%esi) # imm = 0x2000
59c5c3: calll 0x58f380 <.text+0x18e380>
59c5c8: testl %eax, %eax
59c5ca: movl %eax, (%esi)
59c5cc: jne 0x59c5cf <.text+0x19b5cf>
59c5ce: retl
59c5cf: movb $0x0, (%eax)
```
## Destroy
### `0x0059b2e0` `multiplayer_transport_destroy_pending_template_dispatch_record`
- Size: `929`
- Calling convention: `cdecl`
- Callers: 0x0059b76f@0x0059b740:multiplayer_transport_destroy_pending_template_dispatch_store; 0x0059c245@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c259@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c275@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c295@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c2b9@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c2d1@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c2e5@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c309@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c33a@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c356@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c382@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c3a2@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c3ca@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c3e2@0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c4c1@0x0059c470:multiplayer_transport_service_pending_template_dispatch_store
- Direct callees: 0x0059b2f9->0x0058f3c0:tracked_heap_free_with_header; 0x0059b30d->0x0058f3c0:tracked_heap_free_with_header; 0x0059b321->0x0058f3c0:tracked_heap_free_with_header; 0x0059b333->0x0058f3c0:tracked_heap_free_with_header; 0x0059b33b->0x0058f3c0:tracked_heap_free_with_header; 0x0059b343->0x0058f3c0:tracked_heap_free_with_header; 0x0059b357->0x0058f3c0:tracked_heap_free_with_header; 0x0059b35f->0x0058f3c0:tracked_heap_free_with_header; 0x0059b373->0x0058f3c0:tracked_heap_free_with_header; 0x0059b388->0x0058f3c0:tracked_heap_free_with_header; 0x0059b390->0x0058f3c0:tracked_heap_free_with_header; 0x0059b3b6->0x0058f3c0:tracked_heap_free_with_header; 0x0059b3c1->0x0058f3c0:tracked_heap_free_with_header; 0x0059b3d9->0x0058f3c0:tracked_heap_free_with_header; 0x0059b3ee->0x0058f3c0:tracked_heap_free_with_header; 0x0059b3f6->0x0058f3c0:tracked_heap_free_with_header; 0x0059b40b->0x0058f3c0:tracked_heap_free_with_header; 0x0059b426->0x0058f3c0:tracked_heap_free_with_header; 0x0059b436->0x0058f3c0:tracked_heap_free_with_header; 0x0059b43e->0x0058f3c0:tracked_heap_free_with_header; 0x0059b453->0x0058f3c0:tracked_heap_free_with_header; 0x0059b45b->0x0058f3c0:tracked_heap_free_with_header; 0x0059b463->0x0058f3c0:tracked_heap_free_with_header; 0x0059b46b->0x0058f3c0:tracked_heap_free_with_header; 0x0059b486->0x0058f3c0:tracked_heap_free_with_header; 0x0059b496->0x0058f3c0:tracked_heap_free_with_header; 0x0059b4b3->0x0058f3c0:tracked_heap_free_with_header; 0x0059b4bb->0x0058f3c0:tracked_heap_free_with_header; 0x0059b4c3->0x0058f3c0:tracked_heap_free_with_header; 0x0059b4cb->0x0058f3c0:tracked_heap_free_with_header; 0x0059b4e0->0x0058f3c0:tracked_heap_free_with_header; 0x0059b4f6->0x0058f3c0:tracked_heap_free_with_header; 0x0059b506->0x0058f3c0:tracked_heap_free_with_header; 0x0059b51b->0x0058f3c0:tracked_heap_free_with_header; 0x0059b530->0x0058f3c0:tracked_heap_free_with_header; 0x0059b538->0x0058f3c0:tracked_heap_free_with_header; 0x0059b54c->0x0058f3c0:tracked_heap_free_with_header; 0x0059b566->0x0058f3c0:tracked_heap_free_with_header; 0x0059b576->0x0058f3c0:tracked_heap_free_with_header; 0x0059b57e->0x0058f3c0:tracked_heap_free_with_header; 0x0059b592->0x0058f3c0:tracked_heap_free_with_header; 0x0059b59a->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5a2->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5aa->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5bf->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5d6->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5e5->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5f5->0x0058f3c0:tracked_heap_free_with_header; 0x0059b5fd->0x0058f3c0:tracked_heap_free_with_header; 0x0059b612->0x0058f3c0:tracked_heap_free_with_header; 0x0059b61a->0x0058f3c0:tracked_heap_free_with_header; 0x0059b636->0x0058f3c0:tracked_heap_free_with_header; 0x0059b645->0x0058f3c0:tracked_heap_free_with_header; 0x0059b655->0x0058f3c0:tracked_heap_free_with_header; 0x0059b65d->0x0058f3c0:tracked_heap_free_with_header; 0x0059b672->0x0058f3c0:tracked_heap_free_with_header
- Data refs: 0x0059b2ed->0x0059b684
- Key constants: 0x00000020
- Key strings: none
Entry excerpt:
```asm
59b2c0: incl %ebx
59b2c2: nop
59b2c3: nop
59b2c4: nop
59b2c5: nop
59b2c6: nop
59b2c7: nop
59b2c8: nop
59b2c9: nop
59b2ca: nop
59b2cb: nop
59b2cc: nop
59b2cd: nop
59b2ce: nop
59b2cf: nop
59b2d0: movl 0x14(%ecx), %ecx
59b2d3: jmp 0x58f3c0 <.text+0x18e3c0>
59b2d8: nop
59b2d9: nop
59b2da: nop
59b2db: nop
59b2dc: nop
59b2dd: nop
59b2de: nop
59b2df: nop
59b2e0: movl (%esi), %eax
59b2e2: cmpl $0x20, %eax
59b2e5: pushl %edi
59b2e6: ja 0x59b678 <.text+0x19a678>
59b2ec: pushl %ebx
59b2ed: jmpl *0x59b684(,%eax,4)
59b2f4: movl 0x8(%esi), %eax
59b2f7: movl (%eax), %ecx
59b2f9: calll 0x58f3c0 <.text+0x18e3c0>
59b2fe: movl 0x8(%esi), %ecx
```
### `0x0059b740` `multiplayer_transport_destroy_pending_template_dispatch_store`
- Size: `74`
- Calling convention: `cdecl`
- Callers: 0x0058e4cf@0x0058e480:multiplayer_transport_worker_shutdown_gracefully; 0x0058f214@0x0058f110:multiplayer_transport_worker_init
- Direct callees: 0x0059b76f->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059b74f->0x0059e110:generic_vector_count; 0x0059b768->0x0059e120:generic_vector_index_ptr
- Data refs: none
- Key constants: none
- Key strings: none
Entry excerpt:
```asm
59b720: addb %al, (%eax)
59b722: calll 0x59e0b0 <.text+0x19d0b0>
59b727: xorl %ecx, %ecx
59b729: testl %eax, %eax
59b72b: setne %cl
59b72e: movl %eax, 0x55c(%esi)
59b734: popl %esi
59b735: movl %ecx, %eax
59b737: retl
59b738: nop
59b739: nop
59b73a: nop
59b73b: nop
59b73c: nop
59b73d: nop
59b73e: nop
59b73f: nop
59b740: pushl %ebp
59b741: movl %ecx, %ebp
59b743: movl 0x55c(%ebp), %ecx
59b749: testl %ecx, %ecx
59b74b: je 0x59b788 <.text+0x19a788>
59b74d: pushl %ebx
59b74e: pushl %edi
59b74f: calll 0x59e110 <.text+0x19d110>
59b754: movl %eax, %ebx
59b756: xorl %edi, %edi
59b758: testl %ebx, %ebx
59b75a: jle 0x59b77a <.text+0x19a77a>
59b75c: pushl %esi
59b75d: leal (%ecx), %ecx
```
### `0x0059c5e0` `growable_text_buffer_free`
- Size: `7`
- Calling convention: `cdecl`
- Callers: 0x0059c6a8@0x0059c670:multiplayer_transport_text_stream_init; 0x0059c7b8@0x0059c790:multiplayer_transport_text_stream_destroy; 0x0059c7c3@0x0059c790:multiplayer_transport_text_stream_destroy
- Direct callees: none
- Data refs: none
- Key constants: none
- Key strings: none
Entry excerpt:
```asm
59c5c0: andb %al, (%eax)
59c5c2: addb %ch, %al
59c5c4: movl $0x85ffff2d, %eax # imm = 0x85FFFF2D
59c5c9: rorb $0xc6, -0x3cfe8afa(%ecx)
59c5d0: addb %al, (%eax)
59c5d2: movl $0x1, %eax
59c5d7: retl
59c5d8: nop
59c5d9: nop
59c5da: nop
59c5db: nop
59c5dc: nop
59c5dd: nop
59c5de: nop
59c5df: nop
59c5e0: movl (%eax), %ecx
59c5e2: jmp 0x58f3c0 <.text+0x18e3c0>
59c5e7: nop
59c5e8: nop
59c5e9: nop
59c5ea: nop
59c5eb: nop
59c5ec: nop
59c5ed: nop
59c5ee: nop
59c5ef: nop
59c5f0: movl 0x8(%edi), %eax
59c5f3: pushl %esi
59c5f4: movl 0x4(%edi), %esi
59c5f7: addl %ecx, %esi
59c5f9: cmpl %eax, %esi
59c5fb: jle 0x59c62a <.text+0x19b62a>
59c5fd: addl $0x2000, %esi # imm = 0x2000
```
## Lookup
### `0x0059c540` `multiplayer_transport_find_pending_template_dispatch_record_index`
- Size: `72`
- Calling convention: `cdecl`
- Callers: 0x0059c594@0x0059c590:multiplayer_transport_has_pending_template_dispatch_record
- Direct callees: 0x0059c54d->0x0059e110:generic_vector_count; 0x0059c568->0x0059e120:generic_vector_index_ptr
- Data refs: none
- Key constants: 0x000000ff
- Key strings: none
Entry excerpt:
```asm
59c520: movl 0x55c(%ebx), %ecx
59c526: calll 0x59e110 <.text+0x19d110>
59c52b: cmpl %ebp, %eax
59c52d: jg 0x59c4a0 <.text+0x19b4a0>
59c533: popl %esi
59c534: popl %edi
59c535: popl %ebp
59c536: popl %ebx
59c537: addl $0x1c, %esp
59c53a: retl
59c53b: nop
59c53c: nop
59c53d: nop
59c53e: nop
59c53f: nop
59c540: movl 0x55c(%edi), %ecx
59c546: pushl %ebx
59c547: pushl %ebp
59c548: movl 0xc(%esp), %ebp
59c54c: pushl %esi
59c54d: calll 0x59e110 <.text+0x19d110>
59c552: movl %eax, %ebx
59c554: xorl %esi, %esi
59c556: testl %ebx, %ebx
59c558: jle 0x59c577 <.text+0x19b577>
59c55a: leal (%ebx), %ebx
```
### `0x0059c590` `multiplayer_transport_has_pending_template_dispatch_record`
- Size: `21`
- Calling convention: `cdecl`
- Callers: 0x0058e381@0x0058e370:multiplayer_transport_is_request_pending
- Direct callees: 0x0059c594->0x0059c540:multiplayer_transport_find_pending_template_dispatch_record_index
- Data refs: none
- Key constants: none
- Key strings: none
Entry excerpt:
```asm
59c570: je 0x59c580 <.text+0x19b580>
59c572: incl %esi
59c573: cmpl %ebx, %esi
59c575: jl 0x59c560 <.text+0x19b560>
59c577: popl %esi
59c578: popl %ebp
59c579: orl $-0x1, %eax
59c57c: popl %ebx
59c57d: retl $0x4
59c580: movl %esi, %eax
59c582: popl %esi
59c583: popl %ebp
59c584: popl %ebx
59c585: retl $0x4
59c588: nop
59c589: nop
59c58a: nop
59c58b: nop
59c58c: nop
59c58d: nop
59c58e: nop
59c58f: nop
59c590: pushl %edi
59c591: pushl %edx
59c592: movl %ecx, %edi
59c594: calll 0x59c540 <.text+0x19b540>
59c599: xorl %ecx, %ecx
59c59b: cmpl $-0x1, %eax
59c59e: setne %cl
59c5a1: popl %edi
59c5a2: movl %ecx, %eax
59c5a4: retl
59c5a5: nop
59c5a6: nop
59c5a7: nop
59c5a8: nop
59c5a9: nop
59c5aa: nop
59c5ab: nop
59c5ac: nop
59c5ad: nop
59c5ae: nop
59c5af: nop
```
## Prune / Remove
### `0x0059c470` `multiplayer_transport_service_pending_template_dispatch_store`
- Size: `203`
- Calling convention: `cdecl`
- Callers: 0x0058e470@0x0058e3f0:multiplayer_transport_drain_request_text_queue
- Direct callees: 0x0059c4c1->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c511->0x0059c220:multiplayer_transport_dispatch_pending_template_dispatch_record; 0x0059c4b8->0x0059d8d0:multiplayer_transport_has_registered_name; 0x0059c4de->0x0059d9e0:multiplayer_transport_get_registered_name_dirty; 0x0059c486->0x0059e110:generic_vector_count; 0x0059c526->0x0059e110:generic_vector_count; 0x0059c4a8->0x0059e120:generic_vector_index_ptr; 0x0059c4ce->0x0059e3d0:generic_vector_erase_with_callback; 0x0059c506->0x0059e3d0:generic_vector_erase_with_callback
- Data refs: none
- Key constants: 0x0000001c
- Key strings: none
Entry excerpt:
```asm
59c450: movl %ebx, %eax
59c452: popl %ecx
59c453: addb %dl, %bl
59c455: retl
59c456: popl %ecx
59c457: addb %ah, -0x3e(%edx)
59c45a: popl %ecx
59c45b: addb %cl, 0x7e0059c3(%ebx)
59c461: retl $0x59
59c464: sahf
59c465: retl $0x59
59c468: stosl %eax, %es:(%edi)
59c469: retl
59c46a: popl %ecx
59c46b: addb %dl, %bl
59c46d: retl
59c46e: popl %ecx
59c46f: addb %al, 0x55531cec(%ebx)
59c475: pushl %edi
59c476: movl %ecx, %ebx
59c478: movl 0x55c(%ebx), %ecx
59c47e: movl %edx, %edi
59c480: movl %edi, 0xc(%esp)
59c484: xorl %ebp, %ebp
59c486: calll 0x59e110 <.text+0x19d110>
59c48b: testl %eax, %eax
59c48d: jle 0x59c534 <.text+0x19b534>
```
## Dispatch / Update
### `0x0059c220` `multiplayer_transport_dispatch_pending_template_dispatch_record`
- Size: `459`
- Calling convention: `cdecl`
- Callers: 0x0059c511@0x0059c470:multiplayer_transport_service_pending_template_dispatch_store
- Direct callees: 0x0059c245->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c259->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c275->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c295->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c2b9->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c2d1->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c2e5->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c309->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c33a->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c356->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c382->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c3a2->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c3ca->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c3e2->0x0059b2e0:multiplayer_transport_destroy_pending_template_dispatch_record; 0x0059c322->0x0059d9c0:multiplayer_transport_mark_registered_name_dirty
- Data refs: 0x0059c233->0x0059c3ec
- Key constants: 0x00000020; 0x00000018
- Key strings: none
Entry excerpt:
```asm
59c200: xchgl %edi, %eax
59c201: movl $0xc1800059, %ebp # imm = 0xC1800059
59c206: popl %ecx
59c207: addb %bh, 0x610059be
59c20d: movl $0xbf1d0059, %esi # imm = 0xBF1D0059
59c212: popl %ecx
59c213: addb %al, -0x41(%eax)
59c216: popl %ecx
59c217: addb %dl, -0x40(%eax)
59c21a: popl %ecx
59c21b: addb %al, 0x510059c1(%eax)
59c221: pushl %ebx
59c222: pushl %esi
59c223: movl %eax, %esi
59c225: movl (%esi), %eax
59c227: cmpl $0x20, %eax
59c22a: movl 0xc(%esi), %ebx
59c22d: ja 0x59c3e2 <.text+0x19b3e2>
59c233: jmpl *0x59c3ec(,%eax,4)
59c23a: movl 0x8(%esi), %eax
59c23d: movl (%eax), %edx
59c23f: pushl %ebx
```
### `0x0059c5f0` `growable_text_buffer_reserve_append`
- Size: `65`
- Calling convention: `cdecl`
- Callers: 0x0059ca47@0x0059ca10:multiplayer_transport_text_stream_recv_pump; 0x0059cb31@0x0059caf0:multiplayer_transport_text_stream_append_crlf_line
- Direct callees: 0x0059c61a->0x0058f3f0:tracked_heap_resize_with_header
- Data refs: none
- Key constants: 0x00002000
- Key strings: none
Entry excerpt:
```asm
59c5d0: addb %al, (%eax)
59c5d2: movl $0x1, %eax
59c5d7: retl
59c5d8: nop
59c5d9: nop
59c5da: nop
59c5db: nop
59c5dc: nop
59c5dd: nop
59c5de: nop
59c5df: nop
59c5e0: movl (%eax), %ecx
59c5e2: jmp 0x58f3c0 <.text+0x18e3c0>
59c5e7: nop
59c5e8: nop
59c5e9: nop
59c5ea: nop
59c5eb: nop
59c5ec: nop
59c5ed: nop
59c5ee: nop
59c5ef: nop
59c5f0: movl 0x8(%edi), %eax
59c5f3: pushl %esi
59c5f4: movl 0x4(%edi), %esi
59c5f7: addl %ecx, %esi
59c5f9: cmpl %eax, %esi
59c5fb: jle 0x59c62a <.text+0x19b62a>
59c5fd: addl $0x2000, %esi # imm = 0x2000
59c603: movl %esi, %eax
59c605: andl $0x80001fff, %eax # imm = 0x80001FFF
59c60a: jns 0x59c613 <.text+0x19b613>
59c60c: decl %eax
59c60d: orl $0xffffe000, %eax # imm = 0xFFFFE000
```

View file

@ -0,0 +1,35 @@
record_kind,case_group,owning_function,owning_name,inferred_payload_shape,freed_fields,notes
0,0,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,top-level payload,"2 heap free call(s); mov eax, dword [esi+0x08] | mov ecx, dword [eax] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0"
1,1,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,top-level payload,"2 heap free call(s); mov ecx, dword [esi+0x08] | mov ecx, dword [ecx] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0"
2,"2,3,6,9,10,11",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
3,"2,3,6,9,10,11",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
4,"4,5,8",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08]"
5,"4,5,8",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08]"
6,"2,3,6,9,10,11",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
7,7,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,top-level payload pointer,"top-level payload, payload+0x04","1 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | jmp 0x59b4bb"
8,"4,5,8",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08]"
9,"2,3,6,9,10,11",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
10,"2,3,6,9,10,11",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
11,"2,3,6,9,10,11",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
12,12,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,top-level payload,"2 heap free call(s); mov edx, dword [esi+0x08] | mov ecx, dword [edx] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0"
13,13,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,top-level payload pointer,top-level payload,0 heap free call(s); pop ebx
14,14,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x08, payload+0x0c","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
15,15,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c","2 heap free call(s); mov edi, dword [esi+0x08] | mov eax, dword [edi+0x04] | xor ebx, ebx | test eax, eax | jle 0x59b4b8 | nop | mov eax, dword [edi+0x08] | mov ecx, dword [eax+ebx*4]"
16,16,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,top-level payload,"2 heap free call(s); mov edx, dword [esi+0x08] | mov ecx, dword [edx+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0"
17,"17,18,24,27",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
18,"17,18,24,27",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
19,19,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x0c","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
20,20,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10","5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov eax, dword [edi+0x08] | xor ebx, ebx | test eax, eax | jle 0x59b433 | lea esp, dword [esp]"
21,21,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, payload+0x14, payload+0x18, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10, vector@payload+0x14, vector@payload+0x18","7 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [edi+0x10]"
22,22,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,top-level payload pointer,top-level payload,"0 heap free call(s); mov edi, dword [esi+0x08] | jmp 0x59b597"
23,23,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,fixed pointer tuple,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10","5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [edi+0x10]"
24,"17,18,24,27",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
25,25,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c","4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov eax, dword [edi+0x08] | xor ebx, ebx | test eax, eax | jle 0x59b503 | mov edi, edi"
26,26,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,single nested pointer,"top-level payload, payload+0x04","2 heap free call(s); mov eax, dword [esi+0x08] | mov ecx, dword [eax+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0"
27,"17,18,24,27",0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08","3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi"
28,28,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c","5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov eax, dword [edi+0x04] | xor ebx, ebx | test eax, eax | jle 0x59b573 | lea ebx, dword [ebx]"
29,29,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,paired nested pointers,"top-level payload, payload+0x04, payload+0x08, payload+0x0c","5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c]"
30,30,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10","6 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov eax, dword [edi+0x08] | xor ebx, ebx | test eax, eax | jle 0x59b5f2 | lea ecx, dword [ecx]"
31,31,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,pointer vectors with paired side tables,"top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, payload+0x14, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10, vector@payload+0x14","7 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov eax, dword [edi+0x0c] | xor ebx, ebx | test eax, eax"
32,32,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,top-level payload pointer,"top-level payload, payload+0x04","1 heap free call(s); mov ecx, dword [esi+0x08] | mov ecx, dword [ecx+0x04] | call fcn.0058f3c0"
default,default,0x0059b2e0,multiplayer_transport_destroy_pending_template_dispatch_record,top-level payload pointer,top-level payload,"1 heap free call(s); mov ecx, dword [esi+0x08] | pop edi | jmp fcn.0058f3c0"
1 record_kind case_group owning_function owning_name inferred_payload_shape freed_fields notes
2 0 0 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload 2 heap free call(s); mov eax, dword [esi+0x08] | mov ecx, dword [eax] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0
3 1 1 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload 2 heap free call(s); mov ecx, dword [esi+0x08] | mov ecx, dword [ecx] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0
4 2 2,3,6,9,10,11 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
5 3 2,3,6,9,10,11 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
6 4 4,5,8 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08]
7 5 4,5,8 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08]
8 6 2,3,6,9,10,11 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
9 7 7 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record top-level payload pointer top-level payload, payload+0x04 1 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | jmp 0x59b4bb
10 8 4,5,8 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08]
11 9 2,3,6,9,10,11 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
12 10 2,3,6,9,10,11 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
13 11 2,3,6,9,10,11 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
14 12 12 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload 2 heap free call(s); mov edx, dword [esi+0x08] | mov ecx, dword [edx] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0
15 13 13 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record top-level payload pointer top-level payload 0 heap free call(s); pop ebx
16 14 14 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x08, payload+0x0c 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
17 15 15 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c 2 heap free call(s); mov edi, dword [esi+0x08] | mov eax, dword [edi+0x04] | xor ebx, ebx | test eax, eax | jle 0x59b4b8 | nop | mov eax, dword [edi+0x08] | mov ecx, dword [eax+ebx*4]
18 16 16 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload 2 heap free call(s); mov edx, dword [esi+0x08] | mov ecx, dword [edx+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0
19 17 17,18,24,27 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
20 18 17,18,24,27 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
21 19 19 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x0c 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
22 20 20 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10 5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov eax, dword [edi+0x08] | xor ebx, ebx | test eax, eax | jle 0x59b433 | lea esp, dword [esp]
23 21 21 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, payload+0x14, payload+0x18, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10, vector@payload+0x14, vector@payload+0x18 7 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [edi+0x10]
24 22 22 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record top-level payload pointer top-level payload 0 heap free call(s); mov edi, dword [esi+0x08] | jmp 0x59b597
25 23 23 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record fixed pointer tuple top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10 5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c] | call fcn.0058f3c0 | mov ecx, dword [edi+0x10]
26 24 17,18,24,27 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
27 25 25 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c 4 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov eax, dword [edi+0x08] | xor ebx, ebx | test eax, eax | jle 0x59b503 | mov edi, edi
28 26 26 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record single nested pointer top-level payload, payload+0x04 2 heap free call(s); mov eax, dword [esi+0x08] | mov ecx, dword [eax+0x04] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi | jmp fcn.0058f3c0
29 27 17,18,24,27 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08 3 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [esi+0x08] | pop ebx | pop edi
30 28 28 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c 5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov eax, dword [edi+0x04] | xor ebx, ebx | test eax, eax | jle 0x59b573 | lea ebx, dword [ebx]
31 29 29 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record paired nested pointers top-level payload, payload+0x04, payload+0x08, payload+0x0c 5 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi] | call fcn.0058f3c0 | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov ecx, dword [edi+0x0c]
32 30 30 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10 6 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov eax, dword [edi+0x08] | xor ebx, ebx | test eax, eax | jle 0x59b5f2 | lea ecx, dword [ecx]
33 31 31 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record pointer vectors with paired side tables top-level payload, payload+0x04, payload+0x08, payload+0x0c, payload+0x10, payload+0x14, vector@payload+0x04, vector@payload+0x08, vector@payload+0x0c, vector@payload+0x10, vector@payload+0x14 7 heap free call(s); mov edi, dword [esi+0x08] | mov ecx, dword [edi+0x04] | call fcn.0058f3c0 | mov ecx, dword [edi+0x08] | call fcn.0058f3c0 | mov eax, dword [edi+0x0c] | xor ebx, ebx | test eax, eax
34 32 32 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record top-level payload pointer top-level payload, payload+0x04 1 heap free call(s); mov ecx, dword [esi+0x08] | mov ecx, dword [ecx+0x04] | call fcn.0058f3c0
35 default default 0x0059b2e0 multiplayer_transport_destroy_pending_template_dispatch_record top-level payload pointer top-level payload 1 heap free call(s); mov ecx, dword [esi+0x08] | pop edi | jmp fcn.0058f3c0

View file

@ -0,0 +1,6 @@
idx,name,size_hex,vma,lma,file_offset,flags
0,.text,0x001c7000,0x00401000,0x00401000,0x00001000,"CONTENTS, ALLOC, LOAD, READONLY, CODE"
1,.rdata,0x00024adc,0x005c8000,0x005c8000,0x001c8000,"CONTENTS, ALLOC, LOAD, READONLY, DATA"
2,.data,0x0003f000,0x005ed000,0x005ed000,0x001ed000,"CONTENTS, ALLOC, LOAD, DATA"
3,.data1,0x000008e0,0x00dbc000,0x00dbc000,0x0022c000,"CONTENTS, ALLOC, LOAD, DATA"
4,.rsrc,0x0000b260,0x00dbd000,0x00dbd000,0x0022d000,"CONTENTS, ALLOC, LOAD, READONLY, DATA"
1 idx name size_hex vma lma file_offset flags
2 0 .text 0x001c7000 0x00401000 0x00401000 0x00001000 CONTENTS, ALLOC, LOAD, READONLY, CODE
3 1 .rdata 0x00024adc 0x005c8000 0x005c8000 0x001c8000 CONTENTS, ALLOC, LOAD, READONLY, DATA
4 2 .data 0x0003f000 0x005ed000 0x005ed000 0x001ed000 CONTENTS, ALLOC, LOAD, DATA
5 3 .data1 0x000008e0 0x00dbc000 0x00dbc000 0x0022c000 CONTENTS, ALLOC, LOAD, DATA
6 4 .rsrc 0x0000b260 0x00dbd000 0x00dbd000 0x0022d000 CONTENTS, ALLOC, LOAD, READONLY, DATA

View file

@ -0,0 +1,132 @@
# Startup Call Chain
- Depth limit: `2`
- Internal call targets only; imported APIs are intentionally excluded.
## `entry` root `0x005a313b` `entry`
- `0x005a313b` `entry`
- `0x00484440` `FUN_00484440` via `0x005a32b7`
- `0x0046c230` `FUN_0046c230` via `0x00484556`
- `0x0047bbd0` `FUN_0047bbd0` via `0x004844f7`
- `0x0047bbe0` `FUN_0047bbe0` via `0x0048453c`
- `0x00481d00` `FUN_00481d00` via `0x00484466`
- `0x00481fd0` `FUN_00481fd0` via `0x004844ce`
- `0x004840e0` `FUN_004840e0` via `0x00484518`
- `0x00518d50` `FUN_00518d50` via `0x0048445d`
- `0x0051d870` `FUN_0051d870` via `0x00484453`
- `0x0053b010` `FUN_0053b010` via `0x0048446b`
- `0x0053b020` `FUN_0053b020` via `0x0048456e`
- `0x0053b070` `_malloc` via `0x004844c0`
- `0x0053b080` `_free` via `0x00484527`
- `0x0054e6d0` `FUN_0054e6d0` via `0x004844b6`
- `0x0054e700` `FUN_0054e700` via `0x00484578`
- `0x0055d3a0` `FUN_0055d3a0` via `0x00484573`
- `0x0055da40` `FUN_0055da40` via `0x00484458`
- `0x005a15e0` `__chkstk` via `0x005a314e`
- `0x005a2d64` `FUN_005a2d64` via `0x005a3277`
- `0x005a10b9` `FUN_005a10b9` via `0x005a2d6d`
- `0x005a2cb0` `___onexitinit` via `0x005a2d8d`
- `0x005a2d10` `_atexit` via `0x005a2d9f`
- `0x005b1bdb` `FUN_005b1bdb` via `0x005a2dbb`
- `0x005a2e9c` `FUN_005a2e9c` via `0x005a32c7`
- `0x005a2dc9` `FUN_005a2dc9` via `0x005a2ea4`
- `0x005a2ebe` `FUN_005a2ebe` via `0x005a32cc`
- `0x005a30f2` `__amsg_exit` via `0x005a323a`
- `0x005a2ead` `__exit` via `0x005a310e`
- `0x005a3117` `fast_error_exit` via `0x005a3210`
- `0x005a2d22` `___crtExitProcess` via `0x005a3133`
- `0x005acdb0` `FUN_005acdb0` via `0x005a3129`
- `0x005acf27` `__FF_MSGBANNER` via `0x005a3120`
- `0x005a644d` `__heap_init` via `0x005a3204`
- `0x005a6433` `___heap_select` via `0x005a646d`
- `0x005a6601` `___sbh_heap_init` via `0x005a6481`
- `0x005a7124` `__SEH_prolog` via `0x005a3142`
- `0x005a715f` `__SEH_epilog` via `0x005a3307`
- `0x005abd49` `FUN_005abd49` via `0x005a3216`
- `0x005a5714` `_calloc` via `0x005abd72`
- `0x005a649e` `__mtinitlocks` via `0x005abd49`
- `0x005abcba` `FUN_005abcba` via `0x005abd62`
- `0x005abf1b` `FUN_005abf1b` via `0x005a322f`
- `0x005a125d` `_malloc` via `0x005abf25`
- `0x005b082f` `___crtInitCritSecAndSpinCount` via `0x005ac05a`
- `0x005aca5d` `FUN_005aca5d` via `0x005a3227`
- `0x005ad0c4` `FUN_005ad0c4` via `0x005a3297`
- `0x005b1a31` `FUN_005b1a31` via `0x005ad0f9`
- `0x005ad12d` `__setenvp` via `0x005a3266`
- `0x005abe90` `_strlen` via `0x005ad153`
- `0x005ac3b0` `FUN_005ac3b0` via `0x005ad1a9`
- `0x005ad360` `FUN_005ad360` via `0x005a3255`
- `0x005ad1f4` `FUN_005ad1f4` via `0x005ad3b4`
- `0x005b1297` `___initmbctable` via `0x005ad372`
- `0x005ad402` `___crtGetEnvironmentStringsA` via `0x005a324b`
- `0x005a1145` `_free` via `0x005ad4b4`
- `0x005aa9e0` `_memcpy` via `0x005ad50c`
## `bootstrap` root `0x00484440` `FUN_00484440`
- `0x00484440` `FUN_00484440`
- `0x0046c230` `FUN_0046c230` via `0x00484556`
- `0x0046bc40` `FUN_0046bc40` via `0x0046c231`
- `0x00521590` `FUN_00521590` via `0x0046c242`
- `0x00557b70` `FUN_00557b70` via `0x0046c266`
- `0x0047bbd0` `FUN_0047bbd0` via `0x004844f7`
- `0x0047bbe0` `FUN_0047bbe0` via `0x0048453c`
- `0x00481d00` `FUN_00481d00` via `0x00484466`
- `0x00481fd0` `FUN_00481fd0` via `0x004844ce`
- `0x00518de0` `FUN_00518de0` via `0x00482026`
- `0x005193f0` `FUN_005193f0` via `0x004820e4`
- `0x0051cf80` `FUN_0051cf80` via `0x004820d8`
- `0x0051d900` `FUN_0051d900` via `0x004820f0`
- `0x0051e980` `FUN_0051e980` via `0x0048211b`
- `0x005309d0` `FUN_005309d0` via `0x004820d3`
- `0x005a440d` `__close` via `0x00482085`
- `0x005a4c57` `FID_conflict:__open` via `0x00482035`
- `0x004840e0` `FUN_004840e0` via `0x00484518`
- `0x00461070` `FUN_00461070` via `0x004843f5`
- `0x00461120` `FUN_00461120` via `0x00484217`
- `0x00462560` `FUN_00462560` via `0x00484135`
- `0x004625b0` `FUN_004625b0` via `0x00484276`
- `0x00464130` `FUN_00464130` via `0x00484426`
- `0x004683f0` `FUN_004683f0` via `0x004843bd`
- `0x00468760` `FUN_00468760` via `0x00484295`
- `0x00474ce0` `FUN_00474ce0` via `0x00484369`
- `0x00474db0` `FUN_00474db0` via `0x004843af`
- `0x004821d0` `FUN_004821d0` via `0x0048427d`
- `0x00482c90` `FUN_00482c90` via `0x00484160`
- `0x00482ec0` `FUN_00482ec0` via `0x004842e8`
- `0x00483f70` `FUN_00483f70` via `0x0048439d`
- `0x00484910` `FUN_00484910` via `0x004842c6`
- `0x00484980` `FUN_00484980` via `0x00484152`
- `0x00484d70` `FUN_00484d70` via `0x0048426a`
- `0x0051d890` `FUN_0051d890` via `0x00484324`
- `0x0051d8a0` `FUN_0051d8a0` via `0x0048422f`
- `0x0051f0f0` `FUN_0051f0f0` via `0x0048438a`
- `0x0051ff90` `FUN_0051ff90` via `0x00484178`
- `0x00521060` `FUN_00521060` via `0x004841c2`
- `0x00521390` `FUN_00521390` via `0x00484406`
- `0x00521920` `FUN_00521920` via `0x004843f0`
- `0x00531750` `FUN_00531750` via `0x0048434c`
- `0x00532260` `FUN_00532260` via `0x0048431f`
- `0x0053c930` `FUN_0053c930` via `0x004841fd`
- `0x0053f000` `FUN_0053f000` via `0x004842f8`
- `0x00518d50` `FUN_00518d50` via `0x0048445d`
- `0x005a299e` `FUN_005a299e` via `0x00518d52`
- `0x0051d870` `FUN_0051d870` via `0x00484453`
- `0x0053b010` `FUN_0053b010` via `0x0048446b`
- `0x0053b020` `FUN_0053b020` via `0x0048456e`
- `0x0053ae70` `FUN_0053ae70` via `0x0053b021`
- `0x005a1145` `_free` via `0x0053b032`
- `0x0053b070` `_malloc` via `0x004844c0`
- `0x0053b080` `_free` via `0x00484527`
- `0x0054e6d0` `FUN_0054e6d0` via `0x004844b6`
- `0x0054e700` `FUN_0054e700` via `0x00484578`
- `0x0054e660` `FUN_0054e660` via `0x0054e706`
- `0x0055d3a0` `FUN_0055d3a0` via `0x00484573`
- `0x0055da40` `FUN_0055da40` via `0x00484458`
- `0x0055ccc0` `FUN_0055ccc0` via `0x0055da7d`
- `0x0055cd40` `FUN_0055cd40` via `0x0055dae3`
- `0x0055ce60` `FUN_0055ce60` via `0x0055dbd6`
- `0x0055d2f0` `FUN_0055d2f0` via `0x0055da73`
- `0x005a4376` `FUN_005a4376` via `0x0055db48`

View file

@ -0,0 +1,61 @@
# Starter Subsystem Inventory
## startup
- Evidence: DLLs: ADVAPI32.dll, KERNEL32.dll | strings: rt3_debug.txt; language_debug.txt; DebugSetMute; LoadDebugRuntime
- Status: initial hypothesis only
## ui
- Evidence: DLLs: GDI32.dll, USER32.dll, comdlg32.dll
- Status: initial hypothesis only
## render
- Evidence: DLLs: d3d8.dll | strings: Video.win; Disabling Hardware T & L may be useful in resolving/reducing problems with crashes/lockups/freezes. If you experience crashes within one hour or less (sometimes as little as 2 minutes) of going into the main 3D world, this option may resolve your problem (which, at its core can be caused by a variety of factors including old/incompatible drivers and firmware for video cards, motherboards and BIOS chipsets).; Disabling Hardware T & L will reduce frame rates by about 15-30% on cards that support Hardware T & L (basically most video card/chipsets made since 2001, and some older ones, too). You can roughly offset this slowdown by reducing the visual detail setting by one level.; Software\Microsoft\Direct3D
- Status: initial hypothesis only
## audio
- Evidence: DLLs: DSOUND.dll, mss32.dll | strings: PaintSound.win; DirectSound3D Hardware Support; .\Data\Sound\; DirectSound3D 7+ Software - Pan and Volume
- Status: initial hypothesis only
## input
- Evidence: DLLs: DINPUT8.dll | strings: DirectInput8Create
- Status: initial hypothesis only
## network
- Evidence: DLLs: WS2_32.dll, WSOCK32.dll | strings: All players will use the HOST version of the save game.; Unable to create Direct Play interface.; interfejsu Direct Play.; No se puede crear interfaz Direct Play.
- Status: initial hypothesis only
## filesystem
- Evidence: DLLs: KERNEL32.dll | strings: saved games; .\Saved Games\; .\Maps\; MapViewOfFile
- Status: initial hypothesis only
## resource
- Evidence: DLLs: VERSION.dll, ole32.dll | strings: CargoCarOverlay.imb; CargoModels; CargoIcons; AnyCargo.imb
- Status: initial hypothesis only
## map
- Evidence: strings: gptGameMap; ; Map Description; ; * The map description is displayed in a tight space and must stay fairly short.; maps\*.gmp
- Status: initial hypothesis only
## scenario
- Evidence: strings: ; Scenario Text File, version 1.1; If you want it to show up in that list, go into the editor control panel, under 'General', and uncheck the 'Campaign Scenario' checkbox, then resave it.
- Status: initial hypothesis only
## save
- Evidence: strings: Quicksave; saved games; Save Game: %1; .\Saved Games\
- Status: initial hypothesis only
## unknown
- Evidence: 48 broad strings still need manual triage
- Status: expected until GUI analysis identifies real call sites

View file

@ -0,0 +1,9 @@
[package]
name = "rrt-cli"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
rrt-model = { path = "../rrt-model" }
sha2.workspace = true

145
crates/rrt-cli/src/main.rs Normal file
View file

@ -0,0 +1,145 @@
use std::collections::BTreeSet;
use std::env;
use std::fs;
use std::io::Read;
use std::path::{Path, PathBuf};
use rrt_model::{
BINARY_SUMMARY_PATH, CANONICAL_EXE_PATH, CONTROL_LOOP_ATLAS_PATH, FUNCTION_MAP_PATH,
REQUIRED_ATLAS_HEADINGS, REQUIRED_EXPORTS, load_binary_summary, load_function_map,
};
use sha2::{Digest, Sha256};
fn main() {
if let Err(err) = real_main() {
eprintln!("error: {err}");
std::process::exit(1);
}
}
fn real_main() -> Result<(), Box<dyn std::error::Error>> {
let repo_root = parse_repo_root()?;
validate_required_files(&repo_root)?;
validate_binary_summary(&repo_root)?;
validate_function_map(&repo_root)?;
validate_control_loop_atlas(&repo_root)?;
println!("baseline validation passed");
Ok(())
}
fn parse_repo_root() -> Result<PathBuf, Box<dyn std::error::Error>> {
let mut args = env::args().skip(1);
match (args.next().as_deref(), args.next(), args.next()) {
(None, None, None) => Ok(env::current_dir()?),
(Some("validate"), None, None) => Ok(env::current_dir()?),
(Some("validate"), Some(path), None) => Ok(PathBuf::from(path)),
_ => Err("usage: rrt-cli [validate [repo-root]]".into()),
}
}
fn validate_required_files(repo_root: &Path) -> Result<(), Box<dyn std::error::Error>> {
let mut missing = Vec::new();
for relative in REQUIRED_EXPORTS {
let path = repo_root.join(relative);
if !path.exists() {
missing.push(path.display().to_string());
}
}
if !missing.is_empty() {
return Err(format!("missing required exports: {}", missing.join(", ")).into());
}
Ok(())
}
fn validate_binary_summary(repo_root: &Path) -> Result<(), Box<dyn std::error::Error>> {
let summary = load_binary_summary(&repo_root.join(BINARY_SUMMARY_PATH))?;
let actual_exe = repo_root.join(CANONICAL_EXE_PATH);
if !actual_exe.exists() {
return Err(format!("canonical exe missing: {}", actual_exe.display()).into());
}
let actual_hash = sha256_file(&actual_exe)?;
if actual_hash != summary.sha256 {
return Err(format!(
"hash mismatch for {}: summary has {}, actual file is {}",
actual_exe.display(),
summary.sha256,
actual_hash
)
.into());
}
let docs_readme = fs::read_to_string(repo_root.join("docs/README.md"))?;
if !docs_readme.contains(&summary.sha256) {
return Err("docs/README.md does not include the canonical SHA-256".into());
}
Ok(())
}
fn validate_function_map(repo_root: &Path) -> Result<(), Box<dyn std::error::Error>> {
let records = load_function_map(&repo_root.join(FUNCTION_MAP_PATH))?;
let mut seen = BTreeSet::new();
for record in records {
if !(1..=5).contains(&record.confidence) {
return Err(format!(
"invalid confidence {} for {} {}",
record.confidence, record.address, record.name
)
.into());
}
if !seen.insert(record.address) {
return Err(format!("duplicate function address {}", record.address).into());
}
if record.name.trim().is_empty() {
return Err(format!("blank function name at {}", record.address).into());
}
}
Ok(())
}
fn validate_control_loop_atlas(repo_root: &Path) -> Result<(), Box<dyn std::error::Error>> {
let atlas = fs::read_to_string(repo_root.join(CONTROL_LOOP_ATLAS_PATH))?;
for heading in REQUIRED_ATLAS_HEADINGS {
if !atlas.contains(heading) {
return Err(format!("missing atlas heading `{heading}`").into());
}
}
for marker in [
"- Roots:",
"- Trigger/Cadence:",
"- Key Dispatchers:",
"- State Anchors:",
"- Subsystem Handoffs:",
"- Evidence:",
"- Open Questions:",
] {
if !atlas.contains(marker) {
return Err(format!("atlas is missing field marker `{marker}`").into());
}
}
Ok(())
}
fn sha256_file(path: &Path) -> Result<String, Box<dyn std::error::Error>> {
let mut file = fs::File::open(path)?;
let mut hasher = Sha256::new();
let mut buffer = [0_u8; 8192];
loop {
let read = file.read(&mut buffer)?;
if read == 0 {
break;
}
hasher.update(&buffer[..read]);
}
Ok(format!("{:x}", hasher.finalize()))
}

View file

@ -0,0 +1,9 @@
[package]
name = "rrt-hook"
version.workspace = true
edition.workspace = true
license.workspace = true
[lib]
name = "dinput8"
crate-type = ["cdylib", "rlib"]

170
crates/rrt-hook/src/lib.rs Normal file
View file

@ -0,0 +1,170 @@
#![cfg_attr(not(windows), allow(dead_code))]
#[cfg(windows)]
mod windows_hook {
use core::ffi::{c_char, c_void};
use core::mem;
use core::ptr;
const DLL_PROCESS_ATTACH: u32 = 1;
const E_FAIL: i32 = 0x8000_4005_u32 as i32;
const FILE_APPEND_DATA: u32 = 0x0000_0004;
const FILE_SHARE_READ: u32 = 0x0000_0001;
const OPEN_ALWAYS: u32 = 4;
const FILE_ATTRIBUTE_NORMAL: u32 = 0x0000_0080;
const INVALID_HANDLE_VALUE: isize = -1;
const FILE_END: u32 = 2;
static LOG_PATH: &[u8] = b"rrt_hook_attach.log\0";
static ATTACH_MESSAGE: &[u8] = b"rrt-hook: process attach\n";
static DEBUG_MESSAGE: &[u8] = b"rrt-hook: DllMain process attach\0";
static DIRECT_INPUT8_CREATE_NAME: &[u8] = b"DirectInput8Create\0";
static mut REAL_DINPUT8_CREATE: Option<DirectInput8CreateFn> = None;
unsafe extern "system" {
fn CreateFileA(
lp_file_name: *const c_char,
desired_access: u32,
share_mode: u32,
security_attributes: *mut c_void,
creation_disposition: u32,
flags_and_attributes: u32,
template_file: *mut c_void,
) -> isize;
fn SetFilePointer(
file: isize,
distance: i32,
distance_high: *mut i32,
move_method: u32,
) -> u32;
fn WriteFile(
file: isize,
buffer: *const c_void,
bytes_to_write: u32,
bytes_written: *mut u32,
overlapped: *mut c_void,
) -> i32;
fn CloseHandle(handle: isize) -> i32;
fn DisableThreadLibraryCalls(module: *mut c_void) -> i32;
fn GetSystemDirectoryA(buffer: *mut u8, size: u32) -> u32;
fn GetProcAddress(module: isize, name: *const c_char) -> *mut c_void;
fn LoadLibraryA(name: *const c_char) -> isize;
fn OutputDebugStringA(output: *const c_char);
}
#[repr(C)]
pub struct Guid {
data1: u32,
data2: u16,
data3: u16,
data4: [u8; 8],
}
type DirectInput8CreateFn = unsafe extern "system" fn(
instance: *mut c_void,
version: u32,
riid: *const Guid,
out: *mut *mut c_void,
outer: *mut c_void,
) -> i32;
#[unsafe(no_mangle)]
pub extern "system" fn DllMain(
module: *mut c_void,
reason: u32,
_reserved: *mut c_void,
) -> i32 {
if reason == DLL_PROCESS_ATTACH {
unsafe {
let _ = DisableThreadLibraryCalls(module);
OutputDebugStringA(DEBUG_MESSAGE.as_ptr().cast());
append_attach_log();
}
}
1
}
#[unsafe(no_mangle)]
pub extern "system" fn DirectInput8Create(
instance: *mut c_void,
version: u32,
riid: *const Guid,
out: *mut *mut c_void,
outer: *mut c_void,
) -> i32 {
let direct_input8_create = unsafe { load_direct_input8_create() };
match direct_input8_create {
Some(callback) => unsafe { callback(instance, version, riid, out, outer) },
None => E_FAIL,
}
}
unsafe fn append_attach_log() {
let handle = unsafe {
CreateFileA(
LOG_PATH.as_ptr().cast(),
FILE_APPEND_DATA,
FILE_SHARE_READ,
ptr::null_mut(),
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
ptr::null_mut(),
)
};
if handle == INVALID_HANDLE_VALUE {
return;
}
let _ = unsafe { SetFilePointer(handle, 0, ptr::null_mut(), FILE_END) };
let mut bytes_written = 0_u32;
let _ = unsafe {
WriteFile(
handle,
ATTACH_MESSAGE.as_ptr().cast(),
ATTACH_MESSAGE.len() as u32,
&mut bytes_written,
ptr::null_mut(),
)
};
let _ = unsafe { CloseHandle(handle) };
}
unsafe fn load_direct_input8_create() -> Option<DirectInput8CreateFn> {
if let Some(callback) = unsafe { REAL_DINPUT8_CREATE } {
return Some(callback);
}
let mut system_directory = [0_u8; 260];
let length = unsafe {
GetSystemDirectoryA(system_directory.as_mut_ptr(), system_directory.len() as u32)
};
if length == 0 || length as usize >= system_directory.len() {
return None;
}
let mut dll_path = system_directory[..length as usize].to_vec();
dll_path.extend_from_slice(br"\dinput8.dll");
dll_path.push(0);
let module = unsafe { LoadLibraryA(dll_path.as_ptr().cast()) };
if module == 0 {
return None;
}
let symbol = unsafe { GetProcAddress(module, DIRECT_INPUT8_CREATE_NAME.as_ptr().cast()) };
if symbol.is_null() {
return None;
}
let callback: DirectInput8CreateFn = unsafe { mem::transmute(symbol) };
unsafe {
REAL_DINPUT8_CREATE = Some(callback);
}
Some(callback)
}
}
#[cfg(not(windows))]
pub fn host_build_marker() -> &'static str {
"rrt-hook host build"
}

View file

@ -0,0 +1,10 @@
[package]
name = "rrt-model"
version.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
csv.workspace = true
serde.workspace = true
serde_json.workspace = true

304
crates/rrt-model/src/lib.rs Normal file
View file

@ -0,0 +1,304 @@
use std::collections::BTreeMap;
use std::fmt;
use std::fs::File;
use std::path::Path;
use std::str::FromStr;
use serde::Deserialize;
use serde::de::{self, Deserializer};
pub const CANONICAL_EXE_PATH: &str = "rt3_wineprefix/drive_c/rt3/RT3.exe";
pub const CONTROL_LOOP_ATLAS_PATH: &str = "docs/control-loop-atlas.md";
pub const FUNCTION_MAP_PATH: &str = "artifacts/exports/rt3-1.06/function-map.csv";
pub const BINARY_SUMMARY_PATH: &str = "artifacts/exports/rt3-1.06/binary-summary.json";
pub const REQUIRED_EXPORTS: &[&str] = &[
BINARY_SUMMARY_PATH,
"artifacts/exports/rt3-1.06/sections.csv",
"artifacts/exports/rt3-1.06/imported-dlls.txt",
"artifacts/exports/rt3-1.06/imported-functions.csv",
"artifacts/exports/rt3-1.06/interesting-strings.txt",
"artifacts/exports/rt3-1.06/subsystem-inventory.md",
FUNCTION_MAP_PATH,
"artifacts/exports/rt3-1.06/ghidra-startup-functions.csv",
"artifacts/exports/rt3-1.06/startup-call-chain.md",
"artifacts/exports/rt3-1.06/analysis-context-functions.csv",
"artifacts/exports/rt3-1.06/analysis-context-strings.csv",
"artifacts/exports/rt3-1.06/analysis-context.md",
"artifacts/exports/rt3-1.06/pending-template-store-functions.csv",
"artifacts/exports/rt3-1.06/pending-template-store-record-kinds.csv",
"artifacts/exports/rt3-1.06/pending-template-store-management.md",
];
pub const REQUIRED_ATLAS_HEADINGS: &[&str] = &[
"## CRT and Process Startup",
"## Bootstrap and Shell Service Bring-Up",
"## Shell UI Command and Deferred Work Flow",
"## Presentation, Overlay, and Frame Timing",
"## Map and Scenario Content Load",
"## Multiplayer Session and Transport Flow",
"## Input, Save/Load, and Simulation",
"## Next Mapping Passes",
];
pub const FUNCTION_MAP_HEADER: &[&str] = &[
"address",
"size",
"name",
"subsystem",
"calling_convention",
"prototype_status",
"source_tool",
"confidence",
"notes",
"verified_against",
];
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Address(pub u32);
impl Address {
pub fn parse_hex(value: &str) -> Result<Self, String> {
let trimmed = value.trim();
let digits = trimmed
.strip_prefix("0x")
.or_else(|| trimmed.strip_prefix("0X"))
.unwrap_or(trimmed);
u32::from_str_radix(digits, 16)
.map(Self)
.map_err(|err| format!("invalid hex address `{trimmed}`: {err}"))
}
}
impl fmt::Display for Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "0x{:08x}", self.0)
}
}
impl FromStr for Address {
type Err = String;
fn from_str(value: &str) -> Result<Self, Self::Err> {
Self::parse_hex(value)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SubsystemId {
Startup,
Bootstrap,
Shell,
Support,
Ui,
Render,
Audio,
Input,
Network,
Filesystem,
Resource,
Map,
Scenario,
Save,
Simulation,
Unknown,
}
impl fmt::Display for SubsystemId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
Self::Startup => "startup",
Self::Bootstrap => "bootstrap",
Self::Shell => "shell",
Self::Support => "support",
Self::Ui => "ui",
Self::Render => "render",
Self::Audio => "audio",
Self::Input => "input",
Self::Network => "network",
Self::Filesystem => "filesystem",
Self::Resource => "resource",
Self::Map => "map",
Self::Scenario => "scenario",
Self::Save => "save",
Self::Simulation => "simulation",
Self::Unknown => "unknown",
};
f.write_str(label)
}
}
impl FromStr for SubsystemId {
type Err = String;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"startup" => Ok(Self::Startup),
"bootstrap" => Ok(Self::Bootstrap),
"shell" => Ok(Self::Shell),
"support" => Ok(Self::Support),
"ui" => Ok(Self::Ui),
"render" => Ok(Self::Render),
"audio" => Ok(Self::Audio),
"input" => Ok(Self::Input),
"network" => Ok(Self::Network),
"filesystem" => Ok(Self::Filesystem),
"resource" => Ok(Self::Resource),
"map" => Ok(Self::Map),
"scenario" => Ok(Self::Scenario),
"save" => Ok(Self::Save),
"simulation" => Ok(Self::Simulation),
"unknown" => Ok(Self::Unknown),
other => Err(format!("unknown subsystem `{other}`")),
}
}
}
impl<'de> Deserialize<'de> for SubsystemId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let raw = String::deserialize(deserializer)?;
raw.parse().map_err(de::Error::custom)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ControlLoopId {
CrtStartup,
Bootstrap,
ShellUi,
PresentationFrame,
MapScenarioLoad,
MultiplayerTransport,
InputSaveSimulation,
}
impl fmt::Display for ControlLoopId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
Self::CrtStartup => "crt-startup",
Self::Bootstrap => "bootstrap",
Self::ShellUi => "shell-ui",
Self::PresentationFrame => "presentation-frame",
Self::MapScenarioLoad => "map-scenario-load",
Self::MultiplayerTransport => "multiplayer-transport",
Self::InputSaveSimulation => "input-save-simulation",
};
f.write_str(label)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LoopRole {
Root,
Dispatcher,
Cadence,
StateAnchor,
Gateway,
}
impl fmt::Display for LoopRole {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
Self::Root => "root",
Self::Dispatcher => "dispatcher",
Self::Cadence => "cadence",
Self::StateAnchor => "state-anchor",
Self::Gateway => "gateway",
};
f.write_str(label)
}
}
#[derive(Debug, Deserialize)]
pub struct FunctionRecord {
#[serde(deserialize_with = "deserialize_address")]
pub address: Address,
#[serde(default, deserialize_with = "deserialize_optional_u32")]
pub size: Option<u32>,
pub name: String,
pub subsystem: SubsystemId,
pub calling_convention: String,
pub prototype_status: String,
pub source_tool: String,
pub confidence: u8,
pub notes: String,
pub verified_against: String,
}
#[derive(Debug, Deserialize)]
pub struct BinarySummary {
pub path: String,
pub sha256: String,
pub size_bytes: u64,
#[serde(default)]
pub summary: BTreeMap<String, String>,
}
pub fn load_function_map(path: &Path) -> Result<Vec<FunctionRecord>, Box<dyn std::error::Error>> {
let mut reader = csv::ReaderBuilder::new()
.trim(csv::Trim::All)
.from_path(path)?;
let headers = reader.headers()?.clone();
let header_values: Vec<&str> = headers.iter().collect();
if header_values != FUNCTION_MAP_HEADER {
return Err(format!("unexpected function-map header: {header_values:?}").into());
}
let mut rows = Vec::new();
for record in reader.deserialize() {
rows.push(record?);
}
Ok(rows)
}
pub fn load_binary_summary(path: &Path) -> Result<BinarySummary, Box<dyn std::error::Error>> {
let file = File::open(path)?;
Ok(serde_json::from_reader(file)?)
}
fn deserialize_address<'de, D>(deserializer: D) -> Result<Address, D::Error>
where
D: Deserializer<'de>,
{
let raw = String::deserialize(deserializer)?;
raw.parse().map_err(de::Error::custom)
}
fn deserialize_optional_u32<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
where
D: Deserializer<'de>,
{
let raw = String::deserialize(deserializer)?;
let trimmed = raw.trim();
if trimmed.is_empty() {
return Ok(None);
}
let parsed = trimmed
.parse::<u32>()
.or_else(|_| u32::from_str_radix(trimmed.trim_start_matches("0x"), 16))
.map_err(de::Error::custom)?;
Ok(Some(parsed))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_hex_addresses() {
let address = Address::parse_hex("0x005a313b").expect("address should parse");
assert_eq!(address.0, 0x005a313b);
assert_eq!(address.to_string(), "0x005a313b");
}
#[test]
fn parses_subsystems() {
let subsystem: SubsystemId = "shell".parse().expect("subsystem should parse");
assert_eq!(subsystem, SubsystemId::Shell);
assert_eq!(subsystem.to_string(), "shell");
}
}

123
docs/README.md Normal file
View file

@ -0,0 +1,123 @@
# RT3 Reverse-Engineering Handbook
This handbook is the project bootstrap for reverse-engineering and rewriting Railroad Tycoon 3.
It is written for future us first: enough structure to resume work quickly, without pretending the
project is already mature.
## Canonical Target
- Canonical executable: `rt3_wineprefix/drive_c/rt3/RT3.exe` (patch 1.06)
- Reference executable: `rt3_wineprefix/drive_c/rt3_105/RT3.exe` (patch 1.05)
- Canonical SHA-256: `01b0d2496cddefd80e7e8678930e00b13eb8607dd4960096f527564f02af36d4`
- Reference SHA-256: `9e96b0695cb722a700f99c8dce498d34da7235e562b1e275bcc1764f8c9b7eb1`
## Documents
- `setup-workstation.md`: toolchain baseline and local environment setup.
- `re-workflow.md`: how to analyze the binary, record findings, and export reusable artifacts.
- `function-map.md`: canonical schema and conventions for function-by-function mapping.
- `control-loop-atlas.md`: curated atlas of top-level loops, gateways, and subsystem handoffs.
## Repo Conventions
- `docs/`: stable project guidance and durable design notes.
- `tools/py/`: committed Python helpers for analysis and validation.
- `artifacts/exports/`: committed derived outputs that can be regenerated.
- Local-only state stays untracked: `.venv/`, Ghidra projects, Rizin databases, crash dumps, and other
bulky/generated working files.
## Current Baseline
The current technical milestone is a repeatable loop-mapping workflow for the 1.06 executable.
Before injection work or deep file-format work, we capture:
- executable hashes and PE metadata
- section layout, imports, and notable strings
- a starter subsystem inventory plus a control-loop atlas
- focused address and string context exports for branch-deepening passes
- a reusable CLI RE kit for branch dossiers where the atlas needs deeper grounding
- a stable curated function ledger in `artifacts/exports/rt3-1.06/function-map.csv`
Current coverage is broad enough to support future sessions without rediscovery, especially in:
- CRT startup and bootstrap handoff
- shell frame, layout, presentation, deferred-message, and frontend overlay flow
- Multiplayer.win UI, chat, session-event, and transport ownership
- map/scenario load and text-export paths
- shared support layers such as intrusive queues, vectors, hashed stores, and tracked heaps
README maintenance rule:
- Keep this section at subsystem level only.
- Do not mirror per-pass function additions here.
- Detailed mapping progress belongs in `artifacts/exports/rt3-1.06/function-map.csv` and the derived branch artifacts under `artifacts/exports/rt3-1.06/`.
Current local tool status:
- Ghidra is installed at `~/software/ghidra`
- `~/software/ghidra/ghidraRun` launches successfully in an interactive shell
- Rizin is installed and available on `PATH`
- `winedbg` works with `rt3_wineprefix`
- RT3 launches under `/opt/wine-stable/bin/wine` when started from `rt3_wineprefix/drive_c/rt3`
## Next Focus
The next milestone is breadth first. The highest-value passes are:
- promote `docs/control-loop-atlas.md` into the primary human-readable artifact for high-level flow
- name and connect the major loop roots and gateways for startup, shell/UI, frame or presentation,
simulation, map/scenario load, input, save/load, and multiplayer/network
- use `export_startup_map.py` and `export_analysis_context.py` to widen breadth around candidate loop
dispatchers before doing deep leaf naming
- keep the pending-template and multiplayer transport dossiers available, but treat them as targeted
deep-dive tools once a missing atlas edge needs branch-specific grounding
- stand up the Rust workspace so artifacts can be validated in code and a minimal hook DLL can be
built as soon as the 32-bit linker is present
Regenerate the initial exports with:
```bash
python3 tools/py/collect_pe_artifacts.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06
```
Regenerate the startup-focused Ghidra exports with:
```bash
python3 tools/py/export_startup_map.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06
```
That default export now walks two roots:
- `entry:0x005a313b`
- `bootstrap:0x00484440`
For a focused branch-deepening pass, regenerate the analysis context exports with:
```bash
python3 tools/py/export_analysis_context.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06 \
--addr 0x00444dd0 \
--addr 0x00508730 \
--addr 0x00508880 \
--string gpdLabelDB \
--string gpdCityDB \
--string 2DLabel.imb \
--string 2DCity.imb \
--string "Geographic Labels"
```
For the pending-template dispatch-store branch, regenerate the new branch dossier with:
```bash
python3 tools/py/rt3_rekit.py \
pending-template-store \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06
```
That dossier is now a targeted follow-up tool, not the default first pass.

View file

@ -0,0 +1,83 @@
# Control-Loop Atlas
This atlas is the high-level map for RT3 1.06. It is intentionally broader than the function map:
each section explains who owns a loop, where it starts, what dispatches it, which state blocks
anchor it, and where control is handed to neighboring subsystems.
## CRT and Process Startup
- Roots: `entry` at `0x005a313b`, CRT helpers in the `0x005a2d..0x005ad4..` range, and `app_bootstrap_main` at `0x00484440`.
- Trigger/Cadence: single process startup path before shell or engine services exist.
- Key Dispatchers: `startup_init_tls_state`, `startup_init_file_handle_table`, `startup_run_init_callback_table`, `__setenvp`, `startup_build_argv`, `___crtGetEnvironmentStringsA`, then `app_bootstrap_main`.
- State Anchors: CRT heap and file-handle tables; process environment and argv storage.
- Subsystem Handoffs: exits the generic CRT path at `app_bootstrap_main`, which becomes the first RT3-owned coordinator.
- Evidence: `artifacts/exports/rt3-1.06/startup-call-chain.md`, `artifacts/exports/rt3-1.06/function-map.csv`.
- Open Questions: exact ownership boundary between compiler CRT shims and the first game-owned bootstrap helper; whether any nontrivial startup callbacks seed game globals before `app_bootstrap_main`.
## Bootstrap and Shell Service Bring-Up
- Roots: `app_bootstrap_main` at `0x00484440` and `bootstrap_init_shell_window_services` at `0x004840e0`.
- Trigger/Cadence: one-time bootstrap handoff immediately after CRT completion.
- Key Dispatchers: `app_bootstrap_main`, `bootstrap_init_shell_window_services`, graphics config load or default-init helpers, runtime capability probes, and early shell service initializers under the `0x004610..0x0053f0..` branch.
- State Anchors: shell service bundle rooted at `0x006d4024`, display/runtime globals under `0x006d4024` and `0x006d4030`, host capability flags gathered by `bootstrap_probe_system_profile`.
- Subsystem Handoffs: hands control into shell/UI configuration, presentation defaults, and later per-frame shell work.
- Evidence: `startup-call-chain.md`, function-map rows for `app_bootstrap_main`, `bootstrap_init_shell_window_services`, `shell_load_graphics_config_or_init_defaults`, `shell_reset_display_runtime_defaults`, and related graphics setup helpers.
- Open Questions: where the first persistent main-loop owner object becomes stable; whether `0x0046c230` or one of the unnamed bootstrap children is the shell's first long-lived coordinator.
## Shell UI Command and Deferred Work Flow
- Roots: shell callback paths that converge on `shell_dispatch_ui_command` at `0x00464410`.
- Trigger/Cadence: event-driven UI command dispatch plus deferred-message queue flushing during shell activity.
- Key Dispatchers: `shell_dispatch_ui_command`, `shell_enqueue_deferred_work_message`, `shell_post_deferred_message_type5`, `shell_post_deferred_message_type6`, `shell_enqueue_deferred_message_type4`, `shell_enqueue_deferred_message_type1`.
- State Anchors: shell object at `0x0062be68`, queue roots around `[this+0x11369d]`, `[this+0x1136a1]`, and `[this+0x1136a5]`, plus global routing gates at `0x006d4034`.
- Subsystem Handoffs: routes into graphics config, scenario-text export, overlay generation, multiplayer UI, and presentation-facing deferred work.
- Evidence: function-map shell rows around `0x00464410` and `0x0051f1d0..0x0051f460`.
- Open Questions: where the deferred queues are drained in the wider frame loop; whether the shell command dispatcher is also used by hotkeys or only by UI callback tables.
## Presentation, Overlay, and Frame Timing
- Roots: shell display runtime setup and the frame-time history path under `shell_update_frame_time_history` at `0x0051fd70`.
- Trigger/Cadence: recurring shell or presentation update loop once the window and display runtime are live.
- Key Dispatchers: `shell_update_frame_time_history`, `shell_set_gamma_ramp_scalar`, overlay builders such as `shell_queue_single_world_anchor_overlay`, `shell_queue_world_anchor_overlay_list`, and `shell_queue_indexed_world_anchor_marker`.
- State Anchors: shell frame history ring at `0x006d403c`, display/runtime state inside the shell block near `[this+0x114282]` and `[this+0x11428a]`, presentation service pointer at `[this+0x0c]`.
- Subsystem Handoffs: consumes world/object state for overlays and pushes deferred presentation messages back through shell queues.
- Evidence: function-map rows for shell frame history, gamma ramp, world-anchor overlay builders, and graphics runtime helpers.
- Open Questions: the exact outer frame pump is still unnamed; simulation cadence and shell presentation cadence may be separate loops that only rendezvous through shared shell state.
## Map and Scenario Content Load
- Roots: reference-database setup via `map_bundle_open_reference_databases` at `0x00444dd0`, followed by narrower loaders such as `map_load_geographic_label_database` and `map_load_city_database`.
- Trigger/Cadence: map or scenario open paths and scenario-text export commands.
- Key Dispatchers: `map_bundle_open_reference_databases`, `map_load_geographic_label_database`, `map_load_city_database`, `scenario_text_export_build_language_file`, `scenario_text_export_report_language_file`, `scenario_text_export_batch_process_maps`.
- State Anchors: map bundle state allocated through `0x00530c80`, geography tables rooted at `0x0062b2fc` and `0x0062b268`, shell-side map-selection context.
- Subsystem Handoffs: feeds shell preview panels, scenario export tooling, and later gameplay map state.
- Evidence: function-map map/scenario rows, analysis-context exports for geographic-label and city database strings.
- Open Questions: the main gameplay map-load entrypoint is still broader than the currently grounded reference-database loaders; scenario load versus scenario-text export remain only partially overlapped.
## Multiplayer Session and Transport Flow
- Roots: Multiplayer.win session-event callback table around `0x00468de0..0x004691d0`, plus the transport object and pending-template paths around `0x00597880..0x0059caf0`.
- Trigger/Cadence: event-driven session callbacks, registered-name updates, and repeated socket I/O service steps.
- Key Dispatchers: session-event wrappers for actions `1`, `2`, `4`, `7`, `8`; `multiplayer_transport_text_stream_service_io`; `multiplayer_transport_dispatch_pending_template_node`; `multiplayer_transport_service_pending_template_dispatch_store`.
- State Anchors: live session globals at `0x006d40d0`, status latch at `0x006cd974`, pending-template list at `[this+0x550]`, dispatch store at `[this+0x55c]`, text-stream buffers at `[this+0x108]` and `[this+0x114]`.
- Subsystem Handoffs: bridges shell/UI status presentation, transport text streams, session state changes, and pending-template completion callbacks.
- Evidence: `function-map.csv`, `pending-template-store-management.md`, `pending-template-store-functions.csv`.
- Open Questions: unresolved request-id semantics for `1`, `2`, `4`, and `7`; the exact owner loop that repeatedly services transport I/O; and how multiplayer preview data ties back into the shell flow.
## Input, Save/Load, and Simulation
- Roots: not yet cleanly named in the current ledger.
- Trigger/Cadence: expected recurring gameplay or shell-driven loops, but the current evidence is still indirect.
- Key Dispatchers: currently unresolved; nearest grounded hints are `bootstrap_capture_keyboard_state`, filesystem-related strings, and shell pathways that save graphics config rather than gameplay state.
- State Anchors: input DLL import `DINPUT8.dll`, save/load path strings under `.\Saved Games\`, and map/scenario globals already observed elsewhere.
- Subsystem Handoffs: likely connect shell/UI into gameplay state, but not yet strongly evidenced in committed exports.
- Evidence: `binary-summary.json`, `imported-dlls.txt`, `subsystem-inventory.md`, and broad strings in `interesting-strings.txt`.
- Open Questions: first real input pump, first gameplay save/load dispatcher, first simulation tick owner, and the exact boundary between shell frame work and gameplay world stepping.
## Next Mapping Passes
- Name the first stable owner of the outer shell or presentation loop above the existing frame-history helpers.
- Connect the map bundle open path to the broader map/scenario load coordinator instead of only the database leaves.
- Identify the owner loop that repeatedly services multiplayer transport I/O and dispatch-store work.
- Ground the first real input ingest path and the first gameplay save/load dispatcher.
- Keep detailed pending-template or transport work scoped to the specific atlas edges that remain unresolved.

75
docs/function-map.md Normal file
View file

@ -0,0 +1,75 @@
# Function Map
The function map is the canonical ledger for reverse-engineering progress. It should be updated even
when the understanding is partial, because partial structure is still useful if it is explicit about
confidence.
The handbook index in `docs/README.md` should stay high-level. Per-pass function additions and
renames belong here and in the derived export artifacts, not in the README. High-level control-loop
and subsystem flow belongs in `docs/control-loop-atlas.md`, with this file staying function-centric.
## Canonical Schema
The committed CSV header is:
```text
address,size,name,subsystem,calling_convention,prototype_status,source_tool,confidence,notes,verified_against
```
Field meanings:
- `address`: virtual address in the canonical 1.06 executable
- `size`: best current size in bytes; leave blank if unknown
- `name`: current best function name
- `subsystem`: coarse ownership bucket such as `startup`, `bootstrap`, `support`, `render`, `audio`, `ui`, `map`, `save`, `network`
- `calling_convention`: `cdecl`, `stdcall`, `thiscall`, `fastcall`, or `unknown`
- `prototype_status`: `unknown`, `inferred`, or `confirmed`
- `source_tool`: primary tool or source behind the current row
- `confidence`: integer from `1` to `5`
- `notes`: short justification, ambiguity, or follow-up
- `verified_against`: hash, runtime trace, second tool, or other corroboration
## Update Rules
- New rows must always include `address`, `name`, `subsystem`, `source_tool`, and `confidence`.
- If a rename is speculative, state that directly in `notes`.
- When two tools disagree on function boundaries, preserve the ambiguity in `notes` instead of hiding it.
- Prefer one row per concrete function, not per guessed feature.
## Starter Subsystems
Use these buckets until the map needs finer structure:
- `startup`
- `bootstrap`
- `shell`
- `support`
- `ui`
- `render`
- `audio`
- `input`
- `network`
- `filesystem`
- `resource`
- `map`
- `scenario`
- `save`
- `simulation`
- `unknown`
## Verification Sources
Examples for `verified_against`:
- `sha256:01b0... + objdump`
- `ghidra + rizin`
- `ghidra + string xref`
- `runtime trace under winedbg`
## Exit Criteria For The Milestone
The first function-mapping milestone is complete when the repo has:
- a stable starter map for the canonical binary
- named anchors for startup and a few obvious subsystem gateways
- enough notes and exports that a future session can continue without rediscovery

217
docs/re-workflow.md Normal file
View file

@ -0,0 +1,217 @@
# Reverse-Engineering Workflow
## Goal
Produce durable, version-safe analysis that first explains high-level control loops and subsystem
handoffs, then feeds the function-by-function Rust rewrite and later DLL-based replacement work.
## Standard Loop
1. Confirm the target binary and record its hash.
2. Refresh the exported baseline artifacts.
3. Update `docs/control-loop-atlas.md` with newly grounded loop roots, dispatchers, cadence points,
state anchors, or subsystem handoffs.
4. Analyze in Ghidra.
5. Cross-check suspicious findings in Rizin or with CLI tools.
6. Update the function map with names, prototypes, ownership, confidence, and loop-relevant notes.
7. Commit regenerated exports and notes that would help future sessions.
## Baseline Export
Use the committed helper:
```bash
python3 tools/py/collect_pe_artifacts.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06
```
This export pass is expected to produce:
- `binary-summary.json`
- `sections.csv`
- `imported-dlls.txt`
- `imported-functions.csv`
- `interesting-strings.txt`
- `subsystem-inventory.md`
- `function-map.csv`
For the startup-init milestone, run the Ghidra headless export as well:
```bash
python3 tools/py/export_startup_map.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06
```
Optional flags:
```bash
python3 tools/py/export_startup_map.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06 \
--depth 2 \
--root entry:0x005a313b \
--root bootstrap:0x00484440
```
This startup pass is expected to add:
- `ghidra-startup-functions.csv`
- `startup-call-chain.md`
The raw CSV now includes root provenance columns:
- `root_name`
- `root_address`
## Context Export
For branch-deepening passes after the initial root mapping, use the committed context exporter:
```bash
python3 tools/py/export_analysis_context.py \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06 \
--addr 0x00444dd0 \
--addr 0x00508730 \
--addr 0x00508880 \
--string gpdLabelDB \
--string gpdCityDB \
--string 2DLabel.imb \
--string 2DCity.imb \
--string "Geographic Labels"
```
This pass is expected to add:
- `analysis-context-functions.csv`
- `analysis-context-strings.csv`
- `analysis-context.md`
The function CSV captures target function metadata plus caller callee and data-ref summaries.
The string CSV captures matched strings plus their code or data xrefs.
The Markdown report keeps the human-readable disassembly excerpts that are useful for the next naming pass.
Use this exporter to close missing edges in the atlas before using it for leaf-function refinement.
## Branch RE Kit
For deeper branch work after the atlas identifies a narrow unknown, use the CLI RE kit:
```bash
python3 tools/py/rt3_rekit.py \
pending-template-store \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06
```
Optional seed override:
```bash
python3 tools/py/rt3_rekit.py \
pending-template-store \
rt3_wineprefix/drive_c/rt3/RT3.exe \
artifacts/exports/rt3-1.06 \
--seed-addr 0x0059c470 \
--seed-addr 0x0059c540
```
This pass is expected to add:
- `pending-template-store-functions.csv`
- `pending-template-store-record-kinds.csv`
- `pending-template-store-management.md`
The function CSV captures the seed cluster plus adjacent discovered helpers in the same branch.
The record-kinds CSV captures the pending-template dispatch-record destructor switch cases and their
inferred payload cleanup shapes.
The Markdown dossier groups the branch into lifecycle buckets such as init destroy lookup prune and
dispatch.
This branch dossier is intentionally narrower than the atlas. Reach for it only when the broad
loop map is already clear enough that a missing branch blocks the next high-level conclusion.
## Ghidra Workflow
- Create a local project for the canonical 1.06 executable.
- Name the project after the binary version, not just `RT3`, so address notes stay version-safe.
- Import the executable without modifying repo-tracked files.
- Treat Ghidra as the primary source for function boundaries, control flow, and decompilation.
- Local launcher on this host: `~/software/ghidra/ghidraRun`
- Local headless entrypoint on this host: `~/software/ghidra/support/analyzeHeadless`
- Headless project state should live under `ghidra_projects/` and remain untracked.
- The committed wrapper defaults to the `entry` and `bootstrap` roots but can be pointed at additional roots when a milestone needs it.
## Rizin Workflow
Use Rizin as the fast second opinion when you need to:
- check section layout, entrypoints, and imports from the CLI
- confirm function boundaries or calling conventions
- script quick address-oriented inspections without reopening the GUI
## Runtime Debugging
Static analysis comes first. Use `winedbg` only after the local Wine runtime is confirmed to work with
the project prefix and a 32-bit target process. Runtime traces should be recorded back into the
function map as corroborating evidence, not treated as a replacement for static exports.
Current host note:
- `env WINEPREFIX=/home/jan/projects/rrt/rt3_wineprefix winedbg --help` works.
- RT3 launches successfully under `/opt/wine-stable/bin/wine` when the current directory is
`rt3_wineprefix/drive_c/rt3`.
- Launching from the wrong working directory can make the process exit cleanly because the game expects
its relative asset paths to resolve under `C:\\rt3`.
That means runtime work can proceed, but startup commands should always be recorded with the working
directory included.
## Naming Rules
- Names should prefer behavior over implementation detail when behavior is known.
- If behavior is only partly known, keep a neutral prefix such as `subsystem_` or `unk_`.
- Address-derived placeholder names are acceptable, but only as temporary rows.
- Every renamed function should keep a short note explaining why the name is justified.
- For high-level passes, prioritize names that clarify loop role, ownership, or handoff semantics
over names that only describe a local helper's mechanics.
## Confidence Rules
- `1`: address exists, purpose unknown
- `2`: rough subsystem guess only
- `3`: behavior inferred from control flow or strings
- `4`: prototype or side effects mostly understood
- `5`: confirmed by multiple sources or runtime evidence
## Export Policy
Commit exports that are cheap to diff and useful to reuse:
- JSON, CSV, TXT, and Markdown summaries
- function maps and subsystem inventories
- small command outputs that anchor a finding
- raw startup discovery exports from headless Ghidra
Keep these local-only:
- Ghidra projects and caches
- repo-local Ghidra runtime state under `.ghidra/`
- Rizin databases and ephemeral sessions
- temporary dumps and scratch notebooks that have not been curated
Keep the ownership split explicit:
- raw Ghidra or Rizin discovery output is derived data
- `function-map.csv` is the curated ledger and may intentionally diverge from auto-generated names
## Exit Criteria For The Broad-Mapping Milestone
The current breadth-first milestone is complete when the repo has:
- a stable starter map for the canonical binary
- a control-loop atlas covering the major top-level loops and handoff points
- named anchors for startup, shell/UI, frame/presentation, simulation, map/load, input, save/load,
and multiplayer/network flow
- enough notes and exports that a future session can continue without rediscovery

138
docs/setup-workstation.md Normal file
View file

@ -0,0 +1,138 @@
# Workstation Setup
This project targets a Linux host with Wine. The current workspace is a Debian unstable machine with
`python3`, `cargo`, `wine`, `winedbg`, `gdb`, `objdump`, `llvm-objdump`, `strings`, and Java already
present.
## Current Local State
- Ghidra install: `~/software/ghidra`
- Ghidra launcher: `~/software/ghidra/ghidraRun`
- Current Ghidra status: launches successfully in an interactive shell
- Rizin binaries: `/usr/local/bin/rizin`, `/usr/local/bin/rz-bin`, `/usr/local/bin/rz-asm`
- Project Wine prefix: `rt3_wineprefix/`
- Current prefix architecture marker: `win64`
- Preferred Wine runtime: `/opt/wine-stable/bin/wine` (`wine-11.0`)
- Current runtime status: `winedbg` works with the project prefix and RT3 launches under Wine 11 when
started from the install directory
## Required Baseline
- Linux host with Wine capable of running the RT3 install in `rt3_wineprefix/`
- A Wine setup that can run 32-bit Windows targets through the chosen prefix
- Java 21+ for Ghidra
- Python 3.13+ with `venv`
- Rust toolchain for the long-term rewrite, validation CLI, and hook DLL
- Binutils / LLVM CLI tools for quick inspection
- 32-bit MinGW linker support for `i686-pc-windows-gnu`
## Preferred Reverse-Engineering Stack
- Ghidra as the primary GUI disassembler/decompiler
- Rizin as the secondary CLI-first analysis stack
- Existing system tools for quick checks: `objdump`, `llvm-objdump`, `strings`, `gdb`, `winedbg`
## Install Policy
- Prefer upstream Ghidra releases over distro packages on this host.
- Prefer upstream Rizin releases or source builds on this host.
- Do not commit tool project databases or local installs into the repo.
- Commit only exported analysis outputs that can be regenerated.
## Local Python Environment
Create a repo-local virtual environment for committed helper scripts and quick experiments:
```bash
python3 -m venv .venv
source .venv/bin/activate
python -V
```
Start stdlib-only when possible. Add a dependency manifest only when a non-stdlib package becomes
necessary.
## Rust Toolchain
This host uses a user-local Rust install. Source it before running cargo or rustup:
```bash
. ~/.local/share/cargo/env
cargo --version
rustup target list --installed
```
The workspace expects:
- `x86_64-unknown-linux-gnu` for host tools such as `rrt-cli`
- `i686-pc-windows-gnu` for the `rrt-hook` DLL
The current missing piece on this host is the 32-bit linker driver. Install `i686-w64-mingw32-gcc`
and keep the workspace linker config pointed at that binary.
## Suggested Host Layout
- Ghidra install: `~/software/ghidra/`
- Rizin install: system package path such as `/usr/local/bin/`
- Repo-local Python environment: `.venv/`
- Local Ghidra projects: `ghidra_projects/` in the repo root or a sibling workspace
## Basic Verification
These commands should work before starting analysis:
```bash
java -version
/opt/wine-stable/bin/wine --version
objdump --version | head -n 1
llvm-objdump --version | head -n 1
python3 -m venv --help >/dev/null
```
Rust-specific verification:
```bash
. ~/.local/share/cargo/env
cargo test -p rrt-model -p rrt-cli
cargo build -p rrt-hook --target i686-pc-windows-gnu
```
If the hook build fails with `linker i686-w64-mingw32-gcc not found`, the Rust target is installed
but the MinGW PE32 linker is still missing from the host.
For the current end-to-end runtime smoke test, use:
```bash
tools/run_hook_smoke_test.sh
```
That script builds the `dinput8.dll` proxy, copies it into the local RT3 install, and launches RT3
briefly with `WINEDLLOVERRIDES=dinput8=n,b` so Wine prefers the native proxy before the builtin DLL.
`winedbg` is now part of the known-good runtime toolchain for this prefix. Verify it with:
```bash
env WINEPREFIX=/home/jan/projects/rrt/rt3_wineprefix winedbg --help
```
## Launch Pattern
RT3 is sensitive to its working directory because it uses relative paths under `.\Data\`, `.\Maps\`,
and `.\Saved Games\`. Launching it from the repo root can make it start and then exit cleanly without
showing a usable game window.
Use this exact pattern:
```bash
cd /home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3
WINEPREFIX=/home/jan/projects/rrt/rt3_wineprefix /opt/wine-stable/bin/wine RT3.exe
```
If the game appears to fail immediately, check the working directory before assuming a Wine or wow64
regression.
## Canonical Inputs
- Analyze `rt3_wineprefix/drive_c/rt3/RT3.exe` by default.
- Treat `rt3_wineprefix/drive_c/rt3_105/RT3.exe` as a reference build for later diffs.
- Record hashes before trusting any symbol map, address note, or decompilation export.

View file

View file

@ -0,0 +1,386 @@
// Export startup-oriented function metadata from the current Ghidra program.
//@category RT3
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Instruction;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ExportStartupFunctions extends GhidraScript {
private static class QueueEntry {
final Function function;
final int depth;
final String parentAddress;
final String callSite;
QueueEntry(Function function, int depth, String parentAddress, String callSite) {
this.function = function;
this.depth = depth;
this.parentAddress = parentAddress;
this.callSite = callSite;
}
}
private static class RootSpec {
final String name;
final String address;
RootSpec(String name, String address) {
this.name = name;
this.address = address;
}
}
private static class FunctionRow {
String rootName;
String rootAddress;
String address;
int depth;
String name;
long sizeBytes;
String callingConvention;
String signatureSource;
String signature;
String parentAddress;
String callSite;
}
private static class EdgeRow {
String rootName;
String rootAddress;
String parentAddress;
String childAddress;
String callSite;
}
private static class CallTarget {
final String callSite;
final Function callee;
CallTarget(String callSite, Function callee) {
this.callSite = callSite;
this.callee = callee;
}
}
@Override
protected void run() throws Exception {
String[] args = getScriptArgs();
if (args.length < 1) {
throw new RuntimeException(
"usage: ExportStartupFunctions.java <output-dir> [max-depth] [root-name:address ...]");
}
String outputDir = args[0];
int maxDepth = args.length > 1 ? Integer.parseInt(args[1]) : 2;
List<RootSpec> roots = parseRoots(args);
File output = new File(outputDir);
output.mkdirs();
List<FunctionRow> rows = new ArrayList<FunctionRow>();
List<EdgeRow> edges = new ArrayList<EdgeRow>();
for (RootSpec root : roots) {
collectRoot(rows, edges, root, maxDepth);
}
Collections.sort(rows, Comparator
.comparing((FunctionRow row) -> row.rootName)
.thenComparing(row -> row.rootAddress)
.thenComparingInt(row -> row.depth)
.thenComparing(row -> row.address));
Collections.sort(edges, Comparator
.comparing((EdgeRow row) -> row.rootName)
.thenComparing(row -> row.rootAddress)
.thenComparing(row -> row.parentAddress)
.thenComparing(row -> row.callSite)
.thenComparing(row -> row.childAddress));
writeCsv(new File(output, "ghidra-startup-functions.csv"), rows);
writeMarkdown(new File(output, "startup-call-chain.md"), rows, edges, roots, maxDepth);
}
private void collectRoot(
List<FunctionRow> rows,
List<EdgeRow> edges,
RootSpec root,
int maxDepth) {
Function rootFunction = getInternalFunction(toAddr(root.address));
if (rootFunction == null) {
throw new IllegalArgumentException("no function found at " + root.address);
}
ArrayDeque<QueueEntry> queue = new ArrayDeque<QueueEntry>();
Set<String> seen = new HashSet<String>();
queue.add(new QueueEntry(rootFunction, 0, "", ""));
while (!queue.isEmpty()) {
QueueEntry item = queue.removeFirst();
Function function = item.function;
String address = asAddress(function.getEntryPoint());
if (seen.contains(address)) {
continue;
}
seen.add(address);
FunctionRow row = new FunctionRow();
row.rootName = root.name;
row.rootAddress = root.address;
row.address = address;
row.depth = item.depth;
row.name = function.getName();
row.sizeBytes = function.getBody().getNumAddresses();
row.callingConvention = safeString(function.getCallingConventionName(), "unknown");
row.signatureSource = safeSignatureSource(function);
row.signature = safeSignature(function);
row.parentAddress = item.parentAddress;
row.callSite = item.callSite;
rows.add(row);
if (!item.parentAddress.isEmpty()) {
EdgeRow edge = new EdgeRow();
edge.rootName = root.name;
edge.rootAddress = root.address;
edge.parentAddress = item.parentAddress;
edge.childAddress = address;
edge.callSite = item.callSite;
edges.add(edge);
}
if (item.depth >= maxDepth) {
continue;
}
for (CallTarget callTarget : iterInternalCalls(function)) {
queue.add(new QueueEntry(
callTarget.callee,
item.depth + 1,
address,
callTarget.callSite));
}
}
}
private List<RootSpec> parseRoots(String[] args) {
List<RootSpec> roots = new ArrayList<RootSpec>();
if (args.length <= 2) {
roots.add(new RootSpec("entry", "0x005a313b"));
return roots;
}
for (int index = 2; index < args.length; index++) {
String token = args[index];
int separator = token.indexOf(':');
if (separator <= 0 || separator == token.length() - 1) {
throw new IllegalArgumentException("root spec must be name:address: " + token);
}
roots.add(new RootSpec(token.substring(0, separator), token.substring(separator + 1)));
}
return roots;
}
private Function getInternalFunction(Address address) {
Function function = getFunctionAt(address);
if (function == null) {
function = getFunctionContaining(address);
}
if (function != null && function.isExternal()) {
return null;
}
return function;
}
private List<CallTarget> iterInternalCalls(Function function) {
List<CallTarget> result = new ArrayList<CallTarget>();
Set<String> seenCalls = new HashSet<String>();
var instructions = currentProgram.getListing().getInstructions(function.getBody(), true);
while (instructions.hasNext() && !monitor.isCancelled()) {
Instruction instruction = instructions.next();
if (!instruction.getFlowType().isCall()) {
continue;
}
Address[] flows = instruction.getFlows();
for (Address flow : flows) {
Function callee = getInternalFunction(flow);
if (callee == null) {
continue;
}
String key = asAddress(instruction.getAddress()) + "->" + asAddress(callee.getEntryPoint());
if (seenCalls.contains(key)) {
continue;
}
seenCalls.add(key);
result.add(new CallTarget(asAddress(instruction.getAddress()), callee));
}
}
return result;
}
private void writeCsv(File path, List<FunctionRow> rows) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(path));
try {
writer.write(
"root_name,root_address,address,depth,name,size_bytes,calling_convention,signature_source,signature,parent_address,call_site\n");
for (FunctionRow row : rows) {
writer.write(csv(row.rootName));
writer.write(",");
writer.write(csv(row.rootAddress));
writer.write(",");
writer.write(csv(row.address));
writer.write(",");
writer.write(csv(Integer.toString(row.depth)));
writer.write(",");
writer.write(csv(row.name));
writer.write(",");
writer.write(csv(Long.toString(row.sizeBytes)));
writer.write(",");
writer.write(csv(row.callingConvention));
writer.write(",");
writer.write(csv(row.signatureSource));
writer.write(",");
writer.write(csv(row.signature));
writer.write(",");
writer.write(csv(row.parentAddress));
writer.write(",");
writer.write(csv(row.callSite));
writer.write("\n");
}
}
finally {
writer.close();
}
}
private void writeMarkdown(
File path,
List<FunctionRow> rows,
List<EdgeRow> edges,
List<RootSpec> roots,
int maxDepth) throws IOException {
Map<String, FunctionRow> byAddress = new HashMap<String, FunctionRow>();
Map<String, List<EdgeRow>> children = new HashMap<String, List<EdgeRow>>();
for (FunctionRow row : rows) {
byAddress.put(keyedAddress(row.rootName, row.rootAddress, row.address), row);
}
for (EdgeRow edge : edges) {
children.computeIfAbsent(
keyedAddress(edge.rootName, edge.rootAddress, edge.parentAddress),
ignored -> new ArrayList<EdgeRow>()).add(edge);
}
for (List<EdgeRow> childList : children.values()) {
Collections.sort(childList, Comparator.comparing(edge -> edge.childAddress));
}
BufferedWriter writer = new BufferedWriter(new FileWriter(path));
try {
writer.write("# Startup Call Chain\n\n");
writer.write("- Depth limit: `" + maxDepth + "`\n");
writer.write("- Internal call targets only; imported APIs are intentionally excluded.\n\n");
for (RootSpec root : roots) {
FunctionRow row = byAddress.get(keyedAddress(root.name, root.address, root.address));
if (row == null) {
continue;
}
writer.write("## `" + root.name + "` root `" + row.address + "` `" + row.name + "`\n\n");
writer.write("- `" + row.address + "` `" + row.name + "`\n");
HashSet<String> visited = new HashSet<String>();
visited.add(keyedAddress(root.name, root.address, row.address));
emitChildren(writer, root.name, root.address, row.address, 1, children, byAddress, visited);
writer.write("\n");
}
}
finally {
writer.close();
}
}
private void emitChildren(
BufferedWriter writer,
String rootName,
String rootAddress,
String address,
int indent,
Map<String, List<EdgeRow>> children,
Map<String, FunctionRow> byAddress,
Set<String> visited) throws IOException {
List<EdgeRow> childRows = children.get(keyedAddress(rootName, rootAddress, address));
if (childRows == null) {
return;
}
for (EdgeRow edge : childRows) {
String childKey = keyedAddress(edge.rootName, edge.rootAddress, edge.childAddress);
FunctionRow child = byAddress.get(childKey);
if (child == null || visited.contains(childKey)) {
continue;
}
visited.add(childKey);
writer.write(" ".repeat(indent));
writer.write("- `" + child.address + "` `" + child.name + "` via `" + edge.callSite + "`\n");
emitChildren(
writer,
edge.rootName,
edge.rootAddress,
child.address,
indent + 1,
children,
byAddress,
visited);
}
}
private String keyedAddress(String rootName, String rootAddress, String address) {
return rootName + "|" + rootAddress + "|" + address;
}
private String safeSignature(Function function) {
try {
return function.getPrototypeString(true, false);
}
catch (Exception ignored) {
return "";
}
}
private String safeSignatureSource(Function function) {
try {
return function.getSignatureSource().toString();
}
catch (Exception ignored) {
return "";
}
}
private String asAddress(Address address) {
return "0x" + address.toString();
}
private String safeString(String value, String fallback) {
if (value == null || value.isEmpty()) {
return fallback;
}
return value;
}
private String csv(String value) {
if (value == null) {
value = "";
}
return "\"" + value.replace("\"", "\"\"") + "\"";
}
}

View file

@ -0,0 +1,314 @@
#!/usr/bin/env python3
from __future__ import annotations
import csv
import hashlib
import json
import re
import subprocess
import sys
from pathlib import Path
SUMMARY_KEYS = {
"Time/Date",
"Magic",
"AddressOfEntryPoint",
"ImageBase",
"Subsystem",
"SizeOfImage",
"SizeOfCode",
"SizeOfInitializedData",
"BaseOfCode",
"BaseOfData",
}
KEYWORDS = (
"rail",
"cargo",
"map",
"save",
"scenario",
"debug",
"bink",
"mss",
"direct",
"sound",
"video",
"d3d",
)
SUBSYSTEM_HINTS = {
"startup": {
"dlls": {"KERNEL32.dll", "ADVAPI32.dll"},
"strings": ("debug", "OutputDebugStringA"),
},
"ui": {
"dlls": {"USER32.dll", "comdlg32.dll", "GDI32.dll"},
"strings": ("MessageBoxA", "CreateWindowExA"),
},
"render": {
"dlls": {"d3d8.dll"},
"strings": ("Direct3D", "Hardware T & L", "Video.win"),
},
"audio": {
"dlls": {"mss32.dll", "DSOUND.dll"},
"strings": ("DirectSound", "PaintSound.win", "Data\\Sound"),
},
"input": {
"dlls": {"DINPUT8.dll"},
"strings": ("DirectInput8Create",),
},
"network": {
"dlls": {"WS2_32.dll", "WSOCK32.dll"},
"strings": ("Direct Play", "HOST version"),
},
"filesystem": {
"dlls": {"KERNEL32.dll"},
"strings": ("Saved Games", ".\\Maps\\", "MapViewOfFile"),
},
"resource": {
"dlls": {"VERSION.dll", "ole32.dll"},
"strings": ("CargoIcons", "CargoModels", ".imb"),
},
"map": {
"dlls": set(),
"strings": ("gptGameMap", "maps\\*.gmp", "Map Description"),
},
"scenario": {
"dlls": set(),
"strings": ("Scenario Text File", "Campaign Scenario"),
},
"save": {
"dlls": set(),
"strings": ("Quicksave", "Save Game:", "Saved Games"),
},
}
def run_command(*args: str) -> str:
return subprocess.run(
args,
check=True,
text=True,
capture_output=True,
).stdout
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def parse_summary(text: str) -> dict[str, str]:
summary: dict[str, str] = {}
for line in text.splitlines():
line = line.strip()
if not line:
continue
match = re.match(r"([A-Za-z/]+)\s+(.+)", line)
if not match:
continue
key, value = match.groups()
if key in SUMMARY_KEYS:
summary[key] = value.strip()
return summary
def parse_sections(text: str) -> list[dict[str, str]]:
sections: list[dict[str, str]] = []
lines = text.splitlines()
for index, line in enumerate(lines):
match = re.match(
r"\s*(\d+)\s+(\S+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)",
line,
)
if not match:
continue
idx, name, size, vma, lma, file_off = match.groups()
flags = lines[index + 1].strip() if index + 1 < len(lines) else ""
sections.append(
{
"idx": idx,
"name": name,
"size_hex": f"0x{size.lower()}",
"vma": f"0x{vma.lower()}",
"lma": f"0x{lma.lower()}",
"file_offset": f"0x{file_off.lower()}",
"flags": flags,
}
)
return sections
def parse_imports(text: str) -> tuple[list[str], list[dict[str, str]]]:
dlls: list[str] = []
functions: list[dict[str, str]] = []
current_dll = ""
in_imports = False
for raw_line in text.splitlines():
line = raw_line.rstrip()
dll_match = re.match(r"\s*DLL Name:\s+(.+)", line)
if dll_match:
current_dll = dll_match.group(1).strip()
dlls.append(current_dll)
in_imports = False
continue
if "Hint/Ord" in line and "Name" in line:
in_imports = True
continue
if not in_imports or not current_dll:
continue
fn_match = re.match(r"\s*([0-9]+)\s+(.+)", line)
if fn_match:
hint, name = fn_match.groups()
functions.append({"dll": current_dll, "hint": hint, "name": name.strip()})
elif line.strip() == "":
in_imports = False
return dlls, functions
def interesting_strings(text: str) -> list[str]:
hits: list[str] = []
seen: set[str] = set()
for line in text.splitlines():
lowered = line.lower()
if any(keyword in lowered for keyword in KEYWORDS):
stripped = line.strip()
if stripped and stripped not in seen:
hits.append(stripped)
seen.add(stripped)
return hits
def build_subsystem_inventory(dlls: list[str], strings_found: list[str]) -> str:
present_dlls = set(dlls)
lower_strings = [entry.lower() for entry in strings_found]
lines = ["# Starter Subsystem Inventory", ""]
for name, hints in SUBSYSTEM_HINTS.items():
matched_dlls = sorted(present_dlls.intersection(hints["dlls"]))
matched_strings = [
entry
for entry in strings_found
if any(marker.lower() in entry.lower() for marker in hints["strings"])
]
if not matched_dlls and not matched_strings:
continue
evidence = []
if matched_dlls:
evidence.append("DLLs: " + ", ".join(matched_dlls))
if matched_strings:
evidence.append("strings: " + "; ".join(matched_strings[:4]))
lines.append(f"## {name}")
lines.append("")
lines.append("- Evidence: " + " | ".join(evidence))
lines.append("- Status: initial hypothesis only")
lines.append("")
unknown_count = sum(1 for entry in lower_strings if "debug" in entry or "map" in entry)
lines.append("## unknown")
lines.append("")
lines.append(f"- Evidence: {unknown_count} broad strings still need manual triage")
lines.append("- Status: expected until GUI analysis identifies real call sites")
lines.append("")
return "\n".join(lines)
def write_csv(path: Path, fieldnames: list[str], rows: list[dict[str, str]]) -> None:
with path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)
def main() -> int:
if len(sys.argv) != 3:
print("usage: collect_pe_artifacts.py <exe-path> <output-dir>", file=sys.stderr)
return 2
exe_path = Path(sys.argv[1]).resolve()
out_dir = Path(sys.argv[2]).resolve()
out_dir.mkdir(parents=True, exist_ok=True)
file_output = run_command("file", str(exe_path)).strip()
section_output = run_command("objdump", "-h", str(exe_path))
pe_output = run_command("llvm-objdump", "-p", str(exe_path))
strings_output = run_command("strings", "-n", "4", str(exe_path))
summary = parse_summary(pe_output)
sections = parse_sections(section_output)
dlls, functions = parse_imports(pe_output)
strings_found = interesting_strings(strings_output)
summary_payload = {
"path": str(exe_path),
"sha256": sha256(exe_path),
"size_bytes": exe_path.stat().st_size,
"file": file_output,
"summary": summary,
"imported_dll_count": len(dlls),
"imported_function_count": len(functions),
}
(out_dir / "binary-summary.json").write_text(
json.dumps(summary_payload, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
)
write_csv(
out_dir / "sections.csv",
["idx", "name", "size_hex", "vma", "lma", "file_offset", "flags"],
sections,
)
(out_dir / "imported-dlls.txt").write_text("\n".join(dlls) + "\n", encoding="utf-8")
write_csv(out_dir / "imported-functions.csv", ["dll", "hint", "name"], functions)
(out_dir / "interesting-strings.txt").write_text(
"\n".join(strings_found) + "\n",
encoding="utf-8",
)
(out_dir / "subsystem-inventory.md").write_text(
build_subsystem_inventory(dlls, strings_found),
encoding="utf-8",
)
entry_rva = summary.get("AddressOfEntryPoint", "")
image_base = summary.get("ImageBase", "")
entry_va = ""
if entry_rva and image_base:
entry_va = hex(int(entry_rva, 16) + int(image_base, 16))
write_csv(
out_dir / "function-map.csv",
[
"address",
"size",
"name",
"subsystem",
"calling_convention",
"prototype_status",
"source_tool",
"confidence",
"notes",
"verified_against",
],
[
{
"address": entry_va,
"size": "",
"name": "entrypoint_1_06",
"subsystem": "startup",
"calling_convention": "unknown",
"prototype_status": "unknown",
"source_tool": "llvm-objdump",
"confidence": "2",
"notes": "Seed row from PE header entrypoint; function boundary still needs GUI confirmation.",
"verified_against": f"sha256:{summary_payload['sha256']}",
}
],
)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,522 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import csv
import json
import re
import subprocess
import sys
from bisect import bisect_right
from functools import lru_cache
from pathlib import Path
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Export reusable address and string context for focused RT3 analysis passes."
)
parser.add_argument("exe_path", type=Path)
parser.add_argument("output_dir", type=Path)
parser.add_argument(
"--addr",
action="append",
default=[],
help="Function or code address in hex. May be repeated.",
)
parser.add_argument(
"--string",
action="append",
default=[],
help="String text to resolve. May be repeated.",
)
args = parser.parse_args()
if not args.addr and not args.string:
parser.error("at least one --addr or --string target is required")
return args
def parse_hex(text: str) -> int:
value = text.strip().lower()
if value.startswith("0x"):
value = value[2:]
return int(value, 16)
def fmt_addr(value: int) -> str:
return f"0x{value:08x}"
def display_string(text: str) -> str:
return text.encode("unicode_escape").decode("ascii")
def clean_json_payload(text: str) -> str:
stripped = text.strip()
if not stripped:
raise ValueError("rizin returned empty output")
starts = [index for index in (stripped.find("["), stripped.find("{")) if index >= 0]
if not starts:
raise ValueError("rizin did not return JSON")
return stripped[min(starts) :]
def run_rizin_json(exe_path: Path, command: str) -> object:
result = subprocess.run(
[
"rizin",
"-q",
"-e",
"scr.color=false",
"-c",
command,
str(exe_path),
],
check=True,
capture_output=True,
text=True,
)
return json.loads(clean_json_payload(result.stdout))
def run_objdump_excerpt(exe_path: Path, address: int, radius: int = 0x20) -> str:
start = max(address - radius, 0)
stop = address + radius
result = subprocess.run(
[
"llvm-objdump",
"-d",
"--no-show-raw-insn",
f"--start-address={fmt_addr(start)}",
f"--stop-address={fmt_addr(stop)}",
str(exe_path),
],
check=True,
capture_output=True,
text=True,
)
lines = [
line.rstrip()
for line in result.stdout.splitlines()
if re.match(r"^\s*[0-9a-fA-F]+:", line)
]
return "\n".join(lines)
def load_curated_rows(path: Path) -> dict[int, dict[str, str]]:
if not path.exists():
return {}
with path.open(newline="", encoding="utf-8") as handle:
rows = csv.DictReader(handle)
return {parse_hex(row["address"]): dict(row) for row in rows}
class FunctionIndex:
def __init__(self, rows: list[dict[str, object]], curated_names: dict[int, str]):
self.rows = sorted(rows, key=lambda row: int(row["offset"]))
self.by_start = {int(row["offset"]): row for row in self.rows}
self.starts = [int(row["offset"]) for row in self.rows]
self.curated_names = curated_names
def get_exact(self, address: int) -> dict[str, object] | None:
return self.by_start.get(address)
def find_containing(self, address: int) -> dict[str, object] | None:
index = bisect_right(self.starts, address) - 1
if index < 0:
return None
row = self.rows[index]
start = int(row["offset"])
end = int(row.get("maxbound", start + int(row.get("size", 0))))
if start <= address < end:
return row
return None
def preferred_name(self, row: dict[str, object]) -> str:
start = int(row["offset"])
return self.curated_names.get(start, str(row["name"]))
class ContextExporter:
def __init__(self, exe_path: Path, output_dir: Path):
self.exe_path = exe_path.resolve()
self.output_dir = output_dir.resolve()
self.output_dir.mkdir(parents=True, exist_ok=True)
curated_map = self.output_dir / "function-map.csv"
self.curated_rows = load_curated_rows(curated_map)
self.curated_names = {
address: row["name"] for address, row in self.curated_rows.items()
}
self.function_index = FunctionIndex(
self.load_function_rows(),
self.curated_names,
)
self.strings = list(run_rizin_json(self.exe_path, "izzj"))
self.strings_by_addr = {int(entry["vaddr"]): entry for entry in self.strings}
def load_function_rows(self) -> list[dict[str, object]]:
rows = list(run_rizin_json(self.exe_path, "aaa; aflj"))
known_starts = {int(row["offset"]) for row in rows}
missing_curated = sorted(address for address in self.curated_names if address not in known_starts)
if not missing_curated:
return rows
define_cmd = "aaa; " + "; ".join(
f"af @ {fmt_addr(address)}" for address in missing_curated
) + "; aflj"
return list(run_rizin_json(self.exe_path, define_cmd))
@lru_cache(maxsize=None)
def xrefs_to(self, address: int) -> list[dict[str, object]]:
return list(run_rizin_json(self.exe_path, f"aaa; axtj @ {fmt_addr(address)}"))
@lru_cache(maxsize=None)
def excerpt(self, address: int) -> str:
return run_objdump_excerpt(self.exe_path, address)
def fallback_function(self, address: int) -> dict[str, object] | None:
curated = self.curated_rows.get(address)
if curated is None:
return None
size = int(curated["size"])
return {
"offset": address,
"name": curated["name"],
"size": size,
"maxbound": address + size,
"calltype": curated["calling_convention"],
"signature": "",
"codexrefs": self.xrefs_to(address),
"callrefs": [],
"datarefs": [],
"synthetic": True,
}
def resolve_target_function(self, address: int) -> dict[str, object] | None:
exact = self.function_index.get_exact(address)
if exact is not None:
return exact
fallback = self.fallback_function(address)
if fallback is not None:
return fallback
return self.function_index.find_containing(address)
def resolve_string_matches(self, query: str) -> list[tuple[str, dict[str, object]]]:
exact = [entry for entry in self.strings if str(entry.get("string", "")) == query]
if exact:
return [("exact", entry) for entry in exact]
partial = [entry for entry in self.strings if query in str(entry.get("string", ""))]
return [("substring", entry) for entry in partial]
def format_callers(self, row: dict[str, object]) -> list[dict[str, object]]:
callers: list[dict[str, object]] = []
for ref in row.get("codexrefs", []):
if ref.get("type") != "CALL":
continue
call_site = int(ref["from"])
caller = self.function_index.find_containing(call_site)
callers.append(
{
"call_site": call_site,
"function": caller,
}
)
callers.sort(key=lambda entry: entry["call_site"])
return callers
def format_callees(self, row: dict[str, object]) -> list[dict[str, object]]:
callees: list[dict[str, object]] = []
seen: set[tuple[int, int]] = set()
for ref in row.get("callrefs", []):
if ref.get("type") != "CALL":
continue
call_site = int(ref["from"])
callee_site = int(ref["to"])
callee = self.function_index.find_containing(callee_site)
if callee is None:
continue
key = (call_site, int(callee["offset"]))
if key in seen:
continue
seen.add(key)
callees.append(
{
"call_site": call_site,
"function": callee,
}
)
callees.sort(key=lambda entry: (int(entry["function"]["offset"]), entry["call_site"]))
return callees
def format_data_refs(self, row: dict[str, object]) -> list[dict[str, object]]:
refs: list[dict[str, object]] = []
seen: set[tuple[int, int, str]] = set()
for ref in row.get("datarefs", []):
from_addr = int(ref["from"])
to_addr = int(ref["to"])
ref_type = str(ref.get("type", "DATA"))
key = (from_addr, to_addr, ref_type)
if key in seen:
continue
seen.add(key)
refs.append(
{
"from": from_addr,
"to": to_addr,
"type": ref_type,
"string": self.strings_by_addr.get(to_addr),
}
)
refs.sort(key=lambda entry: (entry["to"], entry["from"]))
return refs
def build_function_rows(self, targets: list[int]) -> list[dict[str, str]]:
rows: list[dict[str, str]] = []
for query_address in sorted(dict.fromkeys(targets)):
function = self.resolve_target_function(query_address)
if function is None:
raise ValueError(f"no function found for {fmt_addr(query_address)}")
callers = self.format_callers(function)
callees = self.format_callees(function)
data_refs = self.format_data_refs(function)
rows.append(
{
"query_address": fmt_addr(query_address),
"function_address": fmt_addr(int(function["offset"])),
"name": self.function_index.preferred_name(function),
"size": str(function["size"]),
"calling_convention": str(function.get("calltype", "unknown")),
"signature": str(function.get("signature", "")),
"caller_count": str(len(callers)),
"callers": "; ".join(
self.describe_caller(entry["call_site"], entry["function"])
for entry in callers
),
"callee_count": str(len(callees)),
"callees": "; ".join(
self.describe_callee(entry["call_site"], entry["function"])
for entry in callees
),
"data_ref_count": str(len(data_refs)),
"data_refs": "; ".join(self.describe_data_ref(entry) for entry in data_refs),
"entry_excerpt": self.excerpt(int(function["offset"])).replace("\n", " | "),
}
)
return rows
def build_string_rows(self, targets: list[str]) -> list[dict[str, str]]:
rows: list[dict[str, str]] = []
for query in targets:
matches = self.resolve_string_matches(query)
if not matches:
raise ValueError(f"no string match found for {query!r}")
for match_kind, string_entry in matches:
address = int(string_entry["vaddr"])
xrefs = self.xrefs_to(address)
rows.append(
{
"query_text": query,
"match_kind": match_kind,
"string_address": fmt_addr(address),
"string_text": display_string(str(string_entry["string"])),
"xref_count": str(len(xrefs)),
"xrefs": "; ".join(self.describe_string_xref(entry) for entry in xrefs),
}
)
rows.sort(key=lambda row: (row["query_text"], row["string_address"]))
return rows
def describe_caller(self, call_site: int, function: dict[str, object] | None) -> str:
if function is None:
return fmt_addr(call_site)
return (
f"{fmt_addr(call_site)}@{fmt_addr(int(function['offset']))}:"
f"{self.function_index.preferred_name(function)}"
)
def describe_callee(self, call_site: int, function: dict[str, object] | None) -> str:
if function is None:
return fmt_addr(call_site)
return (
f"{fmt_addr(call_site)}->{fmt_addr(int(function['offset']))}:"
f"{self.function_index.preferred_name(function)}"
)
def describe_data_ref(self, entry: dict[str, object]) -> str:
target = fmt_addr(int(entry["to"]))
string_entry = entry["string"]
if string_entry is not None:
target += f':"{display_string(str(string_entry["string"]))}"'
return f"{fmt_addr(int(entry['from']))}->{target}"
def describe_string_xref(self, entry: dict[str, object]) -> str:
from_addr = int(entry["from"])
ref_type = str(entry.get("type", "DATA"))
function = self.function_index.find_containing(from_addr)
if function is None:
return f"{fmt_addr(from_addr)}:{ref_type}"
return (
f"{fmt_addr(from_addr)}@{fmt_addr(int(function['offset']))}:"
f"{self.function_index.preferred_name(function)}:{ref_type}"
)
def write_csv(self, path: Path, rows: list[dict[str, str]]) -> None:
if not rows:
return
with path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
def write_markdown(self, function_targets: list[int], string_targets: list[str]) -> None:
lines = [
"# Analysis Context",
"",
f"- Target binary: `{self.exe_path}`",
"- Function names prefer the curated ledger when a committed mapping exists.",
"",
]
if function_targets:
lines.extend(["## Function Targets", ""])
for query_address in sorted(dict.fromkeys(function_targets)):
function = self.resolve_target_function(query_address)
if function is None:
continue
function_address = int(function["offset"])
callers = self.format_callers(function)
callees = self.format_callees(function)
data_refs = self.format_data_refs(function)
lines.append(
f"### `{fmt_addr(query_address)}` -> `{fmt_addr(function_address)}` `{self.function_index.preferred_name(function)}`"
)
lines.append("")
lines.append(f"- Size: `{function['size']}`")
lines.append(f"- Calling convention: `{function.get('calltype', 'unknown')}`")
lines.append(f"- Signature: `{function.get('signature', '')}`")
lines.append("")
lines.append("Entry excerpt:")
lines.append("")
lines.append("```asm")
lines.append(self.excerpt(function_address))
lines.append("```")
lines.append("")
lines.append("Callers:")
for entry in callers:
function_row = entry["function"]
if function_row is None:
lines.append(f"- `{fmt_addr(entry['call_site'])}`")
else:
lines.append(
f"- `{fmt_addr(entry['call_site'])}` in `{fmt_addr(int(function_row['offset']))}` `{self.function_index.preferred_name(function_row)}`"
)
if not callers:
lines.append("- none")
lines.append("")
if callers:
lines.append("Caller xref excerpts:")
lines.append("")
for entry in callers:
lines.append(f"#### `{fmt_addr(entry['call_site'])}`")
lines.append("")
lines.append("```asm")
lines.append(self.excerpt(entry["call_site"]))
lines.append("```")
lines.append("")
lines.append("Direct internal callees:")
for entry in callees:
function_row = entry["function"]
lines.append(
f"- `{fmt_addr(entry['call_site'])}` -> `{fmt_addr(int(function_row['offset']))}` `{self.function_index.preferred_name(function_row)}`"
)
if not callees:
lines.append("- none")
lines.append("")
lines.append("Data refs:")
for entry in data_refs:
target = fmt_addr(int(entry["to"]))
string_entry = entry["string"]
if string_entry is not None:
lines.append(
f'- `{fmt_addr(int(entry["from"]))}` -> `{target}` "{display_string(str(string_entry["string"]))}"'
)
else:
lines.append(f"- `{fmt_addr(int(entry['from']))}` -> `{target}`")
if not data_refs:
lines.append("- none")
lines.append("")
if string_targets:
lines.extend(["## String Targets", ""])
for query in string_targets:
matches = self.resolve_string_matches(query)
for match_kind, string_entry in matches:
address = int(string_entry["vaddr"])
xrefs = self.xrefs_to(address)
lines.append(
f"### `{query}` -> `{fmt_addr(address)}`"
)
lines.append("")
lines.append(f"- Match kind: `{match_kind}`")
lines.append(f'- String text: "{display_string(str(string_entry["string"]))}"')
lines.append("")
lines.append("Xrefs:")
for entry in xrefs:
from_addr = int(entry["from"])
function = self.function_index.find_containing(from_addr)
ref_type = str(entry.get("type", "DATA"))
if function is None:
lines.append(f"- `{fmt_addr(from_addr)}` `{ref_type}`")
else:
lines.append(
f"- `{fmt_addr(from_addr)}` in `{fmt_addr(int(function['offset']))}` `{self.function_index.preferred_name(function)}` `{ref_type}`"
)
if not xrefs:
lines.append("- none")
lines.append("")
if xrefs:
lines.append("Xref excerpts:")
lines.append("")
for entry in xrefs:
from_addr = int(entry["from"])
lines.append(f"#### `{fmt_addr(from_addr)}`")
lines.append("")
lines.append("```asm")
lines.append(self.excerpt(from_addr))
lines.append("```")
lines.append("")
(self.output_dir / "analysis-context.md").write_text(
"\n".join(lines) + "\n",
encoding="utf-8",
)
def main() -> int:
args = parse_args()
exporter = ContextExporter(args.exe_path, args.output_dir)
function_targets = [parse_hex(value) for value in args.addr]
string_targets = list(args.string)
function_rows = exporter.build_function_rows(function_targets)
string_rows = exporter.build_string_rows(string_targets)
exporter.write_csv(exporter.output_dir / "analysis-context-functions.csv", function_rows)
exporter.write_csv(exporter.output_dir / "analysis-context-strings.csv", string_rows)
exporter.write_markdown(function_targets, string_targets)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,129 @@
#!/usr/bin/env python3
from __future__ import annotations
import os
import shutil
import subprocess
import sys
from pathlib import Path
DEFAULT_DEPTH = "2"
DEFAULT_ROOTS = [
("entry", "0x005a313b"),
("bootstrap", "0x00484440"),
]
def parse_args(argv: list[str]) -> tuple[Path, Path, str, list[tuple[str, str]]]:
if len(argv) < 3:
print(
"usage: export_startup_map.py <exe-path> <output-dir> [--depth N] [--root NAME:ADDR ...]",
file=sys.stderr,
)
raise SystemExit(2)
exe_path = Path(argv[1]).resolve()
output_dir = Path(argv[2]).resolve()
depth = DEFAULT_DEPTH
roots = list(DEFAULT_ROOTS)
index = 3
while index < len(argv):
token = argv[index]
if token == "--depth":
if index + 1 >= len(argv):
print("--depth requires a value", file=sys.stderr)
raise SystemExit(2)
depth = argv[index + 1]
index += 2
continue
if token == "--root":
if index + 1 >= len(argv):
print("--root requires NAME:ADDR", file=sys.stderr)
raise SystemExit(2)
root_spec = argv[index + 1]
if ":" not in root_spec:
print("--root value must be NAME:ADDR", file=sys.stderr)
raise SystemExit(2)
name, address = root_spec.split(":", 1)
if not name or not address:
print("--root value must be NAME:ADDR", file=sys.stderr)
raise SystemExit(2)
if roots == DEFAULT_ROOTS:
roots = []
roots.append((name, address))
index += 2
continue
print("unknown argument: %s" % token, file=sys.stderr)
raise SystemExit(2)
return exe_path, output_dir, depth, roots
def main() -> int:
repo_root = Path(__file__).resolve().parents[2]
exe_path, output_dir, depth, roots = parse_args(sys.argv)
output_dir.mkdir(parents=True, exist_ok=True)
ghidra_home = Path.home() / "software" / "ghidra"
analyze_headless = ghidra_home / "support" / "analyzeHeadless"
if not analyze_headless.exists():
print("analyzeHeadless not found at %s" % analyze_headless, file=sys.stderr)
return 1
project_dir = repo_root / "ghidra_projects"
project_dir.mkdir(parents=True, exist_ok=True)
project_name = "rt3-1.06"
script_path = repo_root / "tools" / "ghidra" / "scripts"
ghidra_runtime = repo_root / ".ghidra"
ghidra_home_dir = ghidra_runtime / "home"
ghidra_config_dir = ghidra_runtime / "config"
ghidra_cache_dir = ghidra_runtime / "cache"
ghidra_java_prefs = ghidra_runtime / "java-prefs"
ghidra_home_dir.mkdir(parents=True, exist_ok=True)
ghidra_config_dir.mkdir(parents=True, exist_ok=True)
ghidra_cache_dir.mkdir(parents=True, exist_ok=True)
ghidra_java_prefs.mkdir(parents=True, exist_ok=True)
java_bin = shutil.which("java")
if java_bin is None:
print("java not found on PATH", file=sys.stderr)
return 1
java_home = Path(java_bin).resolve().parents[1]
command = [
str(analyze_headless),
str(project_dir),
project_name,
"-import",
str(exe_path),
"-overwrite",
"-scriptPath",
str(script_path),
"-postScript",
"ExportStartupFunctions.java",
str(output_dir),
depth,
]
command.extend(["%s:%s" % (name, address) for name, address in roots])
command.extend([
"-analysisTimeoutPerFile",
"600",
])
env = os.environ.copy()
env["HOME"] = str(ghidra_home_dir)
env["XDG_CONFIG_HOME"] = str(ghidra_config_dir)
env["XDG_CACHE_HOME"] = str(ghidra_cache_dir)
env["JAVA_HOME"] = str(java_home)
env["_JAVA_OPTIONS"] = "-Djava.util.prefs.userRoot=%s" % ghidra_java_prefs
subprocess.run(command, check=True, env=env)
return 0
if __name__ == "__main__":
raise SystemExit(main())

57
tools/py/rt3_rekit.py Normal file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
from pathlib import Path
from rt3_rekitlib import (
PENDING_TEMPLATE_STORE_DEFAULT_SEEDS,
export_pending_template_store,
parse_hex,
)
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="RT3 CLI RE kit for repeatable branch-deepening exports."
)
subparsers = parser.add_subparsers(dest="command", required=True)
pending = subparsers.add_parser(
"pending-template-store",
help="Export the pending-template dispatch-store dossier.",
)
pending.add_argument("exe_path", type=Path)
pending.add_argument("output_dir", type=Path)
pending.add_argument(
"--seed-addr",
action="append",
default=[],
help="Hex seed address. May be repeated.",
)
return parser
def main() -> int:
parser = build_parser()
args = parser.parse_args()
if args.command == "pending-template-store":
seed_addresses = (
[parse_hex(value) for value in args.seed_addr]
if args.seed_addr
else list(PENDING_TEMPLATE_STORE_DEFAULT_SEEDS)
)
export_pending_template_store(
args.exe_path.resolve(),
args.output_dir.resolve(),
seed_addresses,
)
return 0
parser.error(f"unknown command: {args.command}")
return 2
if __name__ == "__main__":
raise SystemExit(main())

543
tools/py/rt3_rekitlib.py Normal file
View file

@ -0,0 +1,543 @@
#!/usr/bin/env python3
from __future__ import annotations
import csv
import json
import re
import subprocess
from bisect import bisect_right
from functools import lru_cache
from pathlib import Path
PENDING_TEMPLATE_STORE_DEFAULT_SEEDS = [
0x0059B2E0,
0x0059B710,
0x0059B740,
0x0059C470,
0x0059C540,
0x0059C590,
0x0059C5B0,
0x0059C5E0,
0x0059C5F0,
]
PENDING_TEMPLATE_STORE_ADJACENT_MIN = 0x0059B000
PENDING_TEMPLATE_STORE_ADJACENT_MAX = 0x0059D000
DESTRUCTOR_SWITCH_ADDR = 0x0059B2E0
HEAP_FREE_ADDR = 0x0058F3C0
def parse_hex(text: str) -> int:
value = text.strip().lower()
if value.startswith("0x"):
value = value[2:]
return int(value, 16)
def fmt_addr(value: int) -> str:
return f"0x{value:08x}"
def display_string(text: str) -> str:
return text.encode("unicode_escape").decode("ascii")
def clean_json_payload(text: str) -> str:
stripped = text.strip()
if not stripped:
raise ValueError("rizin returned empty output")
starts = [index for index in (stripped.find("["), stripped.find("{")) if index >= 0]
if not starts:
raise ValueError("rizin did not return JSON")
return stripped[min(starts) :]
def run_rizin_json(exe_path: Path, command: str) -> object:
result = subprocess.run(
[
"rizin",
"-q",
"-e",
"scr.color=false",
"-c",
command,
str(exe_path),
],
check=True,
capture_output=True,
text=True,
)
return json.loads(clean_json_payload(result.stdout))
def run_objdump_excerpt(exe_path: Path, address: int, radius: int = 0x20) -> str:
start = max(address - radius, 0)
stop = address + radius
result = subprocess.run(
[
"llvm-objdump",
"-d",
"--no-show-raw-insn",
f"--start-address={fmt_addr(start)}",
f"--stop-address={fmt_addr(stop)}",
str(exe_path),
],
check=True,
capture_output=True,
text=True,
)
lines = [
line.rstrip()
for line in result.stdout.splitlines()
if re.match(r"^\s*[0-9a-fA-F]+:", line)
]
return "\n".join(lines)
def load_curated_rows(path: Path) -> dict[int, dict[str, str]]:
if not path.exists():
return {}
with path.open(newline="", encoding="utf-8") as handle:
rows = csv.DictReader(handle)
return {parse_hex(row["address"]): dict(row) for row in rows}
class FunctionIndex:
def __init__(self, rows: list[dict[str, object]], curated_names: dict[int, str]):
self.rows = sorted(rows, key=lambda row: int(row["offset"]))
self.by_start = {int(row["offset"]): row for row in self.rows}
self.starts = [int(row["offset"]) for row in self.rows]
self.curated_names = curated_names
def get_exact(self, address: int) -> dict[str, object] | None:
return self.by_start.get(address)
def find_containing(self, address: int) -> dict[str, object] | None:
index = bisect_right(self.starts, address) - 1
if index < 0:
return None
row = self.rows[index]
start = int(row["offset"])
end = int(row.get("maxbound", start + int(row.get("size", 0))))
if start <= address < end:
return row
return None
def preferred_name(self, row: dict[str, object]) -> str:
start = int(row["offset"])
return self.curated_names.get(start, str(row["name"]))
class BranchAnalyzer:
def __init__(self, exe_path: Path, output_dir: Path):
self.exe_path = exe_path.resolve()
self.output_dir = output_dir.resolve()
self.output_dir.mkdir(parents=True, exist_ok=True)
curated_map = self.output_dir / "function-map.csv"
self.curated_rows = load_curated_rows(curated_map)
self.curated_names = {
address: row["name"] for address, row in self.curated_rows.items()
}
self.function_index = FunctionIndex(
self._load_function_rows(),
self.curated_names,
)
self.strings = list(run_rizin_json(self.exe_path, "izzj"))
self.strings_by_addr = {int(entry["vaddr"]): entry for entry in self.strings}
def _load_function_rows(self) -> list[dict[str, object]]:
rows = list(run_rizin_json(self.exe_path, "aaa; aflj"))
known_starts = {int(row["offset"]) for row in rows}
missing_curated = sorted(
address for address in self.curated_names if address not in known_starts
)
if not missing_curated:
return rows
define_cmd = "aaa; " + "; ".join(
f"af @ {fmt_addr(address)}" for address in missing_curated
) + "; aflj"
return list(run_rizin_json(self.exe_path, define_cmd))
@lru_cache(maxsize=None)
def xrefs_to(self, address: int) -> list[dict[str, object]]:
return list(run_rizin_json(self.exe_path, f"aaa; axtj @ {fmt_addr(address)}"))
@lru_cache(maxsize=None)
def function_pdfj(self, address: int) -> dict[str, object]:
payload = run_rizin_json(self.exe_path, f"aaa; s {fmt_addr(address)}; pdfj")
if not isinstance(payload, dict):
raise TypeError(f"unexpected pdfj payload for {fmt_addr(address)}")
return payload
@lru_cache(maxsize=None)
def excerpt(self, address: int) -> str:
return run_objdump_excerpt(self.exe_path, address)
def fallback_function(self, address: int) -> dict[str, object] | None:
curated = self.curated_rows.get(address)
if curated is None:
return None
size = int(curated["size"])
return {
"offset": address,
"name": curated["name"],
"size": size,
"maxbound": address + size,
"calltype": curated["calling_convention"],
"signature": "",
"codexrefs": self.xrefs_to(address),
"callrefs": [],
"datarefs": [],
"synthetic": True,
}
def resolve_target_function(self, address: int) -> dict[str, object] | None:
exact = self.function_index.get_exact(address)
if exact is not None:
return exact
fallback = self.fallback_function(address)
if fallback is not None:
return fallback
return self.function_index.find_containing(address)
def format_callers(self, row: dict[str, object]) -> list[dict[str, object]]:
callers: list[dict[str, object]] = []
for ref in row.get("codexrefs", []):
if ref.get("type") != "CALL":
continue
call_site = int(ref["from"])
caller = self.function_index.find_containing(call_site)
callers.append({"call_site": call_site, "function": caller})
callers.sort(key=lambda entry: entry["call_site"])
return callers
def format_callees(self, row: dict[str, object]) -> list[dict[str, object]]:
callees: list[dict[str, object]] = []
seen: set[tuple[int, int]] = set()
for ref in row.get("callrefs", []):
if ref.get("type") != "CALL":
continue
call_site = int(ref["from"])
callee_site = int(ref["to"])
callee = self.function_index.find_containing(callee_site)
if callee is None:
continue
key = (call_site, int(callee["offset"]))
if key in seen:
continue
seen.add(key)
callees.append({"call_site": call_site, "function": callee})
callees.sort(key=lambda entry: (int(entry["function"]["offset"]), entry["call_site"]))
return callees
def format_data_refs(self, row: dict[str, object]) -> list[dict[str, object]]:
refs: list[dict[str, object]] = []
seen: set[tuple[int, int, str]] = set()
for ref in row.get("datarefs", []):
from_addr = int(ref["from"])
to_addr = int(ref["to"])
ref_type = str(ref.get("type", "DATA"))
key = (from_addr, to_addr, ref_type)
if key in seen:
continue
seen.add(key)
refs.append(
{
"from": from_addr,
"to": to_addr,
"type": ref_type,
"string": self.strings_by_addr.get(to_addr),
}
)
refs.sort(key=lambda entry: (entry["to"], entry["from"]))
return refs
def describe_caller(self, call_site: int, function: dict[str, object] | None) -> str:
if function is None:
return fmt_addr(call_site)
return (
f"{fmt_addr(call_site)}@{fmt_addr(int(function['offset']))}:"
f"{self.function_index.preferred_name(function)}"
)
def describe_callee(self, call_site: int, function: dict[str, object] | None) -> str:
if function is None:
return fmt_addr(call_site)
return (
f"{fmt_addr(call_site)}->{fmt_addr(int(function['offset']))}:"
f"{self.function_index.preferred_name(function)}"
)
def describe_data_ref(self, entry: dict[str, object]) -> str:
target = fmt_addr(int(entry["to"]))
string_entry = entry["string"]
if string_entry is not None:
target += f':"{display_string(str(string_entry["string"]))}"'
return f"{fmt_addr(int(entry['from']))}->{target}"
def collect_key_constants(self, pdfj: dict[str, object]) -> list[str]:
values: list[int] = []
seen: set[int] = set()
for op in pdfj.get("ops", []):
for key in ("val", "ptr"):
raw = op.get(key)
if not isinstance(raw, int):
continue
if raw < 0x10 or raw > 0x100000:
continue
if 0x00400000 <= raw <= 0x01000000:
continue
if raw in seen:
continue
seen.add(raw)
values.append(raw)
return [fmt_addr(value) for value in values[:10]]
def collect_key_strings(self, data_refs: list[dict[str, object]]) -> list[str]:
strings: list[str] = []
seen: set[str] = set()
for entry in data_refs:
string_entry = entry["string"]
if string_entry is None:
continue
text = display_string(str(string_entry["string"]))
if text in seen:
continue
seen.add(text)
strings.append(text)
return strings[:8]
def discover_adjacent_functions(self, addresses: list[int]) -> list[int]:
discovered = set(addresses)
for address in addresses:
function = self.resolve_target_function(address)
if function is None:
continue
for entry in self.format_callers(function):
caller = entry["function"]
if caller is None:
continue
caller_start = int(caller["offset"])
if PENDING_TEMPLATE_STORE_ADJACENT_MIN <= caller_start < PENDING_TEMPLATE_STORE_ADJACENT_MAX:
discovered.add(caller_start)
for entry in self.format_callees(function):
callee = entry["function"]
callee_start = int(callee["offset"])
if PENDING_TEMPLATE_STORE_ADJACENT_MIN <= callee_start < PENDING_TEMPLATE_STORE_ADJACENT_MAX:
discovered.add(callee_start)
return sorted(discovered)
def build_function_rows(self, addresses: list[int]) -> list[dict[str, str]]:
rows: list[dict[str, str]] = []
for query_address in self.discover_adjacent_functions(addresses):
function = self.resolve_target_function(query_address)
if function is None:
continue
callers = self.format_callers(function)
callees = self.format_callees(function)
data_refs = self.format_data_refs(function)
pdfj = self.function_pdfj(int(function["offset"]))
rows.append(
{
"query_address": fmt_addr(query_address),
"function_address": fmt_addr(int(function["offset"])),
"name": self.function_index.preferred_name(function),
"size": str(function["size"]),
"calling_convention": str(function.get("calltype", "unknown")),
"caller_count": str(len(callers)),
"callers": "; ".join(
self.describe_caller(entry["call_site"], entry["function"])
for entry in callers
),
"callee_count": str(len(callees)),
"callees": "; ".join(
self.describe_callee(entry["call_site"], entry["function"])
for entry in callees
),
"data_ref_count": str(len(data_refs)),
"data_refs": "; ".join(self.describe_data_ref(entry) for entry in data_refs),
"key_constants": "; ".join(self.collect_key_constants(pdfj)),
"key_strings": "; ".join(self.collect_key_strings(data_refs)),
"entry_excerpt": self.excerpt(int(function["offset"])).replace("\n", " | "),
}
)
return rows
def _case_groups(self, switch_address: int) -> list[dict[str, object]]:
pdfj = self.function_pdfj(switch_address)
groups: list[dict[str, object]] = []
current: dict[str, object] | None = None
case_pattern = re.compile(r"^case\.0x[0-9a-f]+\.(\d+)$")
default_pattern = re.compile(r"^case\.default\.0x[0-9a-f]+$")
for op in pdfj.get("ops", []):
labels: list[str] = []
for flag in op.get("flags", []):
match = case_pattern.match(flag)
if match:
labels.append(match.group(1))
continue
if default_pattern.match(flag):
labels.append("default")
if labels:
current = {
"start": int(op["offset"]),
"cases": labels,
"ops": [op],
}
groups.append(current)
continue
if current is not None:
current["ops"].append(op)
return groups
def _infer_case_shape(self, ops: list[dict[str, object]]) -> tuple[str, str, str]:
disasm_lines = [str(op["disasm"]) for op in ops]
text = "\n".join(disasm_lines)
direct_offsets = {
int(match.group(1), 16)
for match in re.finditer(r"\[(?:edi|eax|ecx)\+0x([0-9a-f]+)\]", text)
}
indexed_offsets = {
int(match.group(1), 16)
for match in re.finditer(r"\[(?:edi|eax|ecx)\+0x([0-9a-f]+)\]", text)
if "*4" in text
}
free_calls = sum(
1
for op in ops
if op.get("jump") == HEAP_FREE_ADDR or "fcn.0058f3c0" in str(op.get("disasm", ""))
)
has_loop = any("*4" in line for line in disasm_lines)
fields = ["top-level payload"]
for offset in sorted(direct_offsets):
fields.append(f"payload+0x{offset:02x}")
if has_loop:
for offset in sorted(indexed_offsets):
fields.append(f"vector@payload+0x{offset:02x}")
unique_fields = []
seen_fields: set[str] = set()
for field in fields:
if field in seen_fields:
continue
seen_fields.add(field)
unique_fields.append(field)
if has_loop and len(direct_offsets) >= 3:
shape = "pointer vectors with paired side tables"
elif has_loop:
shape = "indexed pointer vector"
elif len(direct_offsets) >= 4:
shape = "fixed pointer tuple"
elif len(direct_offsets) >= 2:
shape = "paired nested pointers"
elif free_calls <= 1:
shape = "top-level payload pointer"
else:
shape = "single nested pointer"
cleanup_summary = f"{free_calls} heap free call(s)"
excerpt = " | ".join(disasm_lines[:8])
return shape, ", ".join(unique_fields), cleanup_summary + f"; {excerpt}"
def build_record_kind_rows(self) -> list[dict[str, str]]:
rows: list[dict[str, str]] = []
for group in self._case_groups(DESTRUCTOR_SWITCH_ADDR):
shape, freed_fields, notes = self._infer_case_shape(group["ops"])
case_group = ",".join(group["cases"])
for case_label in group["cases"]:
rows.append(
{
"record_kind": case_label,
"case_group": case_group,
"owning_function": fmt_addr(DESTRUCTOR_SWITCH_ADDR),
"owning_name": self.curated_names.get(
DESTRUCTOR_SWITCH_ADDR,
"multiplayer_transport_destroy_pending_template_dispatch_record",
),
"inferred_payload_shape": shape,
"freed_fields": freed_fields,
"notes": notes,
}
)
rows.sort(
key=lambda row: (
row["record_kind"] == "default",
int(row["record_kind"]) if row["record_kind"] != "default" else 0,
)
)
return rows
def write_csv(self, path: Path, rows: list[dict[str, str]]) -> None:
if not rows:
return
with path.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
def write_pending_template_store_markdown(self, function_rows: list[dict[str, str]]) -> None:
by_address = {parse_hex(row["function_address"]): row for row in function_rows}
sections = {
"Init": [0x0059B710, 0x0059C5B0],
"Destroy": [0x0059B2E0, 0x0059B740, 0x0059C5E0],
"Lookup": [0x0059C540, 0x0059C590],
"Prune / Remove": [0x0059C470],
"Dispatch / Update": [0x0059C220, 0x0059C5F0],
}
lines = [
"# Pending-Template Store Management",
"",
f"- Target binary: `{self.exe_path}`",
"- Scope: companion pending-template dispatch store and its adjacent management helpers.",
"",
]
for title, addresses in sections.items():
lines.extend([f"## {title}", ""])
for address in addresses:
row = by_address.get(address)
if row is None:
continue
lines.append(f"### `{row['function_address']}` `{row['name']}`")
lines.append("")
lines.append(f"- Size: `{row['size']}`")
lines.append(f"- Calling convention: `{row['calling_convention']}`")
lines.append(f"- Callers: {row['callers'] or 'none'}")
lines.append(f"- Direct callees: {row['callees'] or 'none'}")
lines.append(f"- Data refs: {row['data_refs'] or 'none'}")
lines.append(f"- Key constants: {row['key_constants'] or 'none'}")
lines.append(f"- Key strings: {row['key_strings'] or 'none'}")
lines.append("")
lines.append("Entry excerpt:")
lines.append("")
lines.append("```asm")
lines.append(self.excerpt(address))
lines.append("```")
lines.append("")
(self.output_dir / "pending-template-store-management.md").write_text(
"\n".join(lines) + "\n",
encoding="utf-8",
)
def export_pending_template_store(
exe_path: Path,
output_dir: Path,
seed_addresses: list[int],
) -> None:
analyzer = BranchAnalyzer(exe_path, output_dir)
function_rows = analyzer.build_function_rows(seed_addresses)
record_rows = analyzer.build_record_kind_rows()
analyzer.write_csv(output_dir / "pending-template-store-functions.csv", function_rows)
analyzer.write_csv(output_dir / "pending-template-store-record-kinds.csv", record_rows)
analyzer.write_pending_template_store_markdown(function_rows)

29
tools/run_hook_smoke_test.sh Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
game_dir="$repo_root/rt3_wineprefix/drive_c/rt3"
log_path="$game_dir/rrt_hook_attach.log"
proxy_path="$game_dir/dinput8.dll"
. "$HOME/.local/share/cargo/env"
cargo build -p rrt-hook --target i686-pc-windows-gnu
rm -f "$log_path"
cp "$repo_root/target/i686-pc-windows-gnu/debug/dinput8.dll" "$proxy_path"
(
cd "$game_dir"
timeout 8s env \
WINEPREFIX="$repo_root/rt3_wineprefix" \
WINEDLLOVERRIDES="dinput8=n,b" \
/opt/wine-stable/bin/wine RT3.exe
) >/tmp/rrt-hook-wine.log 2>&1 || true
if [[ -f "$log_path" ]]; then
cat "$log_path"
else
echo "attach-log-missing" >&2
exit 1
fi