feat: add replay system addresses for stream helpers and globals
Browse filesAdds 12 replay helper function addresses and 12 global data addresses.
All helper functions labelled in Ghidra.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crates/openwa-core/src/address.rs
CHANGED
|
@@ -158,6 +158,37 @@ pub mod va {
|
|
| 158 |
pub const REPLAY_LOADER: u32 = 0x0046_2DF0;
|
| 159 |
/// Parses "MM:SS.FF" time string → frame number. Returns -1 on failure.
|
| 160 |
pub const PARSE_REPLAY_POSITION: u32 = 0x004E_3490;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
/// Routes game messages through the task handler tree.
|
| 162 |
pub const GAME_MESSAGE_ROUTER: u32 = 0x0055_3BD0;
|
| 163 |
/// TurnGame message dispatcher. Case 2=FrameFinish, Case 4=ProcessInput, Case 0x28=SkipGo.
|
|
@@ -846,6 +877,31 @@ pub mod va {
|
|
| 846 |
/// Total palette entry bytes loaded (entry_count × 3)
|
| 847 |
pub const G_SPRITE_PALETTE_BYTES: u32 = 0x007A_0870;
|
| 848 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 849 |
// === Configuration globals (for GameInfo__LoadOptions) ===
|
| 850 |
|
| 851 |
/// Base directory string (null-terminated)
|
|
|
|
| 158 |
pub const REPLAY_LOADER: u32 = 0x0046_2DF0;
|
| 159 |
/// Parses "MM:SS.FF" time string → frame number. Returns -1 on failure.
|
| 160 |
pub const PARSE_REPLAY_POSITION: u32 = 0x004E_3490;
|
| 161 |
+
|
| 162 |
+
// --- Replay stream helpers (ported to Rust, addresses for reference) ---
|
| 163 |
+
|
| 164 |
+
/// Read length-prefixed string. usercall(EDI=ctx) + stdcall(dest, max_len). RET 0x8.
|
| 165 |
+
pub const REPLAY_READ_PREFIXED_STRING: u32 = 0x0046_1340;
|
| 166 |
+
/// Read byte with range validation. usercall(EAX=ctx) + stdcall(dest, min, max). RET 0xC.
|
| 167 |
+
pub const REPLAY_READ_BYTE_VALIDATED: u32 = 0x0046_14D0;
|
| 168 |
+
/// Read byte with signed range validation. usercall(EAX=ctx) + stdcall(dest, min, max). RET 0xC.
|
| 169 |
+
pub const REPLAY_READ_BYTE_RANGE: u32 = 0x0046_1540;
|
| 170 |
+
/// Read u16 with range validation. usercall(EAX=ctx) + stdcall(dest, min, max). RET 0xC.
|
| 171 |
+
pub const REPLAY_READ_U16_VALIDATED: u32 = 0x0046_15B0;
|
| 172 |
+
/// Read worm name (0x11 fixed or length-prefixed). usercall(EAX=ctx) + thiscall(this, flag). RET 0x4.
|
| 173 |
+
pub const REPLAY_READ_WORM_NAME: u32 = 0x0046_1620;
|
| 174 |
+
/// Validate team type byte range. fastcall(ECX=type). Plain RET.
|
| 175 |
+
pub const REPLAY_VALIDATE_TEAM_TYPE: u32 = 0x0046_1690;
|
| 176 |
+
|
| 177 |
+
// --- Replay processing functions (bridged via FFI) ---
|
| 178 |
+
|
| 179 |
+
/// Post-process team color assignments. stdcall(1 param). RET 0x4.
|
| 180 |
+
pub const REPLAY_PROCESS_TEAM_COLORS: u32 = 0x0046_6460;
|
| 181 |
+
/// Apply scheme default values. No params (uses globals). Plain RET.
|
| 182 |
+
pub const REPLAY_PROCESS_SCHEME_DEFAULTS: u32 = 0x0046_70F0;
|
| 183 |
+
/// Process replay feature flags. No params (uses globals). Plain RET.
|
| 184 |
+
pub const REPLAY_PROCESS_FLAGS: u32 = 0x0046_7280;
|
| 185 |
+
/// Register observer team entry. stdcall(1 param). RET 0x4.
|
| 186 |
+
pub const REPLAY_REGISTER_OBSERVER: u32 = 0x0046_7BC0;
|
| 187 |
+
/// Process alliance/team setup. No params (uses globals). Plain RET.
|
| 188 |
+
pub const REPLAY_PROCESS_ALLIANCE: u32 = 0x0046_8890;
|
| 189 |
+
/// Validate team configuration. stdcall(1 param).
|
| 190 |
+
pub const REPLAY_VALIDATE_TEAM_SETUP: u32 = 0x0046_5E10;
|
| 191 |
+
|
| 192 |
/// Routes game messages through the task handler tree.
|
| 193 |
pub const GAME_MESSAGE_ROUTER: u32 = 0x0055_3BD0;
|
| 194 |
/// TurnGame message dispatcher. Case 2=FrameFinish, Case 4=ProcessInput, Case 0x28=SkipGo.
|
|
|
|
| 877 |
/// Total palette entry bytes loaded (entry_count × 3)
|
| 878 |
pub const G_SPRITE_PALETTE_BYTES: u32 = 0x007A_0870;
|
| 879 |
|
| 880 |
+
// === Replay globals ===
|
| 881 |
+
|
| 882 |
+
/// Global game state struct passed to ReplayLoader. Always 0x87D3F8.
|
| 883 |
+
pub const G_REPLAY_STATE: u32 = 0x0087_D3F8;
|
| 884 |
+
/// Team header data buffer (0x5728 bytes), cleared by ReplayLoader.
|
| 885 |
+
pub const G_TEAM_HEADER_DATA: u32 = 0x0087_79E4;
|
| 886 |
+
/// Secondary team/game data buffer (0xD9DC bytes).
|
| 887 |
+
pub const G_TEAM_SECONDARY_DATA: u32 = 0x0087_D438;
|
| 888 |
+
/// XOR'd game ID (payload ^ 0xEF5B5C49).
|
| 889 |
+
pub const G_REPLAY_GAME_ID: u32 = 0x0088_AF50;
|
| 890 |
+
/// Replay sub-format flag.
|
| 891 |
+
pub const G_REPLAY_SUB_FORMAT: u32 = 0x0088_AF54;
|
| 892 |
+
/// Game version ID from replay.
|
| 893 |
+
pub const G_REPLAY_VERSION_ID: u32 = 0x0088_ABB0;
|
| 894 |
+
/// Scheme present flag (1 = has scheme data).
|
| 895 |
+
pub const G_REPLAY_SCHEME_PRESENT: u32 = 0x0088_AE0C;
|
| 896 |
+
/// Version/ArtClass counter. ReplayLoader fails if > 0x33.
|
| 897 |
+
pub const G_ARTCLASS_COUNTER: u32 = 0x0088_C790;
|
| 898 |
+
/// Random seed global.
|
| 899 |
+
pub const G_RANDOM_SEED: u32 = 0x0088_D0B4;
|
| 900 |
+
/// Saved random seed.
|
| 901 |
+
pub const G_SAVED_RANDOM_SEED: u32 = 0x0088_ABAC;
|
| 902 |
+
/// Replay filename buffer.
|
| 903 |
+
pub const G_REPLAY_FILENAME: u32 = 0x0088_AF58;
|
| 904 |
+
|
| 905 |
// === Configuration globals (for GameInfo__LoadOptions) ===
|
| 906 |
|
| 907 |
/// Base directory string (null-terminated)
|