From 192fb96efa2f36f27db8a66271b374abee0e8db2 Mon Sep 17 00:00:00 2001 From: Garrett Smith Date: Tue, 26 May 2026 21:35:34 -0700 Subject: [PATCH 1/3] expose is_entrypoint API (also rename main => entrypoint) (#147) --- ultramodern/include/ultramodern/ultramodern.hpp | 3 ++- ultramodern/src/threads.cpp | 12 ++++++++---- ultramodern/src/ultrainit.cpp | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ultramodern/include/ultramodern/ultramodern.hpp b/ultramodern/include/ultramodern/ultramodern.hpp index 57db6f6..46aea61 100644 --- a/ultramodern/include/ultramodern/ultramodern.hpp +++ b/ultramodern/include/ultramodern/ultramodern.hpp @@ -96,7 +96,8 @@ enum class ThreadPriority { void set_native_thread_name(const std::string& name); void set_native_thread_priority(ThreadPriority pri); PTR(OSThread) this_thread(); -void set_main_thread(); +void set_entrypoint_thread(); +bool is_entrypoint_thread(); bool is_game_thread(); void submit_rsp_task(RDRAM_ARG PTR(OSTask) task); void send_si_message(); diff --git a/ultramodern/src/threads.cpp b/ultramodern/src/threads.cpp index 812c556..6e3ed18 100644 --- a/ultramodern/src/threads.cpp +++ b/ultramodern/src/threads.cpp @@ -29,14 +29,18 @@ std::string ultramodern::threads::get_game_thread_name(const OSThread* t) { extern "C" void bootproc(); -thread_local bool is_main_thread = false; +thread_local bool is_entrypoint_thread = false; // Whether this thread is part of the game (i.e. the start thread or one spawned by osCreateThread) thread_local bool is_game_thread = false; thread_local PTR(OSThread) thread_self = NULLPTR; -void ultramodern::set_main_thread() { +void ultramodern::set_entrypoint_thread() { ::is_game_thread = true; - is_main_thread = true; + ::is_entrypoint_thread = true; +} + +bool ultramodern::is_entrypoint_thread() { + return ::is_entrypoint_thread; } bool ultramodern::is_game_thread() { @@ -45,7 +49,7 @@ bool ultramodern::is_game_thread() { #if 0 int main(int argc, char** argv) { - ultramodern::set_main_thread(); + ultramodern::set_entrypoint_thread(); bootproc(); } diff --git a/ultramodern/src/ultrainit.cpp b/ultramodern/src/ultrainit.cpp index ca1556c..af5132c 100644 --- a/ultramodern/src/ultrainit.cpp +++ b/ultramodern/src/ultrainit.cpp @@ -22,7 +22,7 @@ void ultramodern::set_callbacks( } void ultramodern::preinit(RDRAM_ARG ultramodern::renderer::WindowHandle window_handle) { - ultramodern::set_main_thread(); + ultramodern::set_entrypoint_thread(); ultramodern::init_events(PASS_RDRAM window_handle); ultramodern::init_timers(PASS_RDRAM1); ultramodern::init_audio(); From 8cd9d148173720f36f7fd75f05db13a12965df34 Mon Sep 17 00:00:00 2001 From: Garrett Smith Date: Tue, 26 May 2026 21:37:10 -0700 Subject: [PATCH 2/3] query by value to allow signed/unsigned conversion (#148) --- librecomp/src/mod_manifest.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/librecomp/src/mod_manifest.cpp b/librecomp/src/mod_manifest.cpp index a75d253..a96bf2a 100644 --- a/librecomp/src/mod_manifest.cpp +++ b/librecomp/src/mod_manifest.cpp @@ -466,22 +466,20 @@ recomp::mods::ModOpenError parse_manifest_config_schema_option(const nlohmann::j auto precision = config_schema_json.find(config_schema_precision_key); if (precision != config_schema_json.end()) { - int64_t precision_int64; - if (get_to(*precision, precision_int64)) { - option_number.precision = precision_int64; - } - else { + if (!precision->is_number()) { error_param = config_schema_precision_key; return recomp::mods::ModOpenError::IncorrectConfigSchemaType; } + option_number.precision = precision->template get(); } auto percent = config_schema_json.find(config_schema_percent_key); if (percent != config_schema_json.end()) { - if (!get_to(*percent, option_number.percent)) { + if (!percent->is_boolean()) { error_param = config_schema_percent_key; return recomp::mods::ModOpenError::IncorrectConfigSchemaType; } + option_number.percent = percent->template get(); } auto default_value = config_schema_json.find(config_schema_default_key); From ae1ffbb909d9f93c88c41830deb539f7feef5ed2 Mon Sep 17 00:00:00 2001 From: Garrett Smith Date: Tue, 26 May 2026 21:53:50 -0700 Subject: [PATCH 3/3] support args >= 4 via the stack in _arg template (#138) * support args >= 4 via the stack * fix offset --- librecomp/include/librecomp/helpers.hpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/librecomp/include/librecomp/helpers.hpp b/librecomp/include/librecomp/helpers.hpp index d8f5afd..eb9f86f 100644 --- a/librecomp/include/librecomp/helpers.hpp +++ b/librecomp/include/librecomp/helpers.hpp @@ -7,8 +7,7 @@ #include template -T _arg(uint8_t* rdram, recomp_context* ctx) { - static_assert(index < 4, "Only args 0 through 3 supported"); +T _arg(uint8_t* rdram, recomp_context* ctx) requires(index < 4) { gpr raw_arg = (&ctx->r4)[index]; if constexpr (std::is_same_v) { if constexpr (index < 2) { @@ -38,6 +37,25 @@ T _arg(uint8_t* rdram, recomp_context* ctx) { } } +template +T _arg(uint8_t* rdram, recomp_context* ctx) requires(index >= 4) { + const auto raw_arg = MEM_W(index * 4, ctx->r29); + if constexpr (std::is_pointer_v) { + static_assert (!std::is_pointer_v>, "Double pointers not supported"); + return TO_PTR(std::remove_pointer_t, raw_arg); + } + else if constexpr (std::is_integral_v) { + static_assert(sizeof(T) <= 4, "64-bit args not supported"); + return static_cast(raw_arg); + } + else { + // static_assert in else workaround + [] () { + static_assert(flag, "Unsupported type"); + }(); + } +} + inline float _arg_float_a1(uint8_t* rdram, recomp_context* ctx) { (void)rdram; union {