Commit Β·
e454eb7
0
Parent(s):
Initial openwa-types crate: enums, structs, and RE addresses
Browse filesBootstrap the Rust type foundation for WA 3.8.1 reverse engineering:
- Cargo workspace with openwa-types crate
- Enums translated from wkJellyWorm: ClassType (34), TaskMessage (83+),
Weapon (71), SoundId (126), SpriteId (696)
- Fixed-point math newtype (16.16 format, 0x10000 = 1.0)
- CTask and CGameTask struct stubs with compile-time size assertions
- 80+ known addresses: vtables, constructors, gameplay, rendering, sound
- RE documentation: task hierarchy, vtable layouts, memory map
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- .gitattributes +11 -0
- .gitignore +4 -0
- Cargo.lock +7 -0
- Cargo.toml +3 -0
- crates/openwa-types/Cargo.toml +5 -0
- crates/openwa-types/src/address.rs +171 -0
- crates/openwa-types/src/class_type.rs +61 -0
- crates/openwa-types/src/fixed.rs +92 -0
- crates/openwa-types/src/lib.rs +8 -0
- crates/openwa-types/src/message.rs +137 -0
- crates/openwa-types/src/sound.rs +150 -0
- crates/openwa-types/src/sprite.rs +720 -0
- crates/openwa-types/src/task.rs +74 -0
- crates/openwa-types/src/weapon.rs +94 -0
- docs/plans/2026-03-05-openwa-foundation-design.md +37 -0
- docs/re-notes/memory-map.md +39 -0
- docs/re-notes/task-hierarchy.md +155 -0
.gitattributes
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
testdata/** filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
crates/**/tests/fixtures/** filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.gif filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.wsc filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.pal filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.wagame filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.WAgame filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
crates/*/data/** filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
testdata/**/*.md !text -filter -merge -diff
|
| 11 |
+
testdata/**/.gitignore !text -filter -merge -diff
|
.gitignore
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/target
|
| 2 |
+
.claude/
|
| 3 |
+
.mcp.json
|
| 4 |
+
start-mcp.ps1
|
Cargo.lock
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is automatically @generated by Cargo.
|
| 2 |
+
# It is not intended for manual editing.
|
| 3 |
+
version = 4
|
| 4 |
+
|
| 5 |
+
[[package]]
|
| 6 |
+
name = "openwa-types"
|
| 7 |
+
version = "0.1.0"
|
Cargo.toml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[workspace]
|
| 2 |
+
members = ["crates/*"]
|
| 3 |
+
resolver = "2"
|
crates/openwa-types/Cargo.toml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[package]
|
| 2 |
+
name = "openwa-types"
|
| 3 |
+
version = "0.1.0"
|
| 4 |
+
edition = "2021"
|
| 5 |
+
description = "Type definitions for Worms Armageddon reverse engineering"
|
crates/openwa-types/src/address.rs
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// Known addresses in WA.exe 3.8.1 (image base 0x00400000).
|
| 2 |
+
///
|
| 3 |
+
/// These addresses are discovered through Ghidra analysis and
|
| 4 |
+
/// cross-referenced with wkJellyWorm/WormKit sources.
|
| 5 |
+
///
|
| 6 |
+
/// All addresses are virtual addresses (VA) as loaded in memory.
|
| 7 |
+
pub mod va {
|
| 8 |
+
// Segment layout:
|
| 9 |
+
// .text: 0x00401000 - 0x00619FFF (code)
|
| 10 |
+
// .rdata: 0x0061A000 - 0x00693FFF (read-only data)
|
| 11 |
+
// .data: 0x00694000 - 0x008C4157 (read-write data)
|
| 12 |
+
// .rsrc: 0x008C5000 - 0x00954FFF (resources)
|
| 13 |
+
// .reloc: 0x00955000 - 0x00983FFF (relocations)
|
| 14 |
+
|
| 15 |
+
pub const IMAGE_BASE: u32 = 0x0040_0000;
|
| 16 |
+
pub const TEXT_START: u32 = 0x0040_1000;
|
| 17 |
+
pub const TEXT_END: u32 = 0x0061_9FFF;
|
| 18 |
+
pub const RDATA_START: u32 = 0x0061_A000;
|
| 19 |
+
pub const DATA_START: u32 = 0x0069_4000;
|
| 20 |
+
|
| 21 |
+
// === Vtables (in .rdata) ===
|
| 22 |
+
|
| 23 |
+
/// CTask vtable - 7 virtual method pointers
|
| 24 |
+
pub const CTASK_VTABLE: u32 = 0x0066_9F8C;
|
| 25 |
+
/// CGameTask vtable - extends CTask vtable with 12 more methods
|
| 26 |
+
pub const CGAMETASK_VTABLE: u32 = 0x0066_41F8;
|
| 27 |
+
/// CGameTask secondary vtable (at object offset 0xE8)
|
| 28 |
+
pub const CGAMETASK_VTABLE2: u32 = 0x0066_9CF8;
|
| 29 |
+
|
| 30 |
+
// === CTask vtable methods (at CTask__vtable) ===
|
| 31 |
+
|
| 32 |
+
/// CTask::vtable0 - initialization/unknown
|
| 33 |
+
pub const CTASK_VT0_INIT: u32 = 0x0056_2710;
|
| 34 |
+
/// CTask::Free - destructor/deallocation
|
| 35 |
+
pub const CTASK_VT1_FREE: u32 = 0x0056_2620;
|
| 36 |
+
/// CTask::HandleMessage - message dispatch
|
| 37 |
+
pub const CTASK_VT2_HANDLE_MESSAGE: u32 = 0x0056_2F30;
|
| 38 |
+
/// CTask::vtable3 - unknown
|
| 39 |
+
pub const CTASK_VT3: u32 = 0x0056_13D0;
|
| 40 |
+
/// CTask::vtable4 - unknown (same as vt3 in base)
|
| 41 |
+
pub const CTASK_VT4: u32 = 0x0056_13D0;
|
| 42 |
+
/// CTask::vtable5 - unknown
|
| 43 |
+
pub const CTASK_VT5: u32 = 0x0056_2FA0;
|
| 44 |
+
/// CTask::vtable6 - unknown
|
| 45 |
+
pub const CTASK_VT6: u32 = 0x0056_3000;
|
| 46 |
+
/// CTask::vtable7 - ProcessFrame
|
| 47 |
+
pub const CTASK_VT7_PROCESS_FRAME: u32 = 0x0056_3210;
|
| 48 |
+
|
| 49 |
+
// === CGameTask vtable methods (first 8 override CTask, then 12 new) ===
|
| 50 |
+
|
| 51 |
+
/// CGameTask::vtable0 override
|
| 52 |
+
pub const CGAMETASK_VT0: u32 = 0x004F_F1C0;
|
| 53 |
+
/// CGameTask::Free override
|
| 54 |
+
pub const CGAMETASK_VT1_FREE: u32 = 0x004F_EF10;
|
| 55 |
+
/// CGameTask::HandleMessage override
|
| 56 |
+
pub const CGAMETASK_VT2_HANDLE_MESSAGE: u32 = 0x004F_F280;
|
| 57 |
+
|
| 58 |
+
// === Constructors ===
|
| 59 |
+
|
| 60 |
+
/// CTask constructor - initializes base task fields and children list
|
| 61 |
+
pub const CTASK_CONSTRUCTOR: u32 = 0x0056_25A0;
|
| 62 |
+
/// CGameTask constructor - calls CTask ctor, sets physics defaults
|
| 63 |
+
pub const CGAMETASK_CONSTRUCTOR: u32 = 0x004F_ED50;
|
| 64 |
+
/// CTaskWorm constructor
|
| 65 |
+
pub const CTASK_WORM_CONSTRUCTOR: u32 = 0x0050_BFB0;
|
| 66 |
+
|
| 67 |
+
// === Game entity constructors (from wkJellyWorm) ===
|
| 68 |
+
|
| 69 |
+
pub const CTASK_AIRSTRIKE_CTOR: u32 = 0x0055_53C0;
|
| 70 |
+
pub const CTASK_ARROW_CTOR: u32 = 0x004F_E130;
|
| 71 |
+
pub const CTASK_CANISTER_CTOR: u32 = 0x0050_1A80;
|
| 72 |
+
pub const CTASK_CLOUD_CTOR: u32 = 0x0054_82E0;
|
| 73 |
+
pub const CTASK_CPU_CTOR: u32 = 0x0054_85D0;
|
| 74 |
+
pub const CTASK_CRATE_CTOR: u32 = 0x0050_2490;
|
| 75 |
+
pub const CTASK_CROSS_CTOR: u32 = 0x0050_45C0;
|
| 76 |
+
pub const CTASK_DIRT_CTOR: u32 = 0x0054_EDC0;
|
| 77 |
+
pub const CTASK_FILTER_CTOR: u32 = 0x0054_F3D0;
|
| 78 |
+
pub const CTASK_FIRE_CTOR: u32 = 0x0054_F4C0;
|
| 79 |
+
pub const CTASK_FIREBALL_CTOR: u32 = 0x0055_0890;
|
| 80 |
+
pub const CTASK_FLAME_CTOR: u32 = 0x0054_F0F0;
|
| 81 |
+
pub const CTASK_GAS_CTOR: u32 = 0x0055_4750;
|
| 82 |
+
pub const CTASK_LAND_CTOR: u32 = 0x0050_5440;
|
| 83 |
+
pub const CTASK_MINE_CTOR: u32 = 0x0050_6660;
|
| 84 |
+
pub const CTASK_MISSILE_CTOR: u32 = 0x0050_7D10;
|
| 85 |
+
pub const CTASK_OILDRUM_CTOR: u32 = 0x0050_4AF0;
|
| 86 |
+
pub const CTASK_OLDWORM_CTOR: u32 = 0x0051_FEB0;
|
| 87 |
+
pub const CTASK_SCOREBUBBLE_CTOR: u32 = 0x0055_4CA0;
|
| 88 |
+
pub const CTASK_SEABUBBLE_CTOR: u32 = 0x0055_4FE0;
|
| 89 |
+
pub const CTASK_SMOKE_CTOR: u32 = 0x0055_51D0;
|
| 90 |
+
pub const CTASK_SPRITE_ANIM_CTOR: u32 = 0x0054_66C0;
|
| 91 |
+
pub const CTASK_TEAM_CTOR: u32 = 0x0055_5BB0;
|
| 92 |
+
pub const CTASK_TURNGAME_CTOR: u32 = 0x0055_B280;
|
| 93 |
+
|
| 94 |
+
// === Gameplay functions ===
|
| 95 |
+
|
| 96 |
+
pub const CREATE_EXPLOSION: u32 = 0x0054_8080;
|
| 97 |
+
pub const SPECIAL_IMPACT: u32 = 0x0051_93D0;
|
| 98 |
+
pub const SPAWN_OBJECT: u32 = 0x0056_1CF0;
|
| 99 |
+
pub const WEAPON_RELEASE: u32 = 0x0051_C3D0;
|
| 100 |
+
pub const WORM_START_FIRING: u32 = 0x0051_B7F0;
|
| 101 |
+
pub const FIRE_WEAPON: u32 = 0x0051_EE60;
|
| 102 |
+
pub const CREATE_WEAPON_PROJECTILE: u32 = 0x0051_E0F0;
|
| 103 |
+
|
| 104 |
+
// === Weapon system ===
|
| 105 |
+
|
| 106 |
+
pub const INIT_WEAPON_TABLE: u32 = 0x0053_CAB0;
|
| 107 |
+
pub const GET_AMMO: u32 = 0x0052_25E0;
|
| 108 |
+
pub const ADD_AMMO: u32 = 0x0052_2640;
|
| 109 |
+
pub const SUBTRACT_AMMO: u32 = 0x0052_2680;
|
| 110 |
+
|
| 111 |
+
// === Graphics / rendering ===
|
| 112 |
+
|
| 113 |
+
pub const CONSTRUCT_DD_GAME: u32 = 0x0056_E220;
|
| 114 |
+
pub const CONSTRUCT_DD_GAME_WRAPPER: u32 = 0x0056_DEF0;
|
| 115 |
+
pub const CONSTRUCT_DD_DISPLAY: u32 = 0x0056_9D00;
|
| 116 |
+
pub const CONSTRUCT_FRAME_BUFFER: u32 = 0x005A_2430;
|
| 117 |
+
pub const BLIT_SCREEN: u32 = 0x005A_2020;
|
| 118 |
+
pub const RENDER_DRAWING_QUEUE: u32 = 0x0054_2350;
|
| 119 |
+
pub const DRAW_LANDSCAPE: u32 = 0x005A_2790;
|
| 120 |
+
pub const DRAW_SPRITE_GLOBAL: u32 = 0x0054_1FE0;
|
| 121 |
+
pub const DRAW_BITMAP_GLOBAL: u32 = 0x0054_2170;
|
| 122 |
+
pub const LOAD_SPRITE: u32 = 0x0052_3400;
|
| 123 |
+
pub const CONSTRUCT_OPENGL_CPU: u32 = 0x005A_0850;
|
| 124 |
+
pub const OPENGL_INIT: u32 = 0x0059_F000;
|
| 125 |
+
|
| 126 |
+
// === Landscape ===
|
| 127 |
+
|
| 128 |
+
pub const CONSTRUCT_PC_LANDSCAPE: u32 = 0x0057_ACB0;
|
| 129 |
+
pub const REDRAW_LAND_REGION: u32 = 0x0057_CC10;
|
| 130 |
+
pub const WRITE_LAND_RAW: u32 = 0x0057_C300;
|
| 131 |
+
|
| 132 |
+
// === Sound ===
|
| 133 |
+
|
| 134 |
+
pub const CONSTRUCT_DS_SOUND: u32 = 0x0057_3D50;
|
| 135 |
+
pub const PLAY_SOUND_LOCAL: u32 = 0x004F_DFE0;
|
| 136 |
+
pub const PLAY_SOUND_GLOBAL: u32 = 0x0054_6E20;
|
| 137 |
+
|
| 138 |
+
// === Chat / UI ===
|
| 139 |
+
|
| 140 |
+
pub const SHOW_CHAT_MESSAGE: u32 = 0x0052_ACB0;
|
| 141 |
+
pub const ON_CHAT_INPUT: u32 = 0x0052_B730;
|
| 142 |
+
|
| 143 |
+
// === Lobby / network ===
|
| 144 |
+
|
| 145 |
+
pub const LOBBY_HOST_COMMANDS: u32 = 0x004B_9B00;
|
| 146 |
+
pub const LOBBY_CLIENT_COMMANDS: u32 = 0x004A_ABB0;
|
| 147 |
+
pub const SEND_GAME_PACKET_WRAPPED: u32 = 0x0054_1130;
|
| 148 |
+
pub const FRONTEND_CHANGE_SCREEN: u32 = 0x0044_7A20;
|
| 149 |
+
|
| 150 |
+
// === Memory ===
|
| 151 |
+
|
| 152 |
+
pub const WA_MALLOC_MEMSET: u32 = 0x0053_E910;
|
| 153 |
+
pub const WA_FREE: u32 = 0x005D_0D2B;
|
| 154 |
+
|
| 155 |
+
// === Game context (DDGame struct offsets) ===
|
| 156 |
+
// These are offsets from the DDGame base pointer, not absolute addresses.
|
| 157 |
+
// DDGame pointer is obtained from hookConstructDDGameWrapper param.
|
| 158 |
+
|
| 159 |
+
pub mod ddgame_offsets {
|
| 160 |
+
/// Offset to TurnGame object pointer
|
| 161 |
+
pub const TURN_GAME: u32 = 0x08;
|
| 162 |
+
/// Offset to game global state pointer
|
| 163 |
+
pub const GAME_GLOBAL: u32 = 0x488;
|
| 164 |
+
/// Offset to PC_Landscape pointer
|
| 165 |
+
pub const PC_LANDSCAPE: u32 = 0x4CC;
|
| 166 |
+
/// Offset to weapon table pointer
|
| 167 |
+
pub const WEAPON_TABLE: u32 = 0x510;
|
| 168 |
+
/// Offset to weapon panel pointer
|
| 169 |
+
pub const WEAPON_PANEL: u32 = 0x548;
|
| 170 |
+
}
|
| 171 |
+
}
|
crates/openwa-types/src/class_type.rs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// Task/entity classification type.
|
| 2 |
+
///
|
| 3 |
+
/// Stored at offset 0x20 in CTask. Used to identify the concrete type
|
| 4 |
+
/// of a task in the task hierarchy.
|
| 5 |
+
///
|
| 6 |
+
/// Source: wkJellyWorm Constants.h
|
| 7 |
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
| 8 |
+
#[repr(u32)]
|
| 9 |
+
pub enum ClassType {
|
| 10 |
+
None = 0,
|
| 11 |
+
Task = 1,
|
| 12 |
+
GameTask = 2,
|
| 13 |
+
GameCollisionTask = 3,
|
| 14 |
+
Control = 4,
|
| 15 |
+
Game = 5,
|
| 16 |
+
TurnGame = 6,
|
| 17 |
+
Filter = 7,
|
| 18 |
+
Mine = 8,
|
| 19 |
+
Canister = 9,
|
| 20 |
+
Team = 10,
|
| 21 |
+
Missile = 11,
|
| 22 |
+
Arrow = 12,
|
| 23 |
+
Animation = 13,
|
| 24 |
+
Dirt = 14,
|
| 25 |
+
Crate = 15,
|
| 26 |
+
Flame = 16,
|
| 27 |
+
AirStrike = 17,
|
| 28 |
+
Worm = 18,
|
| 29 |
+
OldWorm = 19,
|
| 30 |
+
Drill = 20,
|
| 31 |
+
Cross = 21,
|
| 32 |
+
Smoke = 22,
|
| 33 |
+
Cloud = 23,
|
| 34 |
+
Fire = 24,
|
| 35 |
+
Gas = 25,
|
| 36 |
+
FireBall = 26,
|
| 37 |
+
SeaBubble = 27,
|
| 38 |
+
Land = 28,
|
| 39 |
+
ScoreBubble = 29,
|
| 40 |
+
OilDrum = 30,
|
| 41 |
+
Cpu = 31,
|
| 42 |
+
SpriteAnimation = 32,
|
| 43 |
+
CollisionManager = 33,
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
impl ClassType {
|
| 47 |
+
pub const MAX: u32 = 34;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
impl TryFrom<u32> for ClassType {
|
| 51 |
+
type Error = u32;
|
| 52 |
+
|
| 53 |
+
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
| 54 |
+
if value < Self::MAX {
|
| 55 |
+
// SAFETY: all values 0..34 are valid variants
|
| 56 |
+
Ok(unsafe { core::mem::transmute(value) })
|
| 57 |
+
} else {
|
| 58 |
+
Err(value)
|
| 59 |
+
}
|
| 60 |
+
}
|
| 61 |
+
}
|
crates/openwa-types/src/fixed.rs
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
use core::ops::{Add, Sub, Mul, Neg};
|
| 2 |
+
|
| 3 |
+
/// 16.16 fixed-point number used throughout WA for coordinates and velocities.
|
| 4 |
+
///
|
| 5 |
+
/// The game uses `0x10000` (65536) to represent `1.0`.
|
| 6 |
+
/// For example, a position of `0x30000` means 3.0 world units.
|
| 7 |
+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
| 8 |
+
#[repr(transparent)]
|
| 9 |
+
pub struct Fixed(pub i32);
|
| 10 |
+
|
| 11 |
+
impl Fixed {
|
| 12 |
+
pub const FRACTIONAL_BITS: u32 = 16;
|
| 13 |
+
pub const SCALE: i32 = 1 << Self::FRACTIONAL_BITS; // 0x10000 = 65536
|
| 14 |
+
|
| 15 |
+
pub const ZERO: Self = Self(0);
|
| 16 |
+
pub const ONE: Self = Self(Self::SCALE);
|
| 17 |
+
|
| 18 |
+
#[inline]
|
| 19 |
+
pub const fn from_raw(raw: i32) -> Self {
|
| 20 |
+
Self(raw)
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
#[inline]
|
| 24 |
+
pub const fn to_raw(self) -> i32 {
|
| 25 |
+
self.0
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
#[inline]
|
| 29 |
+
pub const fn from_int(n: i32) -> Self {
|
| 30 |
+
Self(n << Self::FRACTIONAL_BITS)
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
#[inline]
|
| 34 |
+
pub const fn to_int(self) -> i32 {
|
| 35 |
+
self.0 >> Self::FRACTIONAL_BITS
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
#[inline]
|
| 39 |
+
pub fn from_f32(f: f32) -> Self {
|
| 40 |
+
Self((f * Self::SCALE as f32) as i32)
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
#[inline]
|
| 44 |
+
pub fn to_f32(self) -> f32 {
|
| 45 |
+
self.0 as f32 / Self::SCALE as f32
|
| 46 |
+
}
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
impl Add for Fixed {
|
| 50 |
+
type Output = Self;
|
| 51 |
+
#[inline]
|
| 52 |
+
fn add(self, rhs: Self) -> Self {
|
| 53 |
+
Self(self.0 + rhs.0)
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
impl Sub for Fixed {
|
| 58 |
+
type Output = Self;
|
| 59 |
+
#[inline]
|
| 60 |
+
fn sub(self, rhs: Self) -> Self {
|
| 61 |
+
Self(self.0 - rhs.0)
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
impl Mul for Fixed {
|
| 66 |
+
type Output = Self;
|
| 67 |
+
#[inline]
|
| 68 |
+
fn mul(self, rhs: Self) -> Self {
|
| 69 |
+
// Use i64 to avoid overflow during multiplication
|
| 70 |
+
Self(((self.0 as i64 * rhs.0 as i64) >> Self::FRACTIONAL_BITS) as i32)
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
impl Neg for Fixed {
|
| 75 |
+
type Output = Self;
|
| 76 |
+
#[inline]
|
| 77 |
+
fn neg(self) -> Self {
|
| 78 |
+
Self(-self.0)
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
impl core::fmt::Debug for Fixed {
|
| 83 |
+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
| 84 |
+
write!(f, "Fixed({:.4} raw=0x{:08x})", self.to_f32(), self.0)
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
impl core::fmt::Display for Fixed {
|
| 89 |
+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
| 90 |
+
write!(f, "{:.4}", self.to_f32())
|
| 91 |
+
}
|
| 92 |
+
}
|
crates/openwa-types/src/lib.rs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
pub mod class_type;
|
| 2 |
+
pub mod message;
|
| 3 |
+
pub mod weapon;
|
| 4 |
+
pub mod sound;
|
| 5 |
+
pub mod sprite;
|
| 6 |
+
pub mod fixed;
|
| 7 |
+
pub mod task;
|
| 8 |
+
pub mod address;
|
crates/openwa-types/src/message.rs
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// Inter-task message types for the game's event/message passing system.
|
| 2 |
+
///
|
| 3 |
+
/// Tasks communicate by sending these messages through the hierarchy.
|
| 4 |
+
/// Note: there are gaps in the numbering (10, 24-25, 65-66, 82-83, 87, 95).
|
| 5 |
+
///
|
| 6 |
+
/// Source: wkJellyWorm Constants.h
|
| 7 |
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
| 8 |
+
#[repr(u32)]
|
| 9 |
+
pub enum TaskMessage {
|
| 10 |
+
None = 0,
|
| 11 |
+
FrameStart = 1,
|
| 12 |
+
FrameFinish = 2,
|
| 13 |
+
RenderScene = 3,
|
| 14 |
+
ProcessInput = 4,
|
| 15 |
+
UpdateNonCritical = 5,
|
| 16 |
+
MachineFinished = 6,
|
| 17 |
+
CrateCollected = 7,
|
| 18 |
+
StateChecksum = 8,
|
| 19 |
+
MachineReady = 9,
|
| 20 |
+
// gap: 10 is unused
|
| 21 |
+
WormDrowned = 11,
|
| 22 |
+
FrameNumber = 12,
|
| 23 |
+
MachineQuit = 13,
|
| 24 |
+
EnableCheat = 14,
|
| 25 |
+
PlayerChat = 15,
|
| 26 |
+
CameraAuto = 16,
|
| 27 |
+
CursorMoved = 17,
|
| 28 |
+
GirderChanged = 18,
|
| 29 |
+
StrikeChanged = 19,
|
| 30 |
+
TeamVictory = 20,
|
| 31 |
+
GameOver = 21,
|
| 32 |
+
ExitMode = 22,
|
| 33 |
+
Hurry = 23,
|
| 34 |
+
// gap: 24-25 unused
|
| 35 |
+
ThinkingShow = 26,
|
| 36 |
+
ThinkingHide = 27,
|
| 37 |
+
Explosion = 28,
|
| 38 |
+
ExplosionReport = 29,
|
| 39 |
+
MoveLeft = 30,
|
| 40 |
+
MoveRight = 31,
|
| 41 |
+
MoveUp = 32,
|
| 42 |
+
MoveDown = 33,
|
| 43 |
+
FaceLeft = 34,
|
| 44 |
+
FaceRight = 35,
|
| 45 |
+
Jump = 36,
|
| 46 |
+
JumpUp = 37,
|
| 47 |
+
FireWeapon = 38,
|
| 48 |
+
ReleaseWeapon = 39,
|
| 49 |
+
SkipGo = 40,
|
| 50 |
+
Freeze = 41,
|
| 51 |
+
// gap: 42 unused
|
| 52 |
+
Surrender = 43,
|
| 53 |
+
DetonateWeapon = 44,
|
| 54 |
+
MoveWeaponLeft = 45,
|
| 55 |
+
MoveWeaponRight = 46,
|
| 56 |
+
SelectFuse = 47,
|
| 57 |
+
SelectHerd = 48,
|
| 58 |
+
SelectBounce = 49,
|
| 59 |
+
SelectCursor = 50,
|
| 60 |
+
SelectWeapon = 51,
|
| 61 |
+
StartTurn = 52,
|
| 62 |
+
PauseTurn = 53,
|
| 63 |
+
ResumeTurn = 54,
|
| 64 |
+
FinishTurn = 55,
|
| 65 |
+
TurnStarted = 56,
|
| 66 |
+
TurnFinished = 57,
|
| 67 |
+
SuddenDeath = 58,
|
| 68 |
+
DamageWorms = 59,
|
| 69 |
+
RetreatStarted = 60,
|
| 70 |
+
RetreatFinished = 61,
|
| 71 |
+
ApplyPoison = 62,
|
| 72 |
+
SetWorm = 63,
|
| 73 |
+
KillWorm = 64,
|
| 74 |
+
// gap: 65-66 unused
|
| 75 |
+
AdvanceWorm = 67,
|
| 76 |
+
ShowDamage = 68,
|
| 77 |
+
EnableWeapons = 69,
|
| 78 |
+
DisableWeapons = 70,
|
| 79 |
+
WormMoved = 71,
|
| 80 |
+
WormDamaged = 72,
|
| 81 |
+
WeaponReleased = 73,
|
| 82 |
+
WeaponFinished = 74,
|
| 83 |
+
SpecialImpact = 75,
|
| 84 |
+
WeaponCreated = 76,
|
| 85 |
+
WeaponHoming = 77,
|
| 86 |
+
WeaponDestroyed = 78,
|
| 87 |
+
WeaponClaimControl = 79,
|
| 88 |
+
WeaponReleaseControl = 80,
|
| 89 |
+
PoisonWorm = 81,
|
| 90 |
+
// gap: 82-83 unused
|
| 91 |
+
SetWind = 84,
|
| 92 |
+
GameText = 85,
|
| 93 |
+
CreateAnimation = 86,
|
| 94 |
+
// gap: 87 unused
|
| 95 |
+
BringForward = 88,
|
| 96 |
+
RaiseWater = 89,
|
| 97 |
+
NukeBlast = 90,
|
| 98 |
+
Armageddon = 91,
|
| 99 |
+
DetonateCrate = 92,
|
| 100 |
+
Earthquake = 93,
|
| 101 |
+
ScalesOfJustice = 94,
|
| 102 |
+
// gap: 95 unused
|
| 103 |
+
PauseTimer = 96,
|
| 104 |
+
ResumeTimer = 97,
|
| 105 |
+
MoveSpecial = 98,
|
| 106 |
+
StateWrongChecksum = 99,
|
| 107 |
+
UpdateTween = 100,
|
| 108 |
+
ProcessInputTween = 101,
|
| 109 |
+
TimeReceivedObsolete = 102,
|
| 110 |
+
Transferred = 103,
|
| 111 |
+
TransferTimeFreq = 104,
|
| 112 |
+
UpdatePanelTween = 105,
|
| 113 |
+
StateWrongInitChecksum = 106,
|
| 114 |
+
FrameFinishFiller = 107,
|
| 115 |
+
MachineEvent = 108,
|
| 116 |
+
InvalidDataCompressed = 109,
|
| 117 |
+
InvalidDataUncompressed = 110,
|
| 118 |
+
PacketIndexJump = 111,
|
| 119 |
+
CancelPending = 112,
|
| 120 |
+
BulletExplosion = 113,
|
| 121 |
+
FrameNumberWinsock = 114,
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
impl TryFrom<u32> for TaskMessage {
|
| 125 |
+
type Error = u32;
|
| 126 |
+
|
| 127 |
+
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
| 128 |
+
match value {
|
| 129 |
+
0..=9 | 11..=23 | 26..=41 | 43..=64 | 67..=81 | 84..=86
|
| 130 |
+
| 88..=94 | 96..=114 => {
|
| 131 |
+
// SAFETY: all matched values correspond to valid variants
|
| 132 |
+
Ok(unsafe { core::mem::transmute(value) })
|
| 133 |
+
}
|
| 134 |
+
_ => Err(value),
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
}
|
crates/openwa-types/src/sound.rs
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// Sound effect IDs. Range 1-126, contiguous.
|
| 2 |
+
///
|
| 3 |
+
/// Source: wkJellyWorm Constants.h
|
| 4 |
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
| 5 |
+
#[repr(u32)]
|
| 6 |
+
pub enum SoundId {
|
| 7 |
+
Morse = 1,
|
| 8 |
+
CrowdPart1 = 2,
|
| 9 |
+
CrowdPart2 = 3,
|
| 10 |
+
NukePart1 = 4,
|
| 11 |
+
NukePart2 = 5,
|
| 12 |
+
FrenchAnthem = 6,
|
| 13 |
+
IndianAnthem = 7,
|
| 14 |
+
Twang1 = 8,
|
| 15 |
+
Twang2 = 9,
|
| 16 |
+
Twang3 = 10,
|
| 17 |
+
Twang4 = 11,
|
| 18 |
+
Twang5 = 12,
|
| 19 |
+
Twang6 = 13,
|
| 20 |
+
Cough1 = 14,
|
| 21 |
+
Cough2 = 15,
|
| 22 |
+
Cough3 = 16,
|
| 23 |
+
Cough4 = 17,
|
| 24 |
+
Cough5 = 18,
|
| 25 |
+
Cough6 = 19,
|
| 26 |
+
DonorCardAppears = 20,
|
| 27 |
+
DonorCardCollect = 21,
|
| 28 |
+
FlameThrowerAttack = 22,
|
| 29 |
+
FlameThrowerLoop = 23,
|
| 30 |
+
Freeze = 24,
|
| 31 |
+
UnFreeze = 25,
|
| 32 |
+
JetPackStart = 26,
|
| 33 |
+
JetPackFinish = 27,
|
| 34 |
+
LongbowImpact = 28,
|
| 35 |
+
LongbowRelease = 29,
|
| 36 |
+
NukeFlash = 30,
|
| 37 |
+
ScalesOfJustice = 31,
|
| 38 |
+
UnderWaterLoop = 32,
|
| 39 |
+
VikingAxeImpact = 33,
|
| 40 |
+
VikingAxeRelease = 34,
|
| 41 |
+
WormLanding = 35,
|
| 42 |
+
JetPackLoop1 = 36,
|
| 43 |
+
JetPackLoop2 = 37,
|
| 44 |
+
MoleBombDiggingLoop = 38,
|
| 45 |
+
MoleBombWalkLoop = 39,
|
| 46 |
+
MoleBombSqueak = 40,
|
| 47 |
+
SkunkGasLoop = 41,
|
| 48 |
+
SkunkWalkLoop = 42,
|
| 49 |
+
SkunkSqueak = 43,
|
| 50 |
+
Armageddon = 44,
|
| 51 |
+
StartRound = 45,
|
| 52 |
+
CameraPan = 46,
|
| 53 |
+
WalkCompress = 47,
|
| 54 |
+
WalkExpand = 48,
|
| 55 |
+
CowMoo = 49,
|
| 56 |
+
SheepBaa = 50,
|
| 57 |
+
PigeonCoo = 51,
|
| 58 |
+
AirStrike = 52,
|
| 59 |
+
BlowTorch = 53,
|
| 60 |
+
WormPop = 54,
|
| 61 |
+
Sizzle = 55,
|
| 62 |
+
SnotPlop = 56,
|
| 63 |
+
Splash = 57,
|
| 64 |
+
Splish = 58,
|
| 65 |
+
Petrol = 59,
|
| 66 |
+
WormBurned = 60,
|
| 67 |
+
SalvationArmy = 61,
|
| 68 |
+
MagicBullet = 62,
|
| 69 |
+
WormSpring = 63,
|
| 70 |
+
VaseSmash = 64,
|
| 71 |
+
OldWoman = 65,
|
| 72 |
+
Fuse = 66,
|
| 73 |
+
Teleport = 67,
|
| 74 |
+
Communicator = 68,
|
| 75 |
+
Explosion1 = 69,
|
| 76 |
+
Explosion2 = 70,
|
| 77 |
+
Explosion3 = 71,
|
| 78 |
+
ThrowPowerup = 72,
|
| 79 |
+
ThrowRelease = 73,
|
| 80 |
+
RocketPowerup = 74,
|
| 81 |
+
RocketRelease = 75,
|
| 82 |
+
SuperSheepRelease = 76,
|
| 83 |
+
SuperSheepWhoosh = 77,
|
| 84 |
+
UziFire = 78,
|
| 85 |
+
MinigunFire = 79,
|
| 86 |
+
ShotgunFire = 80,
|
| 87 |
+
ShotgunReload = 81,
|
| 88 |
+
HandgunFire = 82,
|
| 89 |
+
Ricochet = 83,
|
| 90 |
+
Drill = 84,
|
| 91 |
+
DrillImpact = 85,
|
| 92 |
+
NinjaRopeFire = 86,
|
| 93 |
+
NinjaRopeImpact = 87,
|
| 94 |
+
MineArm = 88,
|
| 95 |
+
MineTick = 89,
|
| 96 |
+
MineDud = 90,
|
| 97 |
+
WeaponHoming = 91,
|
| 98 |
+
PauseTick = 92,
|
| 99 |
+
TimerTick = 93,
|
| 100 |
+
SuddenDeath = 94,
|
| 101 |
+
KamikazeRelease = 95,
|
| 102 |
+
BaseballBatRelease = 96,
|
| 103 |
+
BaseballBatImpact = 97,
|
| 104 |
+
BaseballBatJingle = 98,
|
| 105 |
+
DragonBallRelease = 99,
|
| 106 |
+
DragonBallImpact = 100,
|
| 107 |
+
FirePunchImpact = 101,
|
| 108 |
+
HolyDonkey = 102,
|
| 109 |
+
HolyDonkeyImpact = 103,
|
| 110 |
+
HolyGrenade = 104,
|
| 111 |
+
HolyGrenadeImpact = 105,
|
| 112 |
+
FrozenWormImpact = 106,
|
| 113 |
+
MineImpact = 107,
|
| 114 |
+
WormImpact = 108,
|
| 115 |
+
CrossImpact = 109,
|
| 116 |
+
CrateImpact = 110,
|
| 117 |
+
BananaImpact = 111,
|
| 118 |
+
GirderImpact = 112,
|
| 119 |
+
GrenadeImpact = 113,
|
| 120 |
+
OilDrumImpact = 114,
|
| 121 |
+
CratePop = 115,
|
| 122 |
+
KeyClick = 116,
|
| 123 |
+
KeyErase = 117,
|
| 124 |
+
WormSelect = 118,
|
| 125 |
+
CursorSelect = 119,
|
| 126 |
+
WarningBeep = 120,
|
| 127 |
+
LoadingTick = 121,
|
| 128 |
+
TeamDrop = 122,
|
| 129 |
+
TeamBounce = 123,
|
| 130 |
+
Collect = 124,
|
| 131 |
+
ThrowPowerdown = 125,
|
| 132 |
+
RocketPowerdown = 126,
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
impl SoundId {
|
| 136 |
+
pub const MIN: u32 = 1;
|
| 137 |
+
pub const MAX: u32 = 126;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
impl TryFrom<u32> for SoundId {
|
| 141 |
+
type Error = u32;
|
| 142 |
+
|
| 143 |
+
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
| 144 |
+
if value >= Self::MIN && value <= Self::MAX {
|
| 145 |
+
Ok(unsafe { core::mem::transmute(value) })
|
| 146 |
+
} else {
|
| 147 |
+
Err(value)
|
| 148 |
+
}
|
| 149 |
+
}
|
| 150 |
+
}
|
crates/openwa-types/src/sprite.rs
ADDED
|
@@ -0,0 +1,720 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// Sprite/animation frame IDs. Range 1-696 with gaps at 620-621.
|
| 2 |
+
///
|
| 3 |
+
/// Names preserved from the original sprite file names in the game data.
|
| 4 |
+
/// The original names are terse 8-character identifiers from the game's
|
| 5 |
+
/// sprite sheets.
|
| 6 |
+
///
|
| 7 |
+
/// Source: wkJellyWorm Constants.h
|
| 8 |
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
| 9 |
+
#[repr(u32)]
|
| 10 |
+
pub enum SpriteId {
|
| 11 |
+
Cdrom = 1,
|
| 12 |
+
CrshairR = 2,
|
| 13 |
+
CrshairB = 3,
|
| 14 |
+
CrshairG = 4,
|
| 15 |
+
CrshairY = 5,
|
| 16 |
+
CrshairP = 6,
|
| 17 |
+
CrshairC = 7,
|
| 18 |
+
SpangleR = 8,
|
| 19 |
+
SpangleB = 9,
|
| 20 |
+
SpangleG = 10,
|
| 21 |
+
SpangleY = 11,
|
| 22 |
+
SpangleP = 12,
|
| 23 |
+
SpangleC = 13,
|
| 24 |
+
Grave1 = 14,
|
| 25 |
+
Grave2 = 15,
|
| 26 |
+
Grave3 = 16,
|
| 27 |
+
Grave4 = 17,
|
| 28 |
+
Grave5 = 18,
|
| 29 |
+
Grave6 = 19,
|
| 30 |
+
ArrowDnR = 20,
|
| 31 |
+
ArrowDnB = 21,
|
| 32 |
+
ArrowDnG = 22,
|
| 33 |
+
ArrowDnY = 23,
|
| 34 |
+
ArrowDnP = 24,
|
| 35 |
+
ArrowDnC = 25,
|
| 36 |
+
ArrowSdR = 26,
|
| 37 |
+
ArrowSdB = 27,
|
| 38 |
+
ArrowSdG = 28,
|
| 39 |
+
ArrowSdY = 29,
|
| 40 |
+
ArrowSdP = 30,
|
| 41 |
+
ArrowSdC = 31,
|
| 42 |
+
CursorR = 32,
|
| 43 |
+
CursorB = 33,
|
| 44 |
+
CursorG = 34,
|
| 45 |
+
CursorY = 35,
|
| 46 |
+
CursorP = 36,
|
| 47 |
+
CursorC = 37,
|
| 48 |
+
MarkerR = 38,
|
| 49 |
+
MarkerB = 39,
|
| 50 |
+
MarkerG = 40,
|
| 51 |
+
MarkerY = 41,
|
| 52 |
+
MarkerP = 42,
|
| 53 |
+
MarkerC = 43,
|
| 54 |
+
CMarker = 44,
|
| 55 |
+
MineOn = 45,
|
| 56 |
+
Arrow = 46,
|
| 57 |
+
MineOff = 47,
|
| 58 |
+
Missile = 48,
|
| 59 |
+
Bullet = 49,
|
| 60 |
+
Grenade = 50,
|
| 61 |
+
Banana = 51,
|
| 62 |
+
Mortar = 52,
|
| 63 |
+
Cluster = 53,
|
| 64 |
+
Clustlet = 54,
|
| 65 |
+
PetrolBm = 55,
|
| 66 |
+
HGrenade = 56,
|
| 67 |
+
Tamborin = 57,
|
| 68 |
+
HMissil1 = 58,
|
| 69 |
+
HMissil2 = 59,
|
| 70 |
+
AirMisl = 60,
|
| 71 |
+
SheepFal = 61,
|
| 72 |
+
Carpet1 = 62,
|
| 73 |
+
Carpet2 = 63,
|
| 74 |
+
SheepBrn = 64,
|
| 75 |
+
SheepLau = 65,
|
| 76 |
+
Meteor = 66,
|
| 77 |
+
Drill = 67,
|
| 78 |
+
RopeTip = 68,
|
| 79 |
+
RopeCuff = 69,
|
| 80 |
+
Phone = 70,
|
| 81 |
+
MbBomb = 71,
|
| 82 |
+
Letter1 = 72,
|
| 83 |
+
Letter2 = 73,
|
| 84 |
+
Vase = 74,
|
| 85 |
+
VaseBit1 = 75,
|
| 86 |
+
VaseBit2 = 76,
|
| 87 |
+
VaseBit3 = 77,
|
| 88 |
+
Dynamite = 78,
|
| 89 |
+
FireHit = 79,
|
| 90 |
+
KamiSmk = 80,
|
| 91 |
+
BaseHit = 81,
|
| 92 |
+
Donkey = 82,
|
| 93 |
+
Fireball = 83,
|
| 94 |
+
Flame1 = 84,
|
| 95 |
+
Flame2 = 85,
|
| 96 |
+
AirJetB = 86,
|
| 97 |
+
AirJetG = 87,
|
| 98 |
+
AirJetO = 88,
|
| 99 |
+
PostBox = 89,
|
| 100 |
+
ShpTruck = 90,
|
| 101 |
+
CptTruck = 91,
|
| 102 |
+
Targets = 92,
|
| 103 |
+
TargetsV = 93,
|
| 104 |
+
TargetW = 94,
|
| 105 |
+
TargetWV = 95,
|
| 106 |
+
WCrate1 = 96,
|
| 107 |
+
MCrate1 = 97,
|
| 108 |
+
UCrate1 = 98,
|
| 109 |
+
WCrate2 = 99,
|
| 110 |
+
MCrate2 = 100,
|
| 111 |
+
UCrate2 = 101,
|
| 112 |
+
Donor = 102,
|
| 113 |
+
WCrateV = 103,
|
| 114 |
+
MCrateV = 104,
|
| 115 |
+
UCrateV = 105,
|
| 116 |
+
Fallout = 106,
|
| 117 |
+
WCrate0 = 107,
|
| 118 |
+
MCrate0 = 108,
|
| 119 |
+
UCrate0 = 109,
|
| 120 |
+
OilDrum1 = 110,
|
| 121 |
+
OilDrum2 = 111,
|
| 122 |
+
OilDrum3 = 112,
|
| 123 |
+
OilDrum4 = 113,
|
| 124 |
+
UziHit = 114,
|
| 125 |
+
UziCase = 115,
|
| 126 |
+
ShotHit = 116,
|
| 127 |
+
ShotCase = 117,
|
| 128 |
+
WormHit1 = 118,
|
| 129 |
+
WormHit2 = 119,
|
| 130 |
+
Petrol1_ = 120,
|
| 131 |
+
Petrol2_ = 121,
|
| 132 |
+
Petrol3_ = 122,
|
| 133 |
+
Petrol4_ = 123,
|
| 134 |
+
Petrol1 = 124,
|
| 135 |
+
Petrol2 = 125,
|
| 136 |
+
Petrol3 = 126,
|
| 137 |
+
Petrol4 = 127,
|
| 138 |
+
Petrol5 = 128,
|
| 139 |
+
Petrol6 = 129,
|
| 140 |
+
Exhaust = 130,
|
| 141 |
+
HExhaust = 131,
|
| 142 |
+
WExhaust = 132,
|
| 143 |
+
QExhaust = 133,
|
| 144 |
+
Feather = 134,
|
| 145 |
+
MExhaust = 135,
|
| 146 |
+
TCloud = 136,
|
| 147 |
+
WWalk = 137,
|
| 148 |
+
WWalkU = 138,
|
| 149 |
+
WWalkD = 139,
|
| 150 |
+
WBlowW = 140,
|
| 151 |
+
WBlowWU = 141,
|
| 152 |
+
WBlowWD = 142,
|
| 153 |
+
WBlowA = 143,
|
| 154 |
+
WBlowAU = 144,
|
| 155 |
+
WBlowAD = 145,
|
| 156 |
+
WBungee = 146,
|
| 157 |
+
WBatRope = 147,
|
| 158 |
+
WRoll = 148,
|
| 159 |
+
WFly1 = 149,
|
| 160 |
+
WFly2 = 150,
|
| 161 |
+
WFly3 = 151,
|
| 162 |
+
LShpWlk = 152,
|
| 163 |
+
SheepWlk = 153,
|
| 164 |
+
SpSheep1 = 154,
|
| 165 |
+
SpSheep2 = 155,
|
| 166 |
+
AquaShp1 = 156,
|
| 167 |
+
AquaShp2 = 157,
|
| 168 |
+
MoleDive = 158,
|
| 169 |
+
MoleDig1 = 159,
|
| 170 |
+
MoleDig2 = 160,
|
| 171 |
+
MoleDig3 = 161,
|
| 172 |
+
Woman = 162,
|
| 173 |
+
Sally = 163,
|
| 174 |
+
CowWalk = 164,
|
| 175 |
+
CowJump = 165,
|
| 176 |
+
MoleWalk = 166,
|
| 177 |
+
WJetFly1 = 167,
|
| 178 |
+
WJetFly2 = 168,
|
| 179 |
+
WJetFly3 = 169,
|
| 180 |
+
WJetFly4 = 170,
|
| 181 |
+
WJetFlmB = 171,
|
| 182 |
+
WJetFlmD = 172,
|
| 183 |
+
Skunk1 = 173,
|
| 184 |
+
Skunk2 = 174,
|
| 185 |
+
PigeonR0 = 175,
|
| 186 |
+
PigeonR1 = 176,
|
| 187 |
+
PigeonR2 = 177,
|
| 188 |
+
PigeonR3 = 178,
|
| 189 |
+
WpBrth = 179,
|
| 190 |
+
WpBrthU = 180,
|
| 191 |
+
WpBrthD = 181,
|
| 192 |
+
WCough = 182,
|
| 193 |
+
WCoughU = 183,
|
| 194 |
+
WCoughD = 184,
|
| 195 |
+
WBrth1 = 185,
|
| 196 |
+
WBrth1U = 186,
|
| 197 |
+
WBrth1D = 187,
|
| 198 |
+
WBrth2 = 188,
|
| 199 |
+
WBrth2U = 189,
|
| 200 |
+
WBrth2D = 190,
|
| 201 |
+
WBlink1 = 191,
|
| 202 |
+
WBlink1U = 192,
|
| 203 |
+
WBlink1D = 193,
|
| 204 |
+
WBlink2 = 194,
|
| 205 |
+
WBlink2U = 195,
|
| 206 |
+
WBlink2D = 196,
|
| 207 |
+
WGlnce1 = 197,
|
| 208 |
+
WGlnce1U = 198,
|
| 209 |
+
WGlnce1D = 199,
|
| 210 |
+
WGlnce2 = 200,
|
| 211 |
+
WGlnce2U = 201,
|
| 212 |
+
WGlnce2D = 202,
|
| 213 |
+
WBgHead = 203,
|
| 214 |
+
WBgHeadU = 204,
|
| 215 |
+
WBgHeadD = 205,
|
| 216 |
+
WFist = 206,
|
| 217 |
+
WFistU = 207,
|
| 218 |
+
WFistD = 208,
|
| 219 |
+
WPeek = 209,
|
| 220 |
+
WPeekU = 210,
|
| 221 |
+
WPeekD = 211,
|
| 222 |
+
WULook = 212,
|
| 223 |
+
WULookU = 213,
|
| 224 |
+
WULookD = 214,
|
| 225 |
+
WOLook = 215,
|
| 226 |
+
WOLookU = 216,
|
| 227 |
+
WOLookD = 217,
|
| 228 |
+
WScarey = 218,
|
| 229 |
+
WScareyU = 219,
|
| 230 |
+
WScareyD = 220,
|
| 231 |
+
WKami1 = 221,
|
| 232 |
+
WKami2 = 222,
|
| 233 |
+
WKami3 = 223,
|
| 234 |
+
WKami4 = 224,
|
| 235 |
+
WKami5 = 225,
|
| 236 |
+
WScrtch = 226,
|
| 237 |
+
WScrtchU = 227,
|
| 238 |
+
WScrtchD = 228,
|
| 239 |
+
WAccuse = 229,
|
| 240 |
+
WAccuseU = 230,
|
| 241 |
+
WAccuseD = 231,
|
| 242 |
+
WTache = 232,
|
| 243 |
+
WTacheU = 233,
|
| 244 |
+
WTacheD = 234,
|
| 245 |
+
WMunch = 235,
|
| 246 |
+
WMunchU = 236,
|
| 247 |
+
WMunchD = 237,
|
| 248 |
+
WLazy = 238,
|
| 249 |
+
WLazyU = 239,
|
| 250 |
+
WLazyD = 240,
|
| 251 |
+
WWinner = 241,
|
| 252 |
+
WSurndr = 242,
|
| 253 |
+
WSurndrU = 243,
|
| 254 |
+
WSurndrD = 244,
|
| 255 |
+
WSvR = 245,
|
| 256 |
+
WSvRU = 246,
|
| 257 |
+
WSvRD = 247,
|
| 258 |
+
WSvB = 248,
|
| 259 |
+
WSvBU = 249,
|
| 260 |
+
WSvBD = 250,
|
| 261 |
+
WSvG = 251,
|
| 262 |
+
WSvGU = 252,
|
| 263 |
+
WSvGD = 253,
|
| 264 |
+
WSvY = 254,
|
| 265 |
+
WSvYU = 255,
|
| 266 |
+
WSvYD = 256,
|
| 267 |
+
WSvP = 257,
|
| 268 |
+
WSvPU = 258,
|
| 269 |
+
WSvPD = 259,
|
| 270 |
+
WSvC = 260,
|
| 271 |
+
WSvCU = 261,
|
| 272 |
+
WSvCD = 262,
|
| 273 |
+
WSkipGo = 263,
|
| 274 |
+
WSkipGoU = 264,
|
| 275 |
+
WSkipGoD = 265,
|
| 276 |
+
WSelect = 266,
|
| 277 |
+
WSelectU = 267,
|
| 278 |
+
WSelectD = 268,
|
| 279 |
+
WJump = 269,
|
| 280 |
+
WJumpU = 270,
|
| 281 |
+
WJumpD = 271,
|
| 282 |
+
WLand1 = 272,
|
| 283 |
+
WLand1U = 273,
|
| 284 |
+
WLand1D = 274,
|
| 285 |
+
WLand2 = 275,
|
| 286 |
+
WLand2U = 276,
|
| 287 |
+
WLand2D = 277,
|
| 288 |
+
WFlyLnk = 278,
|
| 289 |
+
WBackFlp = 279,
|
| 290 |
+
WPncLnk = 280,
|
| 291 |
+
WPncLnkU = 281,
|
| 292 |
+
WPncLnkD = 282,
|
| 293 |
+
WPncTop = 283,
|
| 294 |
+
WPncBak = 284,
|
| 295 |
+
WPncBakU = 285,
|
| 296 |
+
WPncBakD = 286,
|
| 297 |
+
WParaLnk = 287,
|
| 298 |
+
WParaCht = 288,
|
| 299 |
+
WParBak = 289,
|
| 300 |
+
WParBakU = 290,
|
| 301 |
+
WParBakD = 291,
|
| 302 |
+
WTwang = 292,
|
| 303 |
+
WTwangU = 293,
|
| 304 |
+
WTwangD = 294,
|
| 305 |
+
WSldLk1 = 295,
|
| 306 |
+
WSldLk1U = 296,
|
| 307 |
+
WSldLk1D = 297,
|
| 308 |
+
WSldLk2 = 298,
|
| 309 |
+
WSldLk2U = 299,
|
| 310 |
+
WSldLk2D = 300,
|
| 311 |
+
WpBrtLk = 301,
|
| 312 |
+
WpBrtLkU = 302,
|
| 313 |
+
WpBrtLkD = 303,
|
| 314 |
+
WBlowLk = 304,
|
| 315 |
+
WBlowLkU = 305,
|
| 316 |
+
WBlowLkD = 306,
|
| 317 |
+
WHatLnk = 307,
|
| 318 |
+
WHatLnkU = 308,
|
| 319 |
+
WHatLnkD = 309,
|
| 320 |
+
WNukeLk = 310,
|
| 321 |
+
WNukeLkU = 311,
|
| 322 |
+
WNukeLkD = 312,
|
| 323 |
+
WGrnLnk = 313,
|
| 324 |
+
WGrnLnkU = 314,
|
| 325 |
+
WGrnLnkD = 315,
|
| 326 |
+
WClsLnk = 316,
|
| 327 |
+
WClsLnkU = 317,
|
| 328 |
+
WClsLnkD = 318,
|
| 329 |
+
WBanLnk = 319,
|
| 330 |
+
WBanLnkU = 320,
|
| 331 |
+
WBanLnkD = 321,
|
| 332 |
+
WPbmLnk = 322,
|
| 333 |
+
WPbmLnkU = 323,
|
| 334 |
+
WPbmLnkD = 324,
|
| 335 |
+
WHgrLnk = 325,
|
| 336 |
+
WHgrLnkU = 326,
|
| 337 |
+
WHgrLnkD = 327,
|
| 338 |
+
WUtlLnk = 328,
|
| 339 |
+
WUtlLnkU = 329,
|
| 340 |
+
WUtlLnkD = 330,
|
| 341 |
+
WJetLnk = 331,
|
| 342 |
+
WJetLnkU = 332,
|
| 343 |
+
WJetLnkD = 333,
|
| 344 |
+
WDynLnk = 334,
|
| 345 |
+
WDynLnkU = 335,
|
| 346 |
+
WDynLnkD = 336,
|
| 347 |
+
WVasLnk = 337,
|
| 348 |
+
WVasLnkU = 338,
|
| 349 |
+
WVasLnkD = 339,
|
| 350 |
+
WCowLnk = 340,
|
| 351 |
+
WCowLnkU = 341,
|
| 352 |
+
WCowLnkD = 342,
|
| 353 |
+
WShpLnk = 343,
|
| 354 |
+
WShpLnkU = 344,
|
| 355 |
+
WShpLnkD = 345,
|
| 356 |
+
WWmnLnk = 346,
|
| 357 |
+
WWmnLnkU = 347,
|
| 358 |
+
WWmnLnkD = 348,
|
| 359 |
+
WSknLnk = 349,
|
| 360 |
+
WSknLnkU = 350,
|
| 361 |
+
WSknLnkD = 351,
|
| 362 |
+
WMolLnk = 352,
|
| 363 |
+
WMolLnkU = 353,
|
| 364 |
+
WMolLnkD = 354,
|
| 365 |
+
WWmn2Lk = 355,
|
| 366 |
+
WWmn2LkU = 356,
|
| 367 |
+
WWmn2LkD = 357,
|
| 368 |
+
WDrlLnk = 358,
|
| 369 |
+
WDrlLnkU = 359,
|
| 370 |
+
WDrlLnkD = 360,
|
| 371 |
+
WDrill = 361,
|
| 372 |
+
WPrdLnk = 362,
|
| 373 |
+
WPrdLnkU = 363,
|
| 374 |
+
WPrdLnkD = 364,
|
| 375 |
+
WProd = 365,
|
| 376 |
+
WProdU = 366,
|
| 377 |
+
WProdD = 367,
|
| 378 |
+
WPrdBk2 = 368,
|
| 379 |
+
WPrdBk2U = 369,
|
| 380 |
+
WPrdBk2D = 370,
|
| 381 |
+
WKamLnk = 371,
|
| 382 |
+
WKamLnkU = 372,
|
| 383 |
+
WKamLnkD = 373,
|
| 384 |
+
WKamJmp = 374,
|
| 385 |
+
WKamBmr = 375,
|
| 386 |
+
WKamBmrU = 376,
|
| 387 |
+
WKamBmrD = 377,
|
| 388 |
+
WFirBl1 = 378,
|
| 389 |
+
WFirBl1U = 379,
|
| 390 |
+
WFirBl1D = 380,
|
| 391 |
+
WFirBl2 = 381,
|
| 392 |
+
WFirBl2U = 382,
|
| 393 |
+
WFirBl2D = 383,
|
| 394 |
+
WFirAir = 384,
|
| 395 |
+
WJapBak = 385,
|
| 396 |
+
WJapBakU = 386,
|
| 397 |
+
WJapBakD = 387,
|
| 398 |
+
WMinLnk = 388,
|
| 399 |
+
WMinLnkU = 389,
|
| 400 |
+
WMinLnkD = 390,
|
| 401 |
+
WSkpLnk = 391,
|
| 402 |
+
WSkpLnkU = 392,
|
| 403 |
+
WSkpLnkD = 393,
|
| 404 |
+
WSelLnk = 394,
|
| 405 |
+
WSelLnkU = 395,
|
| 406 |
+
WSelLnkD = 396,
|
| 407 |
+
WAxeLnk = 397,
|
| 408 |
+
WAxeLnkU = 398,
|
| 409 |
+
WAxeLnkD = 399,
|
| 410 |
+
WAxeLk2 = 400,
|
| 411 |
+
WAxeLk2U = 401,
|
| 412 |
+
WAxeLk2D = 402,
|
| 413 |
+
WAxeSwn = 403,
|
| 414 |
+
WAxeSwnU = 404,
|
| 415 |
+
WAxeSwnD = 405,
|
| 416 |
+
WAxeBak = 406,
|
| 417 |
+
WAxeBakU = 407,
|
| 418 |
+
WAxeBakD = 408,
|
| 419 |
+
WBndLnk = 409,
|
| 420 |
+
WBndLnkU = 410,
|
| 421 |
+
WBndLnkD = 411,
|
| 422 |
+
WAirLnk = 412,
|
| 423 |
+
WAirLnkU = 413,
|
| 424 |
+
WAirLnkD = 414,
|
| 425 |
+
WAirTlk = 415,
|
| 426 |
+
WAirTlkU = 416,
|
| 427 |
+
WAirTlkD = 417,
|
| 428 |
+
WTelLnk = 418,
|
| 429 |
+
WTelLnkU = 419,
|
| 430 |
+
WTelLnkD = 420,
|
| 431 |
+
WTelTlk = 421,
|
| 432 |
+
WTelTlkU = 422,
|
| 433 |
+
WTelTlkD = 423,
|
| 434 |
+
WTelDsv = 424,
|
| 435 |
+
WTelDsvU = 425,
|
| 436 |
+
WTelDsvD = 426,
|
| 437 |
+
WThrBak = 427,
|
| 438 |
+
WThrBakU = 428,
|
| 439 |
+
WThrBakD = 429,
|
| 440 |
+
WBsbLnk = 430,
|
| 441 |
+
WBsbLnkU = 431,
|
| 442 |
+
WBsbLnkD = 432,
|
| 443 |
+
WBsbBk2 = 433,
|
| 444 |
+
WBsbBk2U = 434,
|
| 445 |
+
WBsbBk2D = 435,
|
| 446 |
+
WBazLnk = 436,
|
| 447 |
+
WBazLnkU = 437,
|
| 448 |
+
WBazLnkD = 438,
|
| 449 |
+
WFlmLnk = 439,
|
| 450 |
+
WFlmLnkU = 440,
|
| 451 |
+
WFlmLnkD = 441,
|
| 452 |
+
WBz2Lnk = 442,
|
| 453 |
+
WBz2LnkU = 443,
|
| 454 |
+
WBz2LnkD = 444,
|
| 455 |
+
WBz3Lnk = 445,
|
| 456 |
+
WBz3LnkU = 446,
|
| 457 |
+
WBz3LnkD = 447,
|
| 458 |
+
WSurLnk = 448,
|
| 459 |
+
WSurLnkU = 449,
|
| 460 |
+
WSurLnkD = 450,
|
| 461 |
+
WSvrLnk = 451,
|
| 462 |
+
WSvrLnkU = 452,
|
| 463 |
+
WSvrLnkD = 453,
|
| 464 |
+
WSvbLnk = 454,
|
| 465 |
+
WSvbLnkU = 455,
|
| 466 |
+
WSvbLnkD = 456,
|
| 467 |
+
WSvgLnk = 457,
|
| 468 |
+
WSvgLnkU = 458,
|
| 469 |
+
WSvgLnkD = 459,
|
| 470 |
+
WSvyLnk = 460,
|
| 471 |
+
WSvyLnkU = 461,
|
| 472 |
+
WSvyLnkD = 462,
|
| 473 |
+
WSvpLnk = 463,
|
| 474 |
+
WSvpLnkU = 464,
|
| 475 |
+
WSvpLnkD = 465,
|
| 476 |
+
WSvcLnk = 466,
|
| 477 |
+
WSvcLnkU = 467,
|
| 478 |
+
WSvcLnkD = 468,
|
| 479 |
+
WIceLnk = 469,
|
| 480 |
+
WIceLnkU = 470,
|
| 481 |
+
WIceLnkD = 471,
|
| 482 |
+
WIceLk2 = 472,
|
| 483 |
+
WIceLk2U = 473,
|
| 484 |
+
WIceLk2D = 474,
|
| 485 |
+
WIceLk3 = 475,
|
| 486 |
+
WIceLk3U = 476,
|
| 487 |
+
WIceLk3D = 477,
|
| 488 |
+
WIceLook = 478,
|
| 489 |
+
WIceBlnk = 479,
|
| 490 |
+
WIceGlnt = 480,
|
| 491 |
+
WIceStnd = 481,
|
| 492 |
+
WBatLnk = 482,
|
| 493 |
+
WBatLnkU = 483,
|
| 494 |
+
WBatLnkD = 484,
|
| 495 |
+
WBatBk2 = 485,
|
| 496 |
+
WBatBk2U = 486,
|
| 497 |
+
WBatBk2D = 487,
|
| 498 |
+
WUziLnk = 488,
|
| 499 |
+
WUziLnkU = 489,
|
| 500 |
+
WUziLnkD = 490,
|
| 501 |
+
WShgLnk = 491,
|
| 502 |
+
WShgLnkU = 492,
|
| 503 |
+
WShgLnkD = 493,
|
| 504 |
+
WBowLnk = 494,
|
| 505 |
+
WBowLnkU = 495,
|
| 506 |
+
WBowLnkD = 496,
|
| 507 |
+
WBowBk2 = 497,
|
| 508 |
+
WBowBk2U = 498,
|
| 509 |
+
WBowBk2D = 499,
|
| 510 |
+
WHgnLnk = 500,
|
| 511 |
+
WHgnLnkU = 501,
|
| 512 |
+
WHgnLnkD = 502,
|
| 513 |
+
WMgnLnk = 503,
|
| 514 |
+
WMgnLnkU = 504,
|
| 515 |
+
WMgnLnkD = 505,
|
| 516 |
+
WDie = 506,
|
| 517 |
+
SkdSmoke = 507,
|
| 518 |
+
WFlyUp = 508,
|
| 519 |
+
WFlyDn = 509,
|
| 520 |
+
WFall = 510,
|
| 521 |
+
WFallDn = 511,
|
| 522 |
+
WPncUp = 512,
|
| 523 |
+
WSlide = 513,
|
| 524 |
+
WSlideU = 514,
|
| 525 |
+
WSlideD = 515,
|
| 526 |
+
WBow = 516,
|
| 527 |
+
WBowU = 517,
|
| 528 |
+
WBowD = 518,
|
| 529 |
+
WBsbAim = 519,
|
| 530 |
+
WBsbAimU = 520,
|
| 531 |
+
WBsbAimD = 521,
|
| 532 |
+
WBsbSwn = 522,
|
| 533 |
+
WBsbSwnU = 523,
|
| 534 |
+
WBsbSwnD = 524,
|
| 535 |
+
WBaz = 525,
|
| 536 |
+
WBazU = 526,
|
| 537 |
+
WBazD = 527,
|
| 538 |
+
WFlm = 528,
|
| 539 |
+
WFlmU = 529,
|
| 540 |
+
WFlmD = 530,
|
| 541 |
+
WBaz2 = 531,
|
| 542 |
+
WBaz2U = 532,
|
| 543 |
+
WBaz2D = 533,
|
| 544 |
+
WBaz3 = 534,
|
| 545 |
+
WBaz3U = 535,
|
| 546 |
+
WBaz3D = 536,
|
| 547 |
+
WBatAim = 537,
|
| 548 |
+
WBatAimU = 538,
|
| 549 |
+
WBatAimD = 539,
|
| 550 |
+
WBatFrd = 540,
|
| 551 |
+
WBatFrdU = 541,
|
| 552 |
+
WBatFrdD = 542,
|
| 553 |
+
WShotG = 543,
|
| 554 |
+
WShotGU = 544,
|
| 555 |
+
WShotGD = 545,
|
| 556 |
+
WShotP = 546,
|
| 557 |
+
WShotPU = 547,
|
| 558 |
+
WShotPD = 548,
|
| 559 |
+
WShotF = 549,
|
| 560 |
+
WShotFU = 550,
|
| 561 |
+
WShotFD = 551,
|
| 562 |
+
WBowP = 552,
|
| 563 |
+
WBowPU = 553,
|
| 564 |
+
WBowPD = 554,
|
| 565 |
+
WBowF = 555,
|
| 566 |
+
WBowFU = 556,
|
| 567 |
+
WBowFD = 557,
|
| 568 |
+
WHandG = 558,
|
| 569 |
+
WHandGU = 559,
|
| 570 |
+
WHandGD = 560,
|
| 571 |
+
WHandF = 561,
|
| 572 |
+
WHandFU = 562,
|
| 573 |
+
WHandFD = 563,
|
| 574 |
+
WUzi = 564,
|
| 575 |
+
WUziU = 565,
|
| 576 |
+
WUziD = 566,
|
| 577 |
+
WUziF = 567,
|
| 578 |
+
WUziFU = 568,
|
| 579 |
+
WUziFD = 569,
|
| 580 |
+
WMini = 570,
|
| 581 |
+
WMiniU = 571,
|
| 582 |
+
WMiniD = 572,
|
| 583 |
+
WMiniF = 573,
|
| 584 |
+
WMiniFU = 574,
|
| 585 |
+
WMiniFD = 575,
|
| 586 |
+
WThrGrn = 576,
|
| 587 |
+
WThrGrnU = 577,
|
| 588 |
+
WThrGrnD = 578,
|
| 589 |
+
WThrCls = 579,
|
| 590 |
+
WThrClsU = 580,
|
| 591 |
+
WThrClsD = 581,
|
| 592 |
+
WThrBan = 582,
|
| 593 |
+
WThrBanU = 583,
|
| 594 |
+
WThrBanD = 584,
|
| 595 |
+
WThrPbm = 585,
|
| 596 |
+
WThrPbmU = 586,
|
| 597 |
+
WThrPbmD = 587,
|
| 598 |
+
WThrHgr = 588,
|
| 599 |
+
WThrHgrU = 589,
|
| 600 |
+
WThrHgrD = 590,
|
| 601 |
+
WThrow = 591,
|
| 602 |
+
WThrowU = 592,
|
| 603 |
+
WThrowD = 593,
|
| 604 |
+
Replay = 594,
|
| 605 |
+
NetBreak = 595,
|
| 606 |
+
ExFoom = 596,
|
| 607 |
+
ExBiff = 597,
|
| 608 |
+
ExPoot = 598,
|
| 609 |
+
ExPow = 599,
|
| 610 |
+
Circle25 = 600,
|
| 611 |
+
Circle50 = 601,
|
| 612 |
+
Circle75 = 602,
|
| 613 |
+
Circl100 = 603,
|
| 614 |
+
Elipse25 = 604,
|
| 615 |
+
Elipse50 = 605,
|
| 616 |
+
Elipse75 = 606,
|
| 617 |
+
Elips100 = 607,
|
| 618 |
+
GassGrn = 608,
|
| 619 |
+
SmkLt25 = 609,
|
| 620 |
+
SmkLt50 = 610,
|
| 621 |
+
SmkLt75 = 611,
|
| 622 |
+
SmkLt100 = 612,
|
| 623 |
+
SmkDrk20 = 613,
|
| 624 |
+
SmkDrk30 = 614,
|
| 625 |
+
SmkDrk40 = 615,
|
| 626 |
+
Clouds = 616,
|
| 627 |
+
CloudM = 617,
|
| 628 |
+
CloudL = 618,
|
| 629 |
+
Blob = 619,
|
| 630 |
+
// gap: 620-621 unused
|
| 631 |
+
Debris = 622,
|
| 632 |
+
Bubble1 = 623,
|
| 633 |
+
Bubble2 = 624,
|
| 634 |
+
Bubble3 = 625,
|
| 635 |
+
Bubble4 = 626,
|
| 636 |
+
WfDrown = 627,
|
| 637 |
+
Grave1V2 = 628,
|
| 638 |
+
Grave2V2 = 629,
|
| 639 |
+
Grave3V2 = 630,
|
| 640 |
+
Grave4V2 = 631,
|
| 641 |
+
Grave5V2 = 632,
|
| 642 |
+
Grave6V2 = 633,
|
| 643 |
+
TargetsV2 = 634,
|
| 644 |
+
TargetWV2 = 635,
|
| 645 |
+
WCrate1V2 = 636,
|
| 646 |
+
MCrate1V2 = 637,
|
| 647 |
+
UCrate1V2 = 638,
|
| 648 |
+
DonorV2 = 639,
|
| 649 |
+
WDrown = 640,
|
| 650 |
+
OilDrum = 641,
|
| 651 |
+
MeteorV2 = 642,
|
| 652 |
+
MineOnV2 = 643,
|
| 653 |
+
MineOffV2 = 644,
|
| 654 |
+
MissileV2 = 645,
|
| 655 |
+
AirMislV2 = 646,
|
| 656 |
+
GrenadeV2 = 647,
|
| 657 |
+
MortarV2 = 648,
|
| 658 |
+
ClusterV2 = 649,
|
| 659 |
+
ClustletV2 = 650,
|
| 660 |
+
BulletV2 = 651,
|
| 661 |
+
ArrowV2 = 652,
|
| 662 |
+
Sheep = 653,
|
| 663 |
+
Carpet1V2 = 654,
|
| 664 |
+
Carpet2V2 = 655,
|
| 665 |
+
SheepFalV2 = 656,
|
| 666 |
+
SheepBrnV2 = 657,
|
| 667 |
+
MbBombV2 = 658,
|
| 668 |
+
DrillV2 = 659,
|
| 669 |
+
WomanV2 = 660,
|
| 670 |
+
SallyV2 = 661,
|
| 671 |
+
SkunkV2 = 662,
|
| 672 |
+
Mole = 663,
|
| 673 |
+
CowWalkV2 = 664,
|
| 674 |
+
PigeonR0V2 = 665,
|
| 675 |
+
PigeonR1V2 = 666,
|
| 676 |
+
PigeonR2V2 = 667,
|
| 677 |
+
PigeonR3V2 = 668,
|
| 678 |
+
BananaV2 = 669,
|
| 679 |
+
PetrolBmV2 = 670,
|
| 680 |
+
TamborinV2 = 671,
|
| 681 |
+
HGrenadeV2 = 672,
|
| 682 |
+
HMissil1V2 = 673,
|
| 683 |
+
HMissil2V2 = 674,
|
| 684 |
+
AquaShp1V2 = 675,
|
| 685 |
+
AquaShp2V2 = 676,
|
| 686 |
+
VaseV2 = 677,
|
| 687 |
+
VaseBit1V2 = 678,
|
| 688 |
+
VaseBit2V2 = 679,
|
| 689 |
+
VaseBit3V2 = 680,
|
| 690 |
+
DynamiteV2 = 681,
|
| 691 |
+
Letter1V2 = 682,
|
| 692 |
+
Letter2V2 = 683,
|
| 693 |
+
DonkeyV2 = 684,
|
| 694 |
+
WBaz4 = 685,
|
| 695 |
+
WBaz4U = 686,
|
| 696 |
+
WBaz4D = 687,
|
| 697 |
+
WBaz5 = 688,
|
| 698 |
+
WBaz5U = 689,
|
| 699 |
+
WBaz5D = 690,
|
| 700 |
+
WBz4Lnk = 691,
|
| 701 |
+
WBz4LnkU = 692,
|
| 702 |
+
WBz4LnkD = 693,
|
| 703 |
+
WBz5Lnk = 694,
|
| 704 |
+
WBz5LnkU = 695,
|
| 705 |
+
WBz5LnkD = 696,
|
| 706 |
+
}
|
| 707 |
+
|
| 708 |
+
impl TryFrom<u32> for SpriteId {
|
| 709 |
+
type Error = u32;
|
| 710 |
+
|
| 711 |
+
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
| 712 |
+
match value {
|
| 713 |
+
1..=619 | 622..=696 => {
|
| 714 |
+
// SAFETY: all matched values correspond to valid variants
|
| 715 |
+
Ok(unsafe { core::mem::transmute(value) })
|
| 716 |
+
}
|
| 717 |
+
_ => Err(value),
|
| 718 |
+
}
|
| 719 |
+
}
|
| 720 |
+
}
|
crates/openwa-types/src/task.rs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
use crate::class_type::ClassType;
|
| 2 |
+
use crate::fixed::Fixed;
|
| 3 |
+
|
| 4 |
+
/// A 32-bit pointer as it appears in WA's memory (the game is 32-bit x86).
|
| 5 |
+
pub type Ptr32 = u32;
|
| 6 |
+
|
| 7 |
+
/// Base task class in WA's entity hierarchy.
|
| 8 |
+
///
|
| 9 |
+
/// All game objects inherit from CTask. Tasks form a tree via parent/children
|
| 10 |
+
/// pointers and communicate through the TaskMessage system.
|
| 11 |
+
///
|
| 12 |
+
/// PARTIAL: Many fields between known offsets are unknown.
|
| 13 |
+
///
|
| 14 |
+
/// Source: wkJellyWorm CTask.h
|
| 15 |
+
///
|
| 16 |
+
/// Vtable at 0x669F8C (8 methods):
|
| 17 |
+
/// 0x00: 0x562710 vtable0 (init?)
|
| 18 |
+
/// 0x04: 0x562620 Free
|
| 19 |
+
/// 0x08: 0x562F30 HandleMessage
|
| 20 |
+
/// 0x0C: 0x5613D0 unknown
|
| 21 |
+
/// 0x10: 0x5613D0 unknown (same as 0x0C)
|
| 22 |
+
/// 0x14: 0x562FA0 unknown
|
| 23 |
+
/// 0x18: 0x563000 unknown
|
| 24 |
+
/// 0x1C: 0x563210 ProcessFrame
|
| 25 |
+
#[repr(C)]
|
| 26 |
+
pub struct CTask {
|
| 27 |
+
/// 0x00: Pointer to virtual method table
|
| 28 |
+
pub vtable: Ptr32,
|
| 29 |
+
/// 0x04: Parent task in the hierarchy
|
| 30 |
+
pub parent: Ptr32,
|
| 31 |
+
/// 0x08: Unknown (set to 0x10 in constructor β possibly capacity/flags)
|
| 32 |
+
pub _unknown_08: u32,
|
| 33 |
+
/// 0x0C-0x1F: Children task list (CList<CTask*>)
|
| 34 |
+
/// Internal structure: max_size(4), unk4(4), size(4), data_ptr(4), hash_list(4)
|
| 35 |
+
pub _children_raw: [u8; 20],
|
| 36 |
+
/// 0x20: Task classification type
|
| 37 |
+
pub class_type: ClassType,
|
| 38 |
+
/// 0x24-0x2F: Unknown padding to 0x30
|
| 39 |
+
pub _unknown_24: [u8; 12],
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
const _: () = assert!(core::mem::size_of::<CTask>() == 0x30);
|
| 43 |
+
|
| 44 |
+
/// Game task - extends CTask with physics and gameplay data.
|
| 45 |
+
///
|
| 46 |
+
/// PARTIAL: Most fields between 0x30-0x83 and 0x98-0xEC are unknown.
|
| 47 |
+
/// Only position and velocity fields have been verified.
|
| 48 |
+
///
|
| 49 |
+
/// Source: wkJellyWorm CGameTask.h
|
| 50 |
+
///
|
| 51 |
+
/// Additional vtable (12 methods at offsets 0x1C-0x48 in vtable)
|
| 52 |
+
#[repr(C)]
|
| 53 |
+
pub struct CGameTask {
|
| 54 |
+
/// 0x00-0x2F: Base CTask fields
|
| 55 |
+
pub base: CTask,
|
| 56 |
+
/// 0x30-0x83: Unknown gameplay fields (84 bytes)
|
| 57 |
+
pub _unknown_30: [u8; 0x54],
|
| 58 |
+
/// 0x84: X position in fixed-point
|
| 59 |
+
pub pos_x: Fixed,
|
| 60 |
+
/// 0x88: Y position in fixed-point
|
| 61 |
+
pub pos_y: Fixed,
|
| 62 |
+
/// 0x8C-0x8F: Unknown (4 bytes between pos and speed)
|
| 63 |
+
pub _unknown_8c: [u8; 4],
|
| 64 |
+
/// 0x90: X velocity in fixed-point
|
| 65 |
+
pub speed_x: Fixed,
|
| 66 |
+
/// 0x94: Y velocity in fixed-point
|
| 67 |
+
pub speed_y: Fixed,
|
| 68 |
+
/// 0x98-0xE7: Unknown gameplay fields
|
| 69 |
+
pub _unknown_98: [u8; 0x50],
|
| 70 |
+
/// 0xE8: Secondary vtable pointer (-> 0x669CF8 for CGameTask)
|
| 71 |
+
pub vtable2: Ptr32,
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
const _: () = assert!(core::mem::size_of::<CGameTask>() == 0xEC);
|
crates/openwa-types/src/weapon.rs
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/// Weapon types. Contiguous range 0-70.
|
| 2 |
+
///
|
| 3 |
+
/// Source: wkJellyWorm Constants.h
|
| 4 |
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
| 5 |
+
#[repr(u32)]
|
| 6 |
+
pub enum Weapon {
|
| 7 |
+
None = 0,
|
| 8 |
+
Bazooka = 1,
|
| 9 |
+
HomingMissile = 2,
|
| 10 |
+
Mortar = 3,
|
| 11 |
+
HomingPigeon = 4,
|
| 12 |
+
SheepLauncher = 5,
|
| 13 |
+
Grenade = 6,
|
| 14 |
+
ClusterBomb = 7,
|
| 15 |
+
BananaBomb = 8,
|
| 16 |
+
BattleAxe = 9,
|
| 17 |
+
Earthquake = 10,
|
| 18 |
+
Shotgun = 11,
|
| 19 |
+
Handgun = 12,
|
| 20 |
+
Uzi = 13,
|
| 21 |
+
Minigun = 14,
|
| 22 |
+
Longbow = 15,
|
| 23 |
+
FirePunch = 16,
|
| 24 |
+
DragonBall = 17,
|
| 25 |
+
Kamikaze = 18,
|
| 26 |
+
SuicideBomber = 19,
|
| 27 |
+
Prod = 20,
|
| 28 |
+
Dynamite = 21,
|
| 29 |
+
Mine = 22,
|
| 30 |
+
Sheep = 23,
|
| 31 |
+
SuperSheep = 24,
|
| 32 |
+
AquaSheep = 25,
|
| 33 |
+
MoleBomb = 26,
|
| 34 |
+
AirStrike = 27,
|
| 35 |
+
NapalmStrike = 28,
|
| 36 |
+
MailStrike = 29,
|
| 37 |
+
MineStrike = 30,
|
| 38 |
+
MoleSquadron = 31,
|
| 39 |
+
BlowTorch = 32,
|
| 40 |
+
PneumaticDrill = 33,
|
| 41 |
+
Girder = 34,
|
| 42 |
+
BaseballBat = 35,
|
| 43 |
+
GirderPack = 36,
|
| 44 |
+
NinjaRope = 37,
|
| 45 |
+
Bungee = 38,
|
| 46 |
+
Parachute = 39,
|
| 47 |
+
Teleport = 40,
|
| 48 |
+
ScalesOfJustice = 41,
|
| 49 |
+
SuperBanana = 42,
|
| 50 |
+
HolyGrenade = 43,
|
| 51 |
+
FlameThrower = 44,
|
| 52 |
+
SalvationArmy = 45,
|
| 53 |
+
MbBomb = 46,
|
| 54 |
+
PetrolBomb = 47,
|
| 55 |
+
Skunk = 48,
|
| 56 |
+
MingVase = 49,
|
| 57 |
+
SheepStrike = 50,
|
| 58 |
+
CarpetBomb = 51,
|
| 59 |
+
MadCow = 52,
|
| 60 |
+
OldWoman = 53,
|
| 61 |
+
Donkey = 54,
|
| 62 |
+
NuclearTest = 55,
|
| 63 |
+
Armageddon = 56,
|
| 64 |
+
SkipGo = 57,
|
| 65 |
+
Surrender = 58,
|
| 66 |
+
SelectWorm = 59,
|
| 67 |
+
Freeze = 60,
|
| 68 |
+
MagicBullet = 61,
|
| 69 |
+
JetPack = 62,
|
| 70 |
+
LowGravity = 63,
|
| 71 |
+
FastWalk = 64,
|
| 72 |
+
LaserSight = 65,
|
| 73 |
+
Invisibility = 66,
|
| 74 |
+
DamageX2 = 67,
|
| 75 |
+
CrateSpy = 68,
|
| 76 |
+
DoubleTurnTime = 69,
|
| 77 |
+
CrateShower = 70,
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
impl Weapon {
|
| 81 |
+
pub const COUNT: u32 = 71;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
impl TryFrom<u32> for Weapon {
|
| 85 |
+
type Error = u32;
|
| 86 |
+
|
| 87 |
+
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
| 88 |
+
if value < Self::COUNT {
|
| 89 |
+
Ok(unsafe { core::mem::transmute(value) })
|
| 90 |
+
} else {
|
| 91 |
+
Err(value)
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
}
|
docs/plans/2026-03-05-openwa-foundation-design.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# OpenWA Foundation Design
|
| 2 |
+
|
| 3 |
+
## Goal
|
| 4 |
+
|
| 5 |
+
Build the type foundation for an incremental Rust reimplementation of Worms Armageddon 3.8.1 (Steam). Start with Ghidra-assisted reverse engineering and Rust type definitions, later expand to a WormKit module that replaces subsystems.
|
| 6 |
+
|
| 7 |
+
## Strategy: Hybrid Bootstrap
|
| 8 |
+
|
| 9 |
+
- **Constants/enums**: Translate immediately from wkJellyWorm's well-documented Constants.h (weapons, messages, sprites, sounds, class types)
|
| 10 |
+
- **Struct layouts**: Explore in Ghidra first, write Rust types only for verified fields, pad unknowns
|
| 11 |
+
|
| 12 |
+
## Architecture
|
| 13 |
+
|
| 14 |
+
```
|
| 15 |
+
OpenWA/ (Cargo workspace)
|
| 16 |
+
crates/
|
| 17 |
+
openwa-types/ (no_std-compatible type definitions)
|
| 18 |
+
- Enums: ClassType, TaskMessage, Weapon, SoundId, SpriteId
|
| 19 |
+
- Structs: CTask, CGameTask (partial, Ghidra-verified)
|
| 20 |
+
- Primitives: FixedPoint (16.16 fixed-point math)
|
| 21 |
+
- Addresses: Known function/global addresses
|
| 22 |
+
openwa-wormkit/ (future: WormKit DLL module)
|
| 23 |
+
openwa-render/ (future: modern rendering backend)
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
## Key Decisions
|
| 27 |
+
|
| 28 |
+
- `#[repr(C)]` and `#[repr(u32)]` for FFI compatibility from day one
|
| 29 |
+
- Unknown struct fields as `_unknown_XX: [u8; N]` padding β honest about what we don't know
|
| 30 |
+
- Fixed-point newtype rather than raw i32 β prevents unit confusion
|
| 31 |
+
- No external dependencies in openwa-types (pure Rust, no_std compatible)
|
| 32 |
+
|
| 33 |
+
## Sources
|
| 34 |
+
|
| 35 |
+
- wkJellyWorm: Task hierarchy, enums, vtable layouts, offset documentation
|
| 36 |
+
- WormKit: Game state pointers, network protocol, fixed-point conventions
|
| 37 |
+
- Ghidra: WA.exe analysis (6,859 functions, image base 0x400000)
|
docs/re-notes/memory-map.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Memory Map - WA.exe 3.8.1
|
| 2 |
+
|
| 3 |
+
## Segments
|
| 4 |
+
|
| 5 |
+
| Segment | Start | End | Size | Description |
|
| 6 |
+
|---------|------------|------------|----------|----------------------|
|
| 7 |
+
| Headers | 0x00400000 | 0x00400FFF | 4 KB | PE headers |
|
| 8 |
+
| .text | 0x00401000 | 0x00619FFF | ~2.1 MB | Code |
|
| 9 |
+
| .rdata | 0x0061A000 | 0x00693FFF | ~484 KB | Read-only data, vtables |
|
| 10 |
+
| .data | 0x00694000 | 0x008C4157 | ~2.2 MB | Read-write globals |
|
| 11 |
+
| .rsrc | 0x008C5000 | 0x00954FFF | ~576 KB | Resources |
|
| 12 |
+
| .reloc | 0x00955000 | 0x00983FFF | ~188 KB | Relocations |
|
| 13 |
+
|
| 14 |
+
## Key Statistics
|
| 15 |
+
|
| 16 |
+
- Total functions identified: 6,859
|
| 17 |
+
- Image base: 0x00400000
|
| 18 |
+
- 32-bit x86 PE, compiled with MSVC
|
| 19 |
+
- Entry point: 0x005D8B6C (CRT startup)
|
| 20 |
+
- Export: SetHostingProxyAddressAndPort @ 0x0058E380
|
| 21 |
+
|
| 22 |
+
## DDGame structure access
|
| 23 |
+
|
| 24 |
+
The main game state is accessed through the DDGame pointer:
|
| 25 |
+
- DDGame obtained via `ConstructDDGameWrapper` (0x56DEF0) parameter
|
| 26 |
+
- DDGame+0x08 β TurnGame object
|
| 27 |
+
- DDGame+0x488 β Game global state
|
| 28 |
+
- DDGame+0x4CC β PC_Landscape
|
| 29 |
+
- DDGame+0x510 β Weapon table
|
| 30 |
+
- DDGame+0x548 β Weapon panel
|
| 31 |
+
|
| 32 |
+
## Fixed-point convention
|
| 33 |
+
|
| 34 |
+
All coordinates, velocities, and physics values use 16.16 fixed-point:
|
| 35 |
+
- `0x10000` = 1.0
|
| 36 |
+
- `0x20000` = 2.0
|
| 37 |
+
- `0xCCCC` β 0.8
|
| 38 |
+
- Positions stored as Fixed at CGameTask offsets 0x84 (X) and 0x88 (Y)
|
| 39 |
+
- Velocities stored as Fixed at CGameTask offsets 0x90 (X) and 0x94 (Y)
|
docs/re-notes/task-hierarchy.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Task Hierarchy - Worms Armageddon 3.8.1
|
| 2 |
+
|
| 3 |
+
## Overview
|
| 4 |
+
|
| 5 |
+
WA uses a hierarchical task/entity system. All game objects inherit from `CTask`,
|
| 6 |
+
which forms a tree via parent/children pointers. Tasks communicate through a
|
| 7 |
+
message passing system (see `TaskMessage` enum).
|
| 8 |
+
|
| 9 |
+
## Class Hierarchy
|
| 10 |
+
|
| 11 |
+
```
|
| 12 |
+
CTask (base) vtable: 0x669F8C ctor: 0x5625A0
|
| 13 |
+
βββ CGameTask vtable: 0x6641F8 ctor: 0x4FED50
|
| 14 |
+
β βββ CTaskWorm ctor: 0x50BFB0
|
| 15 |
+
β βββ CTaskOldWorm ctor: 0x51FEB0
|
| 16 |
+
β βββ CTaskMissile ctor: 0x507D10
|
| 17 |
+
β βββ CTaskArrow ctor: 0x4FE130
|
| 18 |
+
β βββ CTaskMine ctor: 0x506660
|
| 19 |
+
β βββ CTaskCanister ctor: 0x501A80
|
| 20 |
+
β βββ CTaskCrate ctor: 0x502490
|
| 21 |
+
β βββ CTaskOilDrum ctor: 0x504AF0
|
| 22 |
+
β βββ CTaskCross ctor: 0x5045C0
|
| 23 |
+
β βββ CTaskLand ctor: 0x505440
|
| 24 |
+
βββ CTaskFilter ctor: 0x54F3D0
|
| 25 |
+
βββ CTaskTeam ctor: 0x555BB0
|
| 26 |
+
βββ CTaskTurnGame ctor: 0x55B280
|
| 27 |
+
βββ CTaskAirStrike ctor: 0x5553C0
|
| 28 |
+
βββ CTaskDirt ctor: 0x54EDC0
|
| 29 |
+
βββ CTaskFlame ctor: 0x54F0F0
|
| 30 |
+
βββ CTaskFire ctor: 0x54F4C0
|
| 31 |
+
βββ CTaskFireBall ctor: 0x550890
|
| 32 |
+
βββ CTaskGas ctor: 0x554750
|
| 33 |
+
βββ CTaskSmoke ctor: 0x5551D0
|
| 34 |
+
βββ CTaskCloud ctor: 0x5482E0
|
| 35 |
+
βββ CTaskSeaBubble ctor: 0x554FE0
|
| 36 |
+
βββ CTaskScoreBubble ctor: 0x554CA0
|
| 37 |
+
βββ CTaskCPU ctor: 0x5485D0
|
| 38 |
+
βββ CTaskSpriteAnimation ctor: 0x5466C0
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
Note: Not all tasks are confirmed to inherit from CGameTask. The hierarchy
|
| 42 |
+
above needs further verification via Ghidra analysis of each constructor.
|
| 43 |
+
|
| 44 |
+
## CTask vtable (0x669F8C)
|
| 45 |
+
|
| 46 |
+
| Index | Offset | Address | Name (from wkJellyWorm) |
|
| 47 |
+
|-------|--------|------------|-------------------------|
|
| 48 |
+
| 0 | 0x00 | 0x562710 | vtable0 (init?) |
|
| 49 |
+
| 1 | 0x04 | 0x562620 | Free |
|
| 50 |
+
| 2 | 0x08 | 0x562F30 | HandleMessage |
|
| 51 |
+
| 3 | 0x0C | 0x5613D0 | unknown |
|
| 52 |
+
| 4 | 0x10 | 0x5613D0 | unknown (=vt3) |
|
| 53 |
+
| 5 | 0x14 | 0x562FA0 | unknown |
|
| 54 |
+
| 6 | 0x18 | 0x563000 | unknown |
|
| 55 |
+
| 7 | 0x1C | 0x563210 | ProcessFrame |
|
| 56 |
+
|
| 57 |
+
Note: wkJellyWorm says 7 methods but we see 8 entries. The 8th may be
|
| 58 |
+
the start of CGameTask's extended vtable region, or the count was off by one.
|
| 59 |
+
|
| 60 |
+
## CGameTask vtable (0x6641F8)
|
| 61 |
+
|
| 62 |
+
First 3 entries override CTask:
|
| 63 |
+
|
| 64 |
+
| Index | Offset | Address | Name |
|
| 65 |
+
|-------|--------|------------|-------------------------|
|
| 66 |
+
| 0 | 0x00 | 0x4FF1C0 | vtable0 override |
|
| 67 |
+
| 1 | 0x04 | 0x4FEF10 | Free override |
|
| 68 |
+
| 2 | 0x08 | 0x4FF280 | HandleMessage override |
|
| 69 |
+
| 3 | 0x0C | 0x5613D0 | (inherited from CTask) |
|
| 70 |
+
| 4 | 0x10 | 0x5613D0 | (inherited from CTask) |
|
| 71 |
+
| 5 | 0x14 | 0x562FA0 | (inherited from CTask) |
|
| 72 |
+
| 6 | 0x18 | 0x563000 | (inherited from CTask) |
|
| 73 |
+
| 7 | 0x1C | 0x4FF720 | CGameTask-specific |
|
| 74 |
+
| 8 | 0x20 | 0x4FFED0 | CGameTask-specific |
|
| 75 |
+
| 9 | 0x24 | 0x500070 | CGameTask-specific |
|
| 76 |
+
| 10 | 0x28 | 0x500080 | CGameTask-specific |
|
| 77 |
+
| 11 | 0x2C | 0x5000E0 | CGameTask-specific |
|
| 78 |
+
| 12 | 0x30 | 0x500380 | CGameTask-specific |
|
| 79 |
+
| 13 | 0x34 | 0x500360 | CGameTask-specific |
|
| 80 |
+
| 14 | 0x38 | 0x4FE060 | CGameTask-specific |
|
| 81 |
+
| 15 | 0x3C | 0x500CC0 | CGameTask-specific |
|
| 82 |
+
| 16 | 0x40 | 0x592A50 | CGameTask-specific |
|
| 83 |
+
| 17 | 0x44 | 0x500090 | CGameTask-specific |
|
| 84 |
+
| 18 | 0x48 | 0x545780 | CGameTask-specific |
|
| 85 |
+
| 19 | 0x4C | 0x4AA060 | CGameTask-specific |
|
| 86 |
+
|
| 87 |
+
CGameTask also has a secondary vtable at object offset 0xE8, pointing to 0x669CF8.
|
| 88 |
+
|
| 89 |
+
## CTask memory layout (0x30 bytes)
|
| 90 |
+
|
| 91 |
+
```
|
| 92 |
+
Offset Size Field
|
| 93 |
+
0x00 4 vtable pointer
|
| 94 |
+
0x04 4 parent (CTask*)
|
| 95 |
+
0x08 4 unknown (set to 0x10 in ctor)
|
| 96 |
+
0x0C 4 children.max_size (init 0)
|
| 97 |
+
0x10 4 children.unk4 (init 0)
|
| 98 |
+
0x14 4 children.size
|
| 99 |
+
0x18 4 children.data_ptr (allocated 0x60 bytes, zeroed 0x40)
|
| 100 |
+
0x1C 4 children.hash_list
|
| 101 |
+
0x20 4 class_type (ClassType enum)
|
| 102 |
+
0x24 12 unknown padding
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
## CGameTask memory layout (0xEC bytes)
|
| 106 |
+
|
| 107 |
+
Extends CTask at offset 0x00. Key fields discovered from constructor:
|
| 108 |
+
|
| 109 |
+
```
|
| 110 |
+
Offset Size Field
|
| 111 |
+
0x00 0x30 CTask base
|
| 112 |
+
0x20 4 class_type (set to 3 = GameCollisionTask in ctor)
|
| 113 |
+
0x2C 4 param_3 from ctor
|
| 114 |
+
0x30 4 param_3 (weapon id?)
|
| 115 |
+
0x38 4 param_4
|
| 116 |
+
0x3C 4 unknown
|
| 117 |
+
...
|
| 118 |
+
0x4C 4 = 0x10000 (Fixed 1.0)
|
| 119 |
+
0x50 4 = 0x100000 (Fixed 16.0)
|
| 120 |
+
0x54 4 = 0xCCCC (Fixed ~0.8)
|
| 121 |
+
0x58 4 = 0x10000 (Fixed 1.0)
|
| 122 |
+
0x5C 4 = 0
|
| 123 |
+
0x60 4 = 0x10000 (Fixed 1.0)
|
| 124 |
+
0x64 4 = 0x20000 (Fixed 2.0)
|
| 125 |
+
0x68 4 = 0xF333 (Fixed ~0.95)
|
| 126 |
+
...
|
| 127 |
+
0x84 4 pos_x (Fixed)
|
| 128 |
+
0x88 4 pos_y (Fixed)
|
| 129 |
+
0x8C 4 = 0x10000 (Fixed 1.0, scale?)
|
| 130 |
+
0x90 4 speed_x (Fixed)
|
| 131 |
+
0x94 4 speed_y (Fixed)
|
| 132 |
+
...
|
| 133 |
+
0xCC 4 = 0x10000 (Fixed 1.0)
|
| 134 |
+
0xD8 1 byte flag (init 0)
|
| 135 |
+
0xD9 1 byte flag (init 0)
|
| 136 |
+
0xE0 4 unknown (init 0)
|
| 137 |
+
0xE4 4 unknown (init 0)
|
| 138 |
+
0xDC 4 unknown (init 0)
|
| 139 |
+
0xE8 4 secondary vtable pointer -> 0x669CF8
|
| 140 |
+
```
|
| 141 |
+
|
| 142 |
+
## Physics defaults from CGameTask constructor
|
| 143 |
+
|
| 144 |
+
Several fixed-point constants are set in the constructor, likely physics defaults:
|
| 145 |
+
- `0x10000` = 1.0 (appears at many offsets β scale factors, gravity?)
|
| 146 |
+
- `0x100000` = 16.0 (mass? terminal velocity?)
|
| 147 |
+
- `0xCCCC` β 0.8 (friction? damping?)
|
| 148 |
+
- `0x20000` = 2.0
|
| 149 |
+
- `0xF333` β 0.95 (air resistance?)
|
| 150 |
+
- `0x3333` β 0.2
|
| 151 |
+
- `0x4CCC` β 0.3
|
| 152 |
+
- `0xFEB8` β 0.995
|
| 153 |
+
- `0x9999` β 0.6
|
| 154 |
+
- `0x3AE1` β 0.23
|
| 155 |
+
- `0xFC000000` = -67108864 (large negative, possibly a boundary?)
|