1#include "Library/Yaml/ByamlUtil.h"
2
3#include "Library/Yaml/ByamlData.h"
4#include "Library/Yaml/ByamlIter.h"
5
6namespace al {
7bool tryGetByamlU8(u8* pOut, const ByamlIter& rIter, const char* pKey) {
8 s32 value = 0;
9 if (rIter.tryGetIntByKey(val: &value, key: pKey)) {
10 *pOut = value;
11 return true;
12 }
13 return false;
14}
15
16bool tryGetByamlU16(u16* pOut, const ByamlIter& rIter, const char* pKey) {
17 s32 value = 0;
18 if (rIter.tryGetIntByKey(val: &value, key: pKey)) {
19 *pOut = value;
20 return true;
21 }
22 return false;
23}
24
25bool tryGetByamlS16(s16* pOut, const ByamlIter& rIter, const char* pKey) {
26 s32 value = 0;
27 if (rIter.tryGetIntByKey(val: &value, key: pKey)) {
28 *pOut = value;
29 return true;
30 }
31 return false;
32}
33
34bool tryGetByamlS32(s32* pOut, const ByamlIter& rIter, const char* pKey) {
35 return rIter.tryGetIntByKey(val: pOut, key: pKey);
36}
37
38bool tryGetByamlU32(u32* pOut, const ByamlIter& rIter, const char* pKey) {
39 s32 value = 0;
40 bool res = rIter.tryGetIntByKey(val: &value, key: pKey);
41 if (res)
42 *pOut = value;
43 return res;
44}
45
46bool tryGetByamlS64(s64* pOut, const ByamlIter& rIter, const char* pKey) {
47 return rIter.tryGetInt64ByKey(val: pOut, key: pKey);
48}
49
50bool tryGetByamlU64(u64* pOut, const ByamlIter& rIter, const char* pKey) {
51 u64 value = 0;
52 bool res = rIter.tryGetUInt64ByKey(val: &value, key: pKey);
53 if (res)
54 *pOut = value;
55 return res;
56}
57
58bool tryGetByamlF32(f32* pOut, const ByamlIter& rIter, const char* pKey) {
59 f32 value = 0;
60 if (rIter.tryGetFloatByKey(val: &value, key: pKey)) {
61 *pOut = value;
62 return true;
63 }
64 return false;
65}
66
67bool tryGetByamlV2f(sead::Vector2f* pOut, const ByamlIter& rIter) {
68 f32 x = 0;
69 bool x_ret = rIter.tryGetFloatByKey(val: &x, key: "X");
70 f32 y = 0;
71 bool y_ret = rIter.tryGetFloatByKey(val: &y, key: "Y");
72
73 *pOut = {x, y};
74 return x_ret || y_ret;
75}
76
77bool tryGetByamlV3f(sead::Vector3f* pOut, const ByamlIter& rIter) {
78 bool result = false;
79 f32 x = 0;
80 result = rIter.tryGetFloatByKey(val: &x, key: "X");
81 f32 y = 0;
82 result |= rIter.tryGetFloatByKey(val: &y, key: "Y");
83 f32 z = 0;
84 result |= rIter.tryGetFloatByKey(val: &z, key: "Z");
85
86 *pOut = {x, y, z};
87 return result;
88}
89
90bool tryGetByamlV4f(sead::Vector4f* pOut, const ByamlIter& rIter) {
91 bool result = false;
92 f32 x = 0;
93 result = rIter.tryGetFloatByKey(val: &x, key: "X");
94 f32 y = 0;
95 result |= rIter.tryGetFloatByKey(val: &y, key: "Y");
96 f32 z = 0;
97 result |= rIter.tryGetFloatByKey(val: &z, key: "Z");
98 f32 w = 0;
99 result |= rIter.tryGetFloatByKey(val: &w, key: "W");
100
101 *pOut = {x, y, z, w};
102 return result;
103}
104
105bool tryGetByamlScale(sead::Vector3f* pOut, const ByamlIter& rIter) {
106 bool result = false;
107 f32 x = 1;
108 result = rIter.tryGetFloatByKey(val: &x, key: "X");
109 f32 y = 1;
110 result |= rIter.tryGetFloatByKey(val: &y, key: "Y");
111 f32 z = 1;
112 result |= rIter.tryGetFloatByKey(val: &z, key: "Z");
113
114 *pOut = {x, y, z};
115 return result;
116}
117
118bool tryGetByamlV2s32(sead::Vector2i* pOut, const ByamlIter& rIter) {
119 s32 x = 0;
120 bool x_ret = rIter.tryGetIntByKey(val: &x, key: "X");
121 s32 y = 0;
122 bool y_ret = rIter.tryGetIntByKey(val: &y, key: "Y");
123
124 *pOut = {x, y};
125 return x_ret || y_ret;
126}
127
128bool tryGetByamlV3s32(sead::Vector3i* pOut, const ByamlIter& rIter) {
129 bool result = false;
130 s32 x = 0;
131 result = rIter.tryGetIntByKey(val: &x, key: "X");
132 s32 y = 0;
133 result |= rIter.tryGetIntByKey(val: &y, key: "Y");
134 s32 z = 0;
135 result |= rIter.tryGetIntByKey(val: &z, key: "Z");
136
137 *pOut = {x, y, z};
138 return result;
139}
140
141bool tryGetByamlBox3f(sead::BoundBox3f* pOut, const ByamlIter& rIter) {
142 sead::Vector3f min, max;
143 if (!tryGetByamlV3f(&min, rIter, "Min"))
144 return false;
145 if (!tryGetByamlV3f(&max, rIter, "Max"))
146 return false;
147 *pOut = {min, max};
148 return true;
149}
150
151bool tryGetByamlV3f(sead::Vector3f* pOut, const ByamlIter& sIter, const char* key) {
152 ByamlIter rIter;
153 if (!sIter.tryGetIterByKey(iter: &rIter, key))
154 return false;
155
156 return tryGetByamlV3f(pOut, rIter);
157}
158
159bool tryGetByamlV2f(sead::Vector2f* pOut, const ByamlIter& sIter, const char* key) {
160 ByamlIter rIter;
161 if (!sIter.tryGetIterByKey(iter: &rIter, key))
162 return false;
163
164 return tryGetByamlV2f(pOut, rIter);
165}
166
167bool tryGetByamlV4f(sead::Vector4f* pOut, const ByamlIter& sIter, const char* key) {
168 ByamlIter rIter;
169 if (!sIter.tryGetIterByKey(iter: &rIter, key))
170 return false;
171
172 return tryGetByamlV4f(pOut, rIter);
173}
174
175bool tryGetByamlScale(sead::Vector3f* pOut, const ByamlIter& sIter, const char* key) {
176 ByamlIter rIter;
177 if (!sIter.tryGetIterByKey(iter: &rIter, key))
178 return false;
179
180 return tryGetByamlScale(pOut, rIter);
181}
182
183bool tryGetByamlV2s32(sead::Vector2i* pOut, const ByamlIter& sIter, const char* key) {
184 ByamlIter rIter;
185 if (!sIter.tryGetIterByKey(iter: &rIter, key))
186 return false;
187
188 return tryGetByamlV2s32(pOut, rIter);
189}
190
191bool tryGetByamlV3s32(sead::Vector3i* pOut, const ByamlIter& sIter, const char* key) {
192 ByamlIter rIter;
193 if (!sIter.tryGetIterByKey(iter: &rIter, key))
194 return false;
195
196 return tryGetByamlV3s32(pOut, rIter);
197}
198
199bool tryGetByamlBox3f(sead::BoundBox3f* pOut, const ByamlIter& sIter, const char* key) {
200 ByamlIter rIter;
201 if (!sIter.tryGetIterByKey(iter: &rIter, key))
202 return false;
203
204 return tryGetByamlBox3f(pOut, rIter);
205}
206
207bool tryGetByamlString(const char** pOut, const ByamlIter& rIter, const char* key) {
208 return rIter.tryGetStringByKey(string: pOut, key);
209}
210
211bool tryGetByamlColor(sead::Color4f* pOut, const ByamlIter& rIter) {
212 bool result = false;
213 f32 r = 0;
214 result = rIter.tryGetFloatByKey(val: &r, key: "R");
215 f32 g = 0;
216 result |= rIter.tryGetFloatByKey(val: &g, key: "G");
217 f32 b = 0;
218 result |= rIter.tryGetFloatByKey(val: &b, key: "B");
219 f32 a = 0;
220 result |= rIter.tryGetFloatByKey(val: &a, key: "A");
221
222 *pOut = {r, g, b, a};
223 return result;
224}
225
226bool tryGetByamlColor(sead::Color4f* pOut, const ByamlIter& sIter, const char* key) {
227 ByamlIter rIter;
228 if (!sIter.tryGetIterByKey(iter: &rIter, key))
229 return false;
230
231 return tryGetByamlColor(pOut, rIter);
232}
233
234bool tryGetByamlBool(bool* pOut, const ByamlIter& rIter, const char* key) {
235 return rIter.tryGetBoolByKey(val: pOut, key);
236}
237
238const char* tryGetByamlKeyStringOrNULL(const ByamlIter& rIter, const char* key) {
239 const char* val = nullptr;
240 if (rIter.tryGetStringByKey(string: &val, key))
241 return val;
242 return nullptr;
243}
244
245s32 tryGetByamlKeyIntOrZero(const ByamlIter& rIter, const char* key) {
246 s32 val = 0;
247 if (rIter.tryGetIntByKey(val: &val, key))
248 return val;
249 return 0;
250}
251
252u32 tryGetByamlKeyU32OrZero(const ByamlIter& rIter, const char* key) {
253 u32 val = 0;
254 if (rIter.tryGetUIntByKey(val: &val, key))
255 return val;
256 return 0;
257}
258
259f32 tryGetByamlKeyFloatOrZero(const ByamlIter& rIter, const char* key) {
260 f32 val = 0;
261 if (rIter.tryGetFloatByKey(val: &val, key))
262 return val;
263 return 0;
264}
265
266bool tryGetByamlKeyBoolOrFalse(const ByamlIter& rIter, const char* key) {
267 bool val = false;
268 if (rIter.tryGetBoolByKey(val: &val, key))
269 return val;
270 return false;
271}
272
273bool tryGetByamlIterByKey(ByamlIter* pOut, const ByamlIter& rIter, const char* key) {
274 return rIter.tryGetIterByKey(iter: pOut, key);
275}
276
277bool tryGetByamlKeyAndIntByIndex(const char** key, s32* pOut, const ByamlIter& rIter, s32 index) {
278 ByamlData data;
279 if (!rIter.getByamlDataAndKeyName(data: &data, key, index))
280 return false;
281 if (!rIter.tryConvertInt(val: pOut, data: &data))
282 return false;
283 return true;
284}
285
286const char* getByamlKeyString(const ByamlIter& rIter, const char* key) {
287 return tryGetByamlKeyStringOrNULL(rIter, key);
288}
289
290s32 getByamlKeyInt(const ByamlIter& rIter, const char* key) {
291 return tryGetByamlKeyIntOrZero(rIter, key);
292}
293
294f32 getByamlKeyFloat(const ByamlIter& rIter, const char* key) {
295 return tryGetByamlKeyFloatOrZero(rIter, key);
296}
297
298bool getByamlKeyBool(const ByamlIter& rIter, const char* key) {
299 return tryGetByamlKeyBoolOrFalse(rIter, key);
300}
301
302void getByamlIterByKey(ByamlIter* pOut, const ByamlIter& rIter, const char* pKey) {
303 rIter.tryGetIterByKey(iter: pOut, key: pKey);
304}
305
306void getByamlIterByIndex(ByamlIter* pOut, const ByamlIter& rIter, s32 index) {
307 rIter.tryGetIterByIndex(iter: pOut, index);
308}
309
310bool isTypeBoolByIndex(const ByamlIter& rIter, s32 index) {
311 return isTypeByIndex<ByamlDataType::TYPE_BOOL>(rIter, index);
312}
313
314bool isTypeBoolByKey(const ByamlIter& rIter, const char* pKey) {
315 return isTypeByKey<ByamlDataType::TYPE_BOOL>(rIter, key: pKey);
316}
317
318bool isTypeIntByIndex(const ByamlIter& rIter, s32 index) {
319 return isTypeByIndex<ByamlDataType::TYPE_INT>(rIter, index);
320}
321
322bool isTypeIntByKey(const ByamlIter& rIter, const char* pKey) {
323 return isTypeByKey<ByamlDataType::TYPE_INT>(rIter, key: pKey);
324}
325
326bool isTypeFloatByIndex(const ByamlIter& rIter, s32 index) {
327 return isTypeByIndex<ByamlDataType::TYPE_FLOAT>(rIter, index);
328}
329
330bool isTypeFloatByKey(const ByamlIter& rIter, const char* pKey) {
331 return isTypeByKey<ByamlDataType::TYPE_FLOAT>(rIter, key: pKey);
332}
333
334bool isTypeStringByIndex(const ByamlIter& rIter, s32 index) {
335 return isTypeByIndex<ByamlDataType::TYPE_STRING>(rIter, index);
336}
337
338bool isTypeStringByKey(const ByamlIter& rIter, const char* pKey) {
339 return isTypeByKey<ByamlDataType::TYPE_STRING>(rIter, key: pKey);
340}
341
342bool isTypeArrayByIndex(const ByamlIter& rIter, s32 index) {
343 return isTypeByIndex<ByamlDataType::TYPE_ARRAY>(rIter, index);
344}
345
346bool isTypeArrayByKey(const ByamlIter& rIter, const char* pKey) {
347 return isTypeByKey<ByamlDataType::TYPE_ARRAY>(rIter, key: pKey);
348}
349
350bool isTypeHashByIndex(const ByamlIter& rIter, s32 index) {
351 return isTypeByIndex<ByamlDataType::TYPE_HASH>(rIter, index);
352}
353
354bool isTypeHashByKey(const ByamlIter& rIter, const char* pKey) {
355 return isTypeByKey<ByamlDataType::TYPE_HASH>(rIter, key: pKey);
356}
357
358s32 getByamlIterDataNum(const ByamlIter& rIter) {
359 return rIter.getSize();
360}
361
362void printByamlIter(const u8* data) {
363 ByamlIter iter = {data};
364 printByamlIter(iter);
365}
366
367void printByamlIter(const ByamlIter& iter) {
368 u32 data_off = iter.getHeader()->getDataOffset();
369 PrintParams param = {.depth: 0, .offset: data_off, .parent: nullptr};
370 printByamlIter_(iter, &param);
371}
372
373void printByamlIter_(const ByamlIter& iter, PrintParams* param) {
374 s32 size = iter.getSize();
375 for (s32 i = 0; i < size; ++i) {
376 ByamlData entry;
377 if (iter.isTypeArray()) {
378 iter.getByamlDataByIndex(data: &entry, index: i);
379 } else if (iter.isTypeHash()) {
380 const char* data = nullptr;
381 iter.getByamlDataAndKeyName(data: &entry, key: &data, index: i);
382 }
383 if (entry.getType() == ByamlDataType::TYPE_HASH ||
384 entry.getType() == ByamlDataType::TYPE_ARRAY) {
385 u32 v6 = entry.getValue();
386 if (param) {
387 PrintParams* sub_param = param;
388 while (sub_param) {
389 if (sub_param->offset == v6)
390 goto loop;
391 sub_param = sub_param->parent;
392 }
393 }
394 ByamlIter a1 = {};
395 if (iter.tryGetIterByIndex(iter: &a1, index: i)) {
396 s32 depth = param->depth + 1;
397 u32 value = entry.getValue();
398 PrintParams new_param = {.depth: depth, .offset: value, .parent: param};
399 printByamlIter_(iter: a1, param: &new_param);
400 }
401 } else {
402 u8 type = entry.getType();
403 if (type == ByamlDataType::TYPE_FLOAT) {
404 f32 data;
405 iter.tryConvertFloat(val: &data, data: &entry);
406 } else if (type == ByamlDataType::TYPE_INT) {
407 s32 data;
408 iter.tryConvertInt(val: &data, data: &entry);
409 } else if (type == ByamlDataType::TYPE_STRING) {
410 const char* data;
411 iter.tryConvertString(string: &data, data: &entry);
412 } else if (type == ByamlDataType::TYPE_BOOL) {
413 bool data;
414 iter.tryConvertBool(val: &data, data: &entry);
415 }
416 }
417 loop:;
418 }
419}
420} // namespace al
421