Skip to content

Commit b455b65

Browse files
committed
Rework parsing to use concepts
1 parent fed6fab commit b455b65

File tree

4 files changed

+133
-140
lines changed

4 files changed

+133
-140
lines changed

include/Common.cc

Lines changed: 0 additions & 102 deletions
This file was deleted.

include/Common.hh

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <array>
44
#include <assert.h>
55
#include <bit>
6+
#include <concepts>
67
#include <cstdint>
78
#include <cstdio>
89
#include <cstdlib>
@@ -251,8 +252,106 @@ static constexpr WeightClass VehicleToWeight(Vehicle vehicle) {
251252
}
252253
}
253254

254-
extern const char *const COURSE_NAMES[59];
255-
extern const char *const VEHICLE_NAMES[36];
255+
static constexpr char *COURSE_NAMES[59] = {
256+
"castle_course",
257+
"farm_course",
258+
"kinoko_course",
259+
"volcano_course",
260+
"factory_course",
261+
"shopping_course",
262+
"boardcross_course",
263+
"truck_course",
264+
"beginner_course",
265+
"senior_course",
266+
"ridgehighway_course",
267+
"treehouse_course",
268+
"koopa_course",
269+
"rainbow_course",
270+
"desert_course",
271+
"water_course",
272+
"old_peach_gc",
273+
"old_mario_gc",
274+
"old_waluigi_gc",
275+
"old_donkey_gc",
276+
"old_falls_ds",
277+
"old_desert_ds",
278+
"old_garden_ds",
279+
"old_town_ds",
280+
"old_mario_sfc",
281+
"old_obake_sfc",
282+
"old_mario_64",
283+
"old_sherbet_64",
284+
"old_koopa_64",
285+
"old_donkey_64",
286+
"old_koopa_gba",
287+
"old_heyho_gba",
288+
"venice_battle",
289+
"block_battle",
290+
"casino_battle",
291+
"skate_battle",
292+
"sand_battle",
293+
"old_CookieLand_gc",
294+
"old_House_ds",
295+
"old_battle4_sfc",
296+
"old_battle3_gba",
297+
"old_matenro_64",
298+
nullptr,
299+
nullptr,
300+
nullptr,
301+
nullptr,
302+
nullptr,
303+
nullptr,
304+
nullptr,
305+
nullptr,
306+
nullptr,
307+
nullptr,
308+
nullptr,
309+
nullptr,
310+
"ring_mission",
311+
"winningrun_demo",
312+
"loser_demo",
313+
"draw_dmeo",
314+
"ending_demo",
315+
};
316+
317+
static constexpr char *VEHICLE_NAMES[36] = {
318+
"sdf_kart",
319+
"mdf_kart",
320+
"ldf_kart",
321+
"sa_kart",
322+
"ma_kart",
323+
"la_kart",
324+
"sb_kart",
325+
"mb_kart",
326+
"lb_kart",
327+
"sc_kart",
328+
"mc_kart",
329+
"lc_kart",
330+
"sd_kart",
331+
"md_kart",
332+
"ld_kart",
333+
"se_kart",
334+
"me_kart",
335+
"le_kart",
336+
"sdf_bike",
337+
"mdf_bike",
338+
"ldf_bike",
339+
"sa_bike",
340+
"ma_bike",
341+
"la_bike",
342+
"sb_bike",
343+
"mb_bike",
344+
"lb_bike",
345+
"sc_bike",
346+
"mc_bike",
347+
"lc_bike",
348+
"sd_bike",
349+
"md_bike",
350+
"ld_bike",
351+
"se_bike",
352+
"me_bike",
353+
"le_bike",
354+
};
256355

257356
// CREDIT: MKW-SP
258357
// Hack required to print preprocessor macro
@@ -274,11 +373,19 @@ extern const char *const VEHICLE_NAMES[36];
274373
} while (0)
275374

276375
static_assert(FLT_EPSILON == 1.0f / 8388608.0f);
376+
static_assert(
377+
std::endian::native == std::endian::big || std::endian::native == std::endian::little);
378+
379+
template <typename T>
380+
concept IntegralType = std::is_integral_v<T>;
277381

278-
// Form data into integral value
279382
template <typename T>
383+
concept ParseableType =
384+
std::is_integral_v<T> || std::is_floating_point_v<T> && sizeof(T) == 4 || sizeof(T) == 8;
385+
386+
// Form data into integral value
387+
template <IntegralType T>
280388
static inline T form(const u8 *data) {
281-
static_assert(std::is_integral<T>::value);
282389
T result = 0;
283390
for (size_t i = 0; i < sizeof(T); ++i) {
284391
result = (result << 8) | data[i];
@@ -287,14 +394,15 @@ static inline T form(const u8 *data) {
287394
}
288395

289396
// Consistent file parsing with byte-swappable values
290-
template <typename T>
397+
template <ParseableType T>
291398
static inline T parse(T val, std::endian endian = std::endian::big) {
292-
static_assert(
293-
std::endian::native == std::endian::big || std::endian::native == std::endian::little);
294-
return endian == std::endian::native ? val : std::byteswap(val);
295-
}
296-
297-
// Does not support f64
298-
static inline f32 parsef(f32 val, std::endian endian) {
299-
return std::bit_cast<f32>(parse<u32>(std::bit_cast<u32>(val), endian));
399+
if constexpr (std::is_integral_v<T>) {
400+
return endian == std::endian::native ? val : std::byteswap(val);
401+
} else {
402+
if constexpr (sizeof(T) == 4) {
403+
return std::bit_cast<T>(parse<u32>(std::bit_cast<u32>(val), endian));
404+
} else {
405+
return std::bit_cast<T>(parse<u64>(std::bit_cast<u64>(val), endian));
406+
}
407+
}
300408
}

source/egg/util/Stream.cc

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,12 @@ s64 Stream::read_s64() {
5656
return read<s64>();
5757
}
5858

59-
// Floating point numbers are not integral, so we have special cases outside of the template
6059
f32 Stream::read_f32() {
61-
f32 val;
62-
read(&val, sizeof(val));
63-
m_index += sizeof(val);
64-
assert(!eof());
65-
66-
return std::bit_cast<f32>(parse<u32>(std::bit_cast<u32>(val), m_endian));
60+
return read<f32>();
6761
}
6862

6963
f64 Stream::read_f64() {
70-
f64 val;
71-
read(&val, sizeof(val));
72-
m_index += sizeof(val);
73-
assert(!eof());
74-
75-
return std::bit_cast<f64>(parse<u64>(std::bit_cast<u64>(val), m_endian));
64+
return read<f64>();
7665
}
7766

7867
RamStream::RamStream() : m_buffer(nullptr), m_size(0) {}
@@ -83,14 +72,6 @@ RamStream::RamStream(u8 *buffer, u32 size) {
8372

8473
RamStream::~RamStream() = default;
8574

86-
RamStream RamStream::split(u32 size) {
87-
RamStream stream = RamStream(m_buffer + m_index, size);
88-
m_index += size;
89-
assert(!eof());
90-
91-
return stream;
92-
}
93-
9475
void RamStream::read(void *output, u32 size) {
9576
u8 *buffer = reinterpret_cast<u8 *>(output);
9677
for (size_t i = 0; i < size; ++i) {
@@ -114,4 +95,12 @@ void RamStream::setBufferAndSize(void *buffer, u32 size) {
11495
m_size = size;
11596
}
11697

98+
RamStream RamStream::split(u32 size) {
99+
RamStream stream = RamStream(m_buffer + m_index, size);
100+
m_index += size;
101+
assert(!eof());
102+
103+
return stream;
104+
}
105+
117106
} // namespace EGG

source/egg/util/Stream.hh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ protected:
3636
u32 m_index;
3737

3838
private:
39-
template <typename T>
39+
template <ParseableType T>
4040
T read() {
41-
static_assert(std::is_integral<T>::value);
4241
T val;
4342
read(&val, sizeof(val));
4443
m_index += sizeof(val);
@@ -54,12 +53,11 @@ public:
5453
RamStream(u8 *buffer, u32 size);
5554
~RamStream() override;
5655

57-
RamStream split(u32 size);
58-
5956
void read(void *output, u32 size) override;
6057
void write(void *input, u32 size) override;
6158
bool eof() override;
6259

60+
RamStream split(u32 size);
6361
void setBufferAndSize(void *buffer, u32 size);
6462

6563
private:

0 commit comments

Comments
 (0)