Skip to content

Commit

Permalink
Horribly dirty hacks for Recoil m6 and m9 gamez
Browse files Browse the repository at this point in the history
  • Loading branch information
tobywf committed Nov 8, 2023
1 parent 525a697 commit b9e9b46
Show file tree
Hide file tree
Showing 17 changed files with 161 additions and 49 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Legend:
| Image/texture ZBDs |||||
| `mechlib.zbd` |||||
| `motion.zbd` |||||
| `gamez.zbd` | ✔️ ||||
| `gamez.zbd` | ||||
| `anim.zbd`/`cam_anim.zbd`/`mis_anim.zbd` |||||
| `m*.zmap` |||||
| `planes.zbd` * |||||
Expand Down Expand Up @@ -85,7 +85,6 @@ Not supported (yet?):

### Recoil

* `gamez.zbd` files are supported, but M6 and M9 are not supported yet
* `anim.zbd` files are not supported yet

### Crimson Skies
Expand Down Expand Up @@ -193,6 +192,7 @@ where `--rtexture` and `--rmechtex` are optional.

### [0.6.0-rc5] - Unreleased

* Horribly dirty hacks for Recoil M6 and M9 (`gamez`)
* Allow Recoil light nodes in other positions (`gamez`)
* Update to Rust 1.73.0

Expand Down
2 changes: 2 additions & 0 deletions crates/mech3ax-api-types/src/nodes/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ pub struct Object3d {
pub area_partition: Option<AreaPartition>,
pub mesh_index: i32,
pub parent: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub parents: Option<Vec<u32>>,
pub children: Vec<u32>,

pub data_ptr: u32,
Expand Down
33 changes: 33 additions & 0 deletions crates/mech3ax-gamez/src/gamez/rc/fixup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::HeaderRcC;
use crate::gamez::common::{SIGNATURE, VERSION_RC};

macro_rules! header_m6 {
($node_count:literal) => {
HeaderRcC {
signature: SIGNATURE,
version: VERSION_RC,
texture_count: 612,
textures_offset: 36,
materials_offset: 22068,
meshes_offset: 242084,
node_array_size: 16000,
node_count: $node_count,
nodes_offset: 2299168,
}
};
}

const HEADER_M6_READ: HeaderRcC = header_m6!(309);
const HEADER_M6_WRITE: HeaderRcC = header_m6!(4955);

pub(super) fn read(header: &mut HeaderRcC) {
if header == &HEADER_M6_READ {
header.node_count = HEADER_M6_WRITE.node_count;
}
}

pub(super) fn write(header: &mut HeaderRcC) {
if header == &HEADER_M6_WRITE {
header.node_count = HEADER_M6_READ.node_count;
}
}
10 changes: 7 additions & 3 deletions crates/mech3ax-gamez/src/gamez/rc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod fixup;
mod meshes;
mod nodes;

Expand All @@ -11,7 +12,7 @@ use mech3ax_common::io_ext::{CountingReader, CountingWriter};
use mech3ax_common::{assert_len, assert_that, Result};
use std::io::{Read, Write};

#[derive(Debug)]
#[derive(Debug, PartialEq)]
#[repr(C)]
struct HeaderRcC {
signature: u32, // 00
Expand All @@ -34,9 +35,11 @@ pub fn read_gamez(read: &mut CountingReader<impl Read>) -> Result<GameZDataRc> {
HeaderRcC::SIZE,
read.offset
);
let header: HeaderRcC = read.read_struct()?;
let mut header: HeaderRcC = read.read_struct()?;
trace!("{:#?}", header);

fixup::read(&mut header);

assert_that!("signature", header.signature == SIGNATURE, read.prev + 0)?;
assert_that!("version", header.version == VERSION_RC, read.prev + 4)?;
assert_that!("texture count", header.texture_count < 4096, read.prev + 8)?;
Expand Down Expand Up @@ -117,7 +120,7 @@ pub fn write_gamez(write: &mut CountingWriter<impl Write>, gamez: &GameZDataRc)
HeaderRcC::SIZE,
write.offset
);
let header = HeaderRcC {
let mut header = HeaderRcC {
signature: SIGNATURE,
version: VERSION_RC,
texture_count,
Expand All @@ -128,6 +131,7 @@ pub fn write_gamez(write: &mut CountingWriter<impl Write>, gamez: &GameZDataRc)
node_count,
nodes_offset,
};
fixup::write(&mut header);
trace!("{:#?}", header);
write.write_struct(&header)?;

Expand Down
4 changes: 2 additions & 2 deletions crates/mech3ax-nodes/src/rc/camera/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn assert_variants(node: NodeVariantsRc, offset: u32) -> Result<NodeVariantR
node.area_partition == None,
offset + 76
)?;
assert_that!("camera has parent", node.has_parent == false, offset + 84)?;
assert_that!("camera parent count", node.parent_count == 0, offset + 84)?;
// parent_array_ptr (88) already asserted
assert_that!(
"camera children count",
Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn make_variants(camera: &Camera) -> NodeVariantsRc {
data_ptr: camera.data_ptr,
mesh_index: -1,
area_partition: None,
has_parent: false,
parent_count: 0,
parent_array_ptr: 0,
children_count: 0,
children_array_ptr: 0,
Expand Down
4 changes: 2 additions & 2 deletions crates/mech3ax-nodes/src/rc/display/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn assert_variants(node: NodeVariantsRc, offset: u32) -> Result<NodeVariantR
node.area_partition == None,
offset + 76
)?;
assert_that!("display has parent", node.has_parent == false, offset + 84)?;
assert_that!("display parent count", node.parent_count == 0, offset + 84)?;
// parent_array_ptr (88) already asserted
assert_that!(
"display children count",
Expand Down Expand Up @@ -82,7 +82,7 @@ pub fn make_variants(display: &Display) -> NodeVariantsRc {
data_ptr: display.data_ptr,
mesh_index: -1,
area_partition: None,
has_parent: false,
parent_count: 0,
parent_array_ptr: 0,
children_count: 0,
children_array_ptr: 0,
Expand Down
8 changes: 4 additions & 4 deletions crates/mech3ax-nodes/src/rc/empty/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const ALWAYS_PRESENT: NodeBitFlags = NodeBitFlags::from_bits_truncate(
| NodeBitFlags::INTERSECT_SURFACE.bits()
// | NodeBitFlags::INTERSECT_BBOX.bits()
// | NodeBitFlags::LANDMARK.bits()
| NodeBitFlags::UNK08.bits()
// | NodeBitFlags::UNK08.bits()
// | NodeBitFlags::HAS_MESH.bits()
// | NodeBitFlags::UNK10.bits()
// | NodeBitFlags::TERRAIN.bits()
Expand All @@ -30,7 +30,7 @@ const VARIABLE_FLAGS: NodeBitFlags = NodeBitFlags::from_bits_truncate(
// | NodeBitFlags::INTERSECT_SURFACE.bits()
| NodeBitFlags::INTERSECT_BBOX.bits()
// | NodeBitFlags::LANDMARK.bits()
// | NodeBitFlags::UNK08.bits()
| NodeBitFlags::UNK08.bits()
// | NodeBitFlags::HAS_MESH.bits()
| NodeBitFlags::UNK10.bits()
// | NodeBitFlags::TERRAIN.bits()
Expand Down Expand Up @@ -61,7 +61,7 @@ pub fn assert_variants(node: NodeVariantsRc, offset: u32) -> Result<NodeVariantR
node.area_partition == None,
offset + 76
)?;
assert_that!("empty has parent", node.has_parent == false, offset + 84)?;
assert_that!("empty parent count", node.parent_count == 0, offset + 84)?;
// parent_array_ptr (88) already asserted
assert_that!(
"empty children count",
Expand Down Expand Up @@ -98,7 +98,7 @@ pub fn make_variants(empty: &Empty) -> NodeVariantsRc {
data_ptr: 0,
mesh_index: -1,
area_partition: None,
has_parent: false,
parent_count: 0,
parent_array_ptr: 0,
children_count: 0,
children_array_ptr: 0,
Expand Down
4 changes: 2 additions & 2 deletions crates/mech3ax-nodes/src/rc/light/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn assert_variants(node: NodeVariantsRc, offset: u32) -> Result<NodeVariantR
node.area_partition == None,
offset + 76
)?;
assert_that!("light has parent", node.has_parent == false, offset + 84)?;
assert_that!("light parent count", node.parent_count == 0, offset + 84)?;
// parent_array_ptr (88) already asserted
assert_that!(
"light children count",
Expand Down Expand Up @@ -79,7 +79,7 @@ pub fn make_variants(light: &Light) -> NodeVariantsRc {
data_ptr: light.data_ptr,
mesh_index: -1,
area_partition: None,
has_parent: false,
parent_count: 0,
parent_array_ptr: 0,
children_count: 0,
children_array_ptr: 0,
Expand Down
2 changes: 1 addition & 1 deletion crates/mech3ax-nodes/src/rc/lod/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn assert_lod(lod: &LodRcC, offset: u32) -> Result<(bool, Range, f32, Option<u32
let level = assert_that!("lod level", bool lod.level, offset + 0)?;
assert_that!("lod range near sq", 0.0 <= lod.range_near_sq <= 1000.0 * 1000.0, offset + 4)?;
let range_near = lod.range_near_sq.sqrt();
assert_that!("lod range far", lod.range_far > 0.0, offset + 8)?;
assert_that!("lod range far", lod.range_far >= 0.0, offset + 8)?;
let expected = lod.range_far * lod.range_far;
assert_that!(
"lod range far sq",
Expand Down
10 changes: 6 additions & 4 deletions crates/mech3ax-nodes/src/rc/lod/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::rc::node::{NodeVariantLodRc, NodeVariantRc, NodeVariantsRc};
use crate::types::ZONE_DEFAULT;
use mech3ax_api_types::nodes::rc::Lod;
use mech3ax_api_types::nodes::BoundingBox;
use mech3ax_common::{assert_len, assert_that, Result};
use mech3ax_common::{assert_len, assert_that, bool_c, Result};

const ALWAYS_PRESENT: NodeBitFlags = NodeBitFlags::from_bits_truncate(
0
Expand Down Expand Up @@ -77,7 +77,9 @@ pub fn assert_variants(node: NodeVariantsRc, offset: u32) -> Result<NodeVariantR
node.area_partition == None,
offset + 76
)?;
// has_parent (84) is variable
// parent_count (84) is variable
// can only have one parent
let has_parent = assert_that!("parent count", bool node.parent_count, offset + 84)?;
// parent_array_ptr (88) already asserted
// children_count (92) is variable
// children_array_ptr (96) already asserted
Expand All @@ -97,7 +99,7 @@ pub fn assert_variants(node: NodeVariantsRc, offset: u32) -> Result<NodeVariantR
flags: node.flags,
zone_id: node.zone_id,
data_ptr: node.data_ptr,
has_parent: node.has_parent,
has_parent,
parent_array_ptr: node.parent_array_ptr,
children_count: node.children_count,
children_array_ptr: node.children_array_ptr,
Expand All @@ -120,7 +122,7 @@ pub fn make_variants(lod: &Lod) -> Result<NodeVariantsRc> {
data_ptr: lod.data_ptr,
mesh_index: -1,
area_partition: None,
has_parent: lod.parent.is_some(),
parent_count: bool_c!(lod.parent.is_some()),
parent_array_ptr: lod.parent_array_ptr,
children_count,
children_array_ptr: lod.children_array_ptr,
Expand Down
22 changes: 11 additions & 11 deletions crates/mech3ax-nodes/src/rc/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use mech3ax_api_types::{static_assert_size, ReprSize as _};
use mech3ax_common::assert::{assert_all_zero, assert_utf8};
use mech3ax_common::io_ext::{CountingReader, CountingWriter};
use mech3ax_common::string::{str_from_c_node_name, str_to_c_node_name};
use mech3ax_common::{assert_that, assert_with_msg, bool_c, Result};
use mech3ax_common::{assert_that, assert_with_msg, Result};
use mech3ax_debug::{Ascii, Hex, Ptr};
use num_traits::FromPrimitive;
use std::io::{Read, Write};
Expand All @@ -29,7 +29,7 @@ pub struct NodeVariantsRc {
pub data_ptr: u32,
pub mesh_index: i32,
pub area_partition: Option<AreaPartition>,
pub has_parent: bool,
pub parent_count: u32,
pub parent_array_ptr: u32,
pub children_count: u32,
pub children_array_ptr: u32,
Expand Down Expand Up @@ -166,21 +166,21 @@ fn assert_node(node: NodeRcC, offset: u32) -> Result<(NodeType, NodeVariantsRc)>
Some(node.area_partition)
};

// can only have one parent
let has_parent = assert_that!("parent count", bool node.parent_count, offset + 84)?;
if has_parent {
// upper bound is arbitrary
assert_that!("parent count", 0 <= node.parent_count <= 80, offset + 84)?;
if node.parent_count == 0 {
assert_that!(
"parent array ptr",
node.parent_array_ptr != Ptr::NULL,
node.parent_array_ptr == Ptr::NULL,
offset + 88
)?;
} else {
assert_that!(
"parent array ptr",
node.parent_array_ptr == Ptr::NULL,
node.parent_array_ptr != Ptr::NULL,
offset + 88
)?;
};
}

// upper bound is arbitrary
assert_that!("children count", 0 <= node.children_count <= 80, offset + 92)?;
Expand All @@ -196,7 +196,7 @@ fn assert_node(node: NodeRcC, offset: u32) -> Result<(NodeType, NodeVariantsRc)>
node.children_array_ptr != Ptr::NULL,
offset + 96
)?;
};
}

let variants = NodeVariantsRc {
name,
Expand All @@ -206,7 +206,7 @@ fn assert_node(node: NodeRcC, offset: u32) -> Result<(NodeType, NodeVariantsRc)>
data_ptr: node.data_ptr.0,
mesh_index: node.mesh_index,
area_partition,
has_parent,
parent_count: node.parent_count,
parent_array_ptr: node.parent_array_ptr.0,
children_count: node.children_count,
children_array_ptr: node.children_array_ptr.0,
Expand Down Expand Up @@ -333,7 +333,7 @@ fn write_variant(
action_priority: 1,
action_callback: 0,
area_partition,
parent_count: bool_c!(variant.has_parent),
parent_count: variant.parent_count,
parent_array_ptr: Ptr(variant.parent_array_ptr),
children_count: variant.children_count,
children_array_ptr: Ptr(variant.children_array_ptr),
Expand Down
Loading

0 comments on commit b9e9b46

Please sign in to comment.