|
7 | 7 | #include <ultramodern/ultra64.h> |
8 | 8 |
|
9 | 9 | template<int index, typename T> |
10 | | -T _arg(uint8_t* rdram, recomp_context* ctx) { |
11 | | - static_assert(index < 4, "Only args 0 through 3 supported"); |
| 10 | +T _arg(uint8_t* rdram, recomp_context* ctx) requires(index < 4) { |
12 | 11 | gpr raw_arg = (&ctx->r4)[index]; |
13 | 12 | if constexpr (std::is_same_v<T, float>) { |
14 | 13 | if constexpr (index < 2) { |
@@ -38,6 +37,25 @@ T _arg(uint8_t* rdram, recomp_context* ctx) { |
38 | 37 | } |
39 | 38 | } |
40 | 39 |
|
| 40 | +template<int index, typename T> |
| 41 | +T _arg(uint8_t* rdram, recomp_context* ctx) requires(index >= 4) { |
| 42 | + const auto raw_arg = MEM_W(index * 4, ctx->r29); |
| 43 | + if constexpr (std::is_pointer_v<T>) { |
| 44 | + static_assert (!std::is_pointer_v<std::remove_pointer_t<T>>, "Double pointers not supported"); |
| 45 | + return TO_PTR(std::remove_pointer_t<T>, raw_arg); |
| 46 | + } |
| 47 | + else if constexpr (std::is_integral_v<T>) { |
| 48 | + static_assert(sizeof(T) <= 4, "64-bit args not supported"); |
| 49 | + return static_cast<T>(raw_arg); |
| 50 | + } |
| 51 | + else { |
| 52 | + // static_assert in else workaround |
| 53 | + [] <bool flag = false>() { |
| 54 | + static_assert(flag, "Unsupported type"); |
| 55 | + }(); |
| 56 | + } |
| 57 | +} |
| 58 | + |
41 | 59 | inline float _arg_float_a1(uint8_t* rdram, recomp_context* ctx) { |
42 | 60 | (void)rdram; |
43 | 61 | union { |
|
0 commit comments