Skip to main content

rgpre/ffi/
types.rs

1use bytemuck::{Pod, Zeroable};
2
3// --- Texture decode output ---
4
5#[derive(Clone, Copy, Pod, Zeroable)]
6#[repr(C)]
7pub struct TextureHeader {
8    pub width: i32,
9    pub height: i32,
10    pub frame_count: i32,
11    pub rgba_size: i32,
12}
13// 16 bytes, align 4. Followed by `rgba_size` bytes of RGBA pixel data.
14
15#[derive(Clone, Copy, Pod, Zeroable)]
16#[repr(C)]
17pub struct AllFramesHeader {
18    pub width: i32,
19    pub height: i32,
20    pub frame_count: i32,
21}
22// 12 bytes, align 4. Followed by `frame_count` frames, each prefixed by an i32 size.
23
24// --- RGMD (model/terrain mesh data) ---
25
26#[derive(Clone, Copy, Pod, Zeroable)]
27#[repr(C)]
28pub struct RgmdHeader {
29    pub magic: [u8; 4],
30    pub version: [u8; 4],
31    pub submesh_count: i32,
32    pub frame_count: i32,
33    pub total_vertex_count: i32,
34    pub total_index_count: i32,
35    pub radius: f32,
36}
37// 28 bytes, align 4.
38
39#[derive(Clone, Copy, Pod, Zeroable)]
40#[repr(C)]
41pub struct RgmdSubmeshHeader {
42    pub textured: u8,
43    pub color_r: u8,
44    pub color_g: u8,
45    pub color_b: u8,
46    pub texture_id: u16,
47    pub image_id: u8,
48    pub _pad: u8,
49    pub vertex_count: i32,
50    pub index_count: i32,
51}
52// 16 bytes, align 4. textured: 0 = solid color (color_r/g/b hold resolved RGB),
53// 1 = textured (texture_id + image_id identify the TEXBSI image).
54
55#[derive(Clone, Copy, Pod, Zeroable)]
56#[repr(C)]
57pub struct RgmdVertex {
58    pub position: [f32; 3],
59    pub normal: [f32; 3],
60    pub uv: [f32; 2],
61}
62// 32 bytes, align 4. Followed by index_count × u32 indices.
63
64#[derive(Clone, Copy, Pod, Zeroable)]
65#[repr(C)]
66pub struct RgmdDeltaVertex {
67    pub dx: f32,
68    pub dy: f32,
69    pub dz: f32,
70    pub dnx: f32,
71    pub dny: f32,
72    pub dnz: f32,
73}
74// 24 bytes, align 4.
75// After all base submesh data, frame delta blocks follow:
76// For each animation frame: i32 total_delta_count, then per-submesh: i32 delta_count, then delta_count × RgmdDeltaVertex
77
78// --- RGPL (placements + lights) ---
79
80#[derive(Clone, Copy, Pod, Zeroable)]
81#[repr(C)]
82pub struct RgplHeader {
83    pub magic: [u8; 4],
84    pub placement_count: i32,
85    pub light_count: i32,
86}
87// 12 bytes, align 4.
88
89#[derive(Clone, Copy, Pod, Zeroable)]
90#[repr(C)]
91pub struct RgplPlacement {
92    pub model_name: [u8; 32],
93    pub source_id: [u8; 32],
94    pub transform: [f32; 16],
95    pub texture_id: u16,
96    pub image_id: u8,
97    pub object_type: u8,
98}
99// 132 bytes, align 4. object_type: 0 = mesh, 1 = flat sprite, 2 = rope link.
100// texture_id/image_id: TEXBSI texture for flat sprites; 0 for mesh/rope placements.
101
102#[derive(Clone, Copy, Pod, Zeroable)]
103#[repr(C)]
104pub struct RgplLight {
105    pub name: [u8; 32],
106    pub color: [f32; 3],
107    pub position: [f32; 3],
108    pub range: f32,
109    pub light_type: u8,
110    pub _pad: [u8; 3],
111}
112// 64 bytes, align 4. light_type: 0 = point. color is linear RGB 0.0–1.0.
113
114// --- ROB (segment archive) ---
115
116#[derive(Clone, Copy, Pod, Zeroable)]
117#[repr(C)]
118pub struct RobHeader {
119    pub segment_count: i32,
120}
121// 4 bytes, align 4.
122
123#[derive(Clone, Copy, Pod, Zeroable)]
124#[repr(C)]
125pub struct RobSegmentHeader {
126    pub segment_name: [u8; 8],
127    pub has_model: u8,
128    pub _pad: [u8; 3],
129    pub model_data_size: i32,
130}
131// 16 bytes, align 4. If has_model == 1, followed by model_data_size bytes of RGMD data.
132
133#[derive(Clone, Copy, Pod, Zeroable)]
134#[repr(C)]
135pub struct RgWorldDescriptor {
136    pub world_id: i32,
137    pub has_wld: u8,
138    pub _pad: [u8; 3],
139    pub texbsi_id: u16,
140    pub _pad2: [u8; 2],
141    pub rgm_path: [u8; 64],
142    pub wld_path: [u8; 64],
143    pub palette_path: [u8; 64],
144}
145// 204 bytes, align 4. Paths are null-terminated ASCII, zero-padded.