Skip to main content

classicube_sys/
model.rs

1use crate::{
2    bindings::{BoxDesc, FACE_CONSTS_FACE_COUNT, MODEL_QUAD_VERTICES, ModelPart, cc_uint16},
3    std_types::c_float,
4};
5
6#[allow(clippy::unnecessary_cast)]
7pub const MODEL_BOX_VERTICES: u32 = FACE_CONSTS_FACE_COUNT as u32 * MODEL_QUAD_VERTICES as u32;
8
9#[macro_export]
10macro_rules! BoxDesc_Dim {
11    ($p1:expr, $p2:expr) => {
12        #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
13        {
14            (if $p1 < $p2 { $p2 - $p1 } else { $p1 - $p2 }) as u8
15        }
16    };
17}
18
19// Macros for making initialising a BoxDesc easier to understand. See Model.c for how these get used.
20
21#[macro_export]
22macro_rules! BoxDesc_Tex {
23    ($x:expr, $y:expr) => {
24        ($x, $y)
25    };
26}
27
28/// gives (x, y, z)
29#[macro_export]
30macro_rules! BoxDesc_Dims {
31    ($x1:expr, $y1:expr, $z1:expr, $x2:expr, $y2:expr, $z2:expr) => {
32        (
33            $crate::BoxDesc_Dim!($x1, $x2),
34            $crate::BoxDesc_Dim!($y1, $y2),
35            $crate::BoxDesc_Dim!($z1, $z2),
36        )
37    };
38}
39
40/// gives (x1, y1, z1, x2, y2, z2)
41#[cfg(feature = "no_std")]
42#[macro_export]
43macro_rules! BoxDesc_Bounds {
44    ($x1:expr, $y1:expr, $z1:expr, $x2:expr, $y2:expr, $z2:expr) => {
45        #[allow(clippy::cast_precision_loss)]
46        (
47            $x1 as ::libc::c_float / 16.0,
48            $y1 as ::libc::c_float / 16.0,
49            $z1 as ::libc::c_float / 16.0,
50            $x2 as ::libc::c_float / 16.0,
51            $y2 as ::libc::c_float / 16.0,
52            $z2 as ::libc::c_float / 16.0,
53        )
54    };
55}
56#[cfg(not(feature = "no_std"))]
57#[macro_export]
58macro_rules! BoxDesc_Bounds {
59    ($x1:expr, $y1:expr, $z1:expr, $x2:expr, $y2:expr, $z2:expr) => {
60        #[allow(clippy::cast_precision_loss)]
61        (
62            $x1 as ::std::os::raw::c_float / 16.0,
63            $y1 as ::std::os::raw::c_float / 16.0,
64            $z1 as ::std::os::raw::c_float / 16.0,
65            $x2 as ::std::os::raw::c_float / 16.0,
66            $y2 as ::std::os::raw::c_float / 16.0,
67            $z2 as ::std::os::raw::c_float / 16.0,
68        )
69    };
70}
71
72/// gives (x, y, z)
73#[macro_export]
74macro_rules! BoxDesc_Rot {
75    ($x:expr, $y:expr, $z:expr) => {
76        ($x / 16.0, $y / 16.0, $z / 16.0)
77    };
78}
79
80/// gives ((x, y, z), (x1, y1, z1, x2, y2, z2))
81#[macro_export]
82macro_rules! BoxDesc_Box {
83    ($x1:expr, $y1:expr, $z1:expr, $x2:expr, $y2:expr, $z2:expr) => {
84        (
85            $crate::BoxDesc_Dims!($x1, $y1, $z1, $x2, $y2, $z2),
86            $crate::BoxDesc_Bounds!($x1, $y1, $z1, $x2, $y2, $z2),
87        )
88    };
89}
90
91type BoxDescDimsReturn = (u8, u8, u8);
92type BoxDescBoundsReturn = (c_float, c_float, c_float, c_float, c_float, c_float);
93impl BoxDesc {
94    #[must_use]
95    pub fn from_macros(
96        (texX, texY): (u16, u16),
97        ((sizeX, sizeY, sizeZ), (x1, y1, z1, x2, y2, z2)): (BoxDescDimsReturn, BoxDescBoundsReturn),
98    ) -> Self {
99        Self {
100            texX,
101            texY,
102            sizeX,
103            sizeY,
104            sizeZ,
105            x1,
106            y1,
107            z1,
108            x2,
109            y2,
110            z2,
111            rotX: 0.0,
112            rotY: 0.0,
113            rotZ: 0.0,
114        }
115    }
116}
117
118#[macro_export]
119macro_rules! Model_RetSize {
120    ($e:expr, $x:expr, $y:expr, $z:expr) => {
121        static P: $crate::Vec3 = $crate::Vec3::new(
122            $x/16.0,
123            $y/16.0,
124            $z/16.0
125        );
126        $e.Size = P;
127    };
128}
129
130#[macro_export]
131macro_rules! Model_RetAABB {
132    ($e:expr, $x1:expr, $y1:expr, $z1:expr, $x2:expr, $y2:expr, $z2:expr) => {
133        static BB: $crate::AABB = $crate::AABB {
134            Min: $crate::Vec3::new($x1 / 16.0, $y1 / 16.0, $z1 / 16.0),
135            Max: $crate::Vec3::new($x2 / 16.0, $y2 / 16.0, $z2 / 16.0),
136        };
137        $e.ModelAABB = BB;
138    };
139}
140
141#[test]
142fn test_model_macros() {
143    use crate::bindings::Entity;
144
145    fn BoxDesc_BuildBox(_part: *mut ModelPart, desc: *const BoxDesc) {
146        #[cfg(not(feature = "no_std"))]
147        unsafe {
148            println!("{:#?}", *desc);
149        }
150    }
151
152    let mut part: ModelPart = unsafe { core::mem::zeroed() };
153    let desc = BoxDesc::from_macros(BoxDesc_Tex!(0, 16), BoxDesc_Box!(-3, 1, -3, 3, 7, 3));
154    BoxDesc_BuildBox(&raw mut part, &raw const desc);
155
156    let mut e: Entity = unsafe { core::mem::zeroed() };
157    Model_RetSize!(e, 0.0, 0.0, 0.0);
158
159    let mut e: Entity = unsafe { core::mem::zeroed() };
160    Model_RetAABB!(e, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
161}
162
163pub fn ModelPart_Init(
164    part: &mut ModelPart,
165    offset: cc_uint16,
166    count: cc_uint16,
167    rotX: c_float,
168    rotY: c_float,
169    rotZ: c_float,
170) {
171    part.offset = offset;
172    part.count = count;
173    part.rotX = rotX;
174    part.rotY = rotY;
175    part.rotZ = rotZ;
176}