1use anyhow::bail;
2use std::ffi::c_void;
3use std::ffi::CString;
4use std::ptr;
5
6#[allow(non_upper_case_globals)]
7#[allow(non_camel_case_types)]
8#[allow(non_snake_case)]
9pub mod bindings {
10 use std::os::raw::c_void;
11
12 #[repr(C)]
13 pub struct CBrres {
14 pub json_metadata: *const u8,
15 pub len_json_metadata: u32,
16 pub buffer_data: *const u8,
17 pub len_buffer_data: u32,
18 pub freeResult: extern "C" fn(*mut CBrres),
19 pub opaque: *mut c_void,
20 }
21
22 extern "C" {
23 pub fn imp_brres_read_from_bytes(result: *mut CBrres, buf: *const u8, len: u32) -> u32;
24 pub fn imp_brres_write_bytes(
25 result: *mut CBrres,
26 json: *const i8,
27 json_len: u32,
28 buffer: *const c_void,
29 buffer_len: u32,
30 write_type: u32,
31 ) -> u32;
32 pub fn imp_brres_free(result: *mut CBrres);
33
34 pub fn imp_brres_read_mdl0mat_preset(
35 result: *mut CBrres,
36 path: *const i8,
37 path_len: u32,
38 ) -> u32;
39 }
40}
41
42pub struct CBrresWrapper<'a> {
43 pub json_metadata: &'a str,
44 pub buffer_data: &'a [u8],
45 result: Box<bindings::CBrres>,
46}
47
48impl<'a> CBrresWrapper<'a> {
49 pub fn default() -> bindings::CBrres {
50 bindings::CBrres {
51 json_metadata: ptr::null(),
52 len_json_metadata: 0,
53 buffer_data: ptr::null(),
54 len_buffer_data: 0,
55 freeResult: dummy_free_result,
56 opaque: ptr::null_mut(),
57 }
58 }
59
60 pub fn from_bytes(buf: &[u8]) -> anyhow::Result<Self> {
61 unsafe {
62 let mut result: Box<bindings::CBrres> = Box::new(Self::default());
63
64 let ok = bindings::imp_brres_read_from_bytes(
65 &mut *result as *mut bindings::CBrres,
66 buf.as_ptr(),
67 buf.len() as u32,
68 );
69
70 let json_metadata = {
71 let slice = std::slice::from_raw_parts(
72 result.json_metadata,
73 result.len_json_metadata as usize,
74 );
75 std::str::from_utf8(slice).unwrap()
76 };
77
78 if ok == 0 {
79 bail!("Failed to read BRRES file: {json_metadata}");
80 }
81
82 let buffer_data =
83 std::slice::from_raw_parts(result.buffer_data, result.len_buffer_data as usize);
84
85 Ok(CBrresWrapper {
86 json_metadata,
87 buffer_data,
88 result,
89 })
90 }
91 }
92 pub fn write_bytes(json: &str, buffer: &[u8]) -> anyhow::Result<Self> {
93 let json_cstring = CString::new(json)?;
94 let json_ptr = json_cstring.as_ptr();
95 let json_len = json.len() as u32;
96 let buffer_ptr = buffer.as_ptr() as *const c_void;
97 let buffer_len = buffer.len() as u32;
98
99 unsafe {
100 let mut result: Box<bindings::CBrres> = Box::new(Self::default());
101
102 let ok = bindings::imp_brres_write_bytes(
103 &mut *result as *mut bindings::CBrres,
104 json_ptr,
105 json_len,
106 buffer_ptr,
107 buffer_len,
108 0, );
110
111 let json_metadata = {
112 let slice = std::slice::from_raw_parts(
113 result.json_metadata,
114 result.len_json_metadata as usize,
115 );
116 std::str::from_utf8(slice)?
117 };
118
119 if ok == 0 {
120 anyhow::bail!("Failed to write BRRES file: {json_metadata}");
121 }
122 let buffer_data =
123 std::slice::from_raw_parts(result.buffer_data, result.len_buffer_data as usize);
124
125 Ok(CBrresWrapper {
126 json_metadata,
127 buffer_data,
128 result,
129 })
130 }
131 }
132 pub fn read_preset_folder(json: &str) -> anyhow::Result<Self> {
133 let json_cstring = CString::new(json)?;
134 let json_ptr = json_cstring.as_ptr();
135 let json_len = json.len() as u32;
136
137 unsafe {
138 let mut result: Box<bindings::CBrres> = Box::new(Self::default());
139
140 let ok = bindings::imp_brres_read_mdl0mat_preset(
141 &mut *result as *mut bindings::CBrres,
142 json_ptr,
143 json_len,
144 );
145
146 if ok == 0 {
147 let json_metadata = {
148 let slice = std::slice::from_raw_parts(
149 result.json_metadata,
150 result.len_json_metadata as usize,
151 );
152 std::str::from_utf8(slice)?
153 };
154 anyhow::bail!("Failed to write BRRES file: {json_metadata}");
155 }
156 let buffer_data =
157 std::slice::from_raw_parts(result.buffer_data, result.len_buffer_data as usize);
158
159 Ok(CBrresWrapper {
160 json_metadata: "",
161 buffer_data,
162 result,
163 })
164 }
165 }
166}
167
168impl<'a> Drop for CBrresWrapper<'a> {
169 fn drop(&mut self) {
170 (self.result.freeResult)(&mut *self.result as *mut bindings::CBrres);
172 }
174}
175
176extern "C" fn dummy_free_result(_: *mut bindings::CBrres) {
177 }
179
180pub mod c_api {
182 use crate::*;
183 use core::ffi::c_char;
184 use gctex;
185 use wiitrig;
186
187 #[no_mangle]
192 pub unsafe extern "C" fn rii_compute_image_size2(format: u32, width: u32, height: u32) -> u32 {
193 gctex::c_api::rii_compute_image_size(format, width, height)
194 }
195
196 #[no_mangle]
197 pub unsafe extern "C" fn rsl_log_init2() {
198 }
200
201 #[no_mangle]
202 pub unsafe extern "C" fn rsl_c_debug2(_s: *const c_char, _len: u32) {
203 }
207 #[no_mangle]
208 pub unsafe extern "C" fn rsl_c_error2(_s: *const c_char, _len: u32) {
209 }
213 #[no_mangle]
214 pub unsafe extern "C" fn rsl_c_info2(_s: *const c_char, _len: u32) {
215 }
219 #[no_mangle]
220 pub unsafe extern "C" fn rsl_c_trace2(_s: *const c_char, _len: u32) {
221 }
225 #[no_mangle]
226 pub unsafe extern "C" fn rsl_c_warn2(_s: *const c_char, _len: u32) {
227 }
231
232 #[no_mangle]
233 pub unsafe extern "C" fn wii_sin2(x: f32) -> f32 {
234 wiitrig::wii_sin(x)
235 }
236
237 #[no_mangle]
238 pub unsafe extern "C" fn wii_cos2(x: f32) -> f32 {
239 wiitrig::wii_cos(x)
240 }
241
242 use core::ffi::c_void;
243
244 #[cfg(feature = "c_api")]
245 #[no_mangle]
246 pub unsafe fn brres_read_from_bytes(
247 result: *mut ffi::bindings::CBrres,
248 buf: *const u8,
249 len: u32,
250 ) -> u32 {
251 ffi::bindings::imp_brres_read_from_bytes(result, buf, len)
252 }
253 #[cfg(feature = "c_api")]
254 #[no_mangle]
255 pub unsafe fn brres_write_bytes(
256 result: *mut ffi::bindings::CBrres,
257 json: *const i8,
258 json_len: u32,
259 buffer: *const c_void,
260 buffer_len: u32,
261 write_type: u32,
262 ) -> u32 {
263 ffi::bindings::imp_brres_write_bytes(result, json, json_len, buffer, buffer_len, write_type)
264 }
265 #[cfg(feature = "c_api")]
266 #[no_mangle]
267 pub unsafe fn brres_free(result: *mut ffi::bindings::CBrres) {
268 ffi::bindings::imp_brres_free(result)
269 }
270 #[cfg(feature = "c_api")]
271 #[no_mangle]
272 pub unsafe fn brres_read_mdl0mat_preset(
273 result: *mut ffi::bindings::CBrres,
274 path: *const i8,
275 path_len: u32,
276 ) {
277 ffi::bindings::imp_brres_read_mdl0mat_preset(result, path, path_len);
278 }
279}