From 0df06daf44239c4496538ff8c6ee3fcfd3694e73 Mon Sep 17 00:00:00 2001 From: Angie Date: Mon, 20 May 2024 23:39:11 -0400 Subject: [PATCH] Start setting up user callbacks system --- ultramodern/CMakeLists.txt | 5 -- ultramodern/include/ultramodern/recomp_ui.h | 12 ----- .../include/ultramodern/user_callbacks.hpp | 29 ++++++++++ ultramodern/src/events.cpp | 54 ++++++++++++------- ultramodern/src/mesgqueue.cpp | 1 - ultramodern/src/user_callbacks.cpp | 11 ++++ 6 files changed, 76 insertions(+), 36 deletions(-) delete mode 100644 ultramodern/include/ultramodern/recomp_ui.h create mode 100644 ultramodern/include/ultramodern/user_callbacks.hpp create mode 100644 ultramodern/src/user_callbacks.cpp diff --git a/ultramodern/CMakeLists.txt b/ultramodern/CMakeLists.txt index 1b62ca9..720b8cc 100644 --- a/ultramodern/CMakeLists.txt +++ b/ultramodern/CMakeLists.txt @@ -43,11 +43,6 @@ target_include_directories(ultramodern PRIVATE "${PROJECT_SOURCE_DIR}/../rt64/src/contrib/nativefiledialog-extended/src/include" ) -# TODO: remove when librecomp is untangled from ultramodern -target_include_directories(ultramodern PRIVATE - "${CMAKE_SOURCE_DIR}/librecomp/include" -) - if (WIN32) include(FetchContent) # Fetch SDL2 on windows diff --git a/ultramodern/include/ultramodern/recomp_ui.h b/ultramodern/include/ultramodern/recomp_ui.h deleted file mode 100644 index 7b511fc..0000000 --- a/ultramodern/include/ultramodern/recomp_ui.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ULTRAMODERN_RECOMP_UI__ -#define __ULTRAMODERN_RECOMP_UI__ - -namespace recomp { - // Currently those functions are expected to be provided by the consumer of this library. - // TODO: Change these functions to a callback registering system - - void destroy_ui(); - void update_supported_options(); -} - -#endif diff --git a/ultramodern/include/ultramodern/user_callbacks.hpp b/ultramodern/include/ultramodern/user_callbacks.hpp new file mode 100644 index 0000000..6c702b7 --- /dev/null +++ b/ultramodern/include/ultramodern/user_callbacks.hpp @@ -0,0 +1,29 @@ +#ifndef __USER_CALLBACKS_HPP__ +#define __USER_CALLBACKS_HPP__ + +namespace ultramodern { + struct UserCallbacks { + // TODO: Do we want those functions to take a generic `void *arg` for user data? + + // TODO: Consider renaming some functions to something more general, + // like `update_rumble` -> `update_controller` + + void (*update_rumble)(); + void (*update_supported_options)(); + + // TODO: Since we have a destroy_ui we could provide an init_ui? + // void (*init_ui)(); + void (*destroy_ui)(); + + /** + * Show an OS dialog with the given `msg`. + * `msg` is non-NULL. + */ + void (*message_box)(const char* msg); + }; + + void register_user_callbacks(UserCallbacks& callbacks); + const UserCallbacks& get_user_callbacks(); +}; + +#endif diff --git a/ultramodern/src/events.cpp b/ultramodern/src/events.cpp index 9af5568..5afd05b 100644 --- a/ultramodern/src/events.cpp +++ b/ultramodern/src/events.cpp @@ -15,11 +15,7 @@ #include "ultramodern.hpp" #include "config.hpp" #include "rt64_layer.h" -#include "recomp_ui.h" -#include "recomp.h" -#include "recomp_game.h" -#include "recomp_input.h" -#include "rsp.h" +#include "user_callbacks.hpp" struct SpTaskAction { OSTask task; @@ -116,8 +112,9 @@ void vi_thread_func() { // the game to generate new audio and gfx lists. ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Critical); using namespace std::chrono_literals; - + int remaining_retraces = events_context.vi.retrace_count; + auto& user_callbacks = ultramodern::get_user_callbacks(); while (!exited) { // Determine the next VI time (more accurate than adding 16ms each VI interrupt) @@ -176,9 +173,10 @@ void vi_thread_func() { } } } - - // TODO move recomp code out of ultramodern. - recomp::update_rumble(); + + if (user_callbacks.update_rumble != nullptr) { + user_callbacks.update_rumble(); + } } } @@ -198,9 +196,11 @@ uint8_t dmem[0x1000]; uint16_t rspReciprocals[512]; uint16_t rspInverseSquareRoots[512]; +#if 0 using RspUcodeFunc = RspExitReason(uint8_t* rdram); extern RspUcodeFunc njpgdspMain; extern RspUcodeFunc aspMain; +#endif // From Ares emulator. For license details, see rsp_vu.h void rsp_constants_init() { @@ -219,7 +219,7 @@ void rsp_constants_init() { rspInverseSquareRoots[index] = u16(b >> 1); } } - +#if 0 // Runs a recompiled RSP microcode void run_rsp_microcode(uint8_t* rdram, const OSTask* task, RspUcodeFunc* ucode_func) { // Load the OSTask into DMEM @@ -231,7 +231,7 @@ void run_rsp_microcode(uint8_t* rdram, const OSTask* task, RspUcodeFunc* ucode_f // Ensure that the ucode exited correctly assert(exit_reason == RspExitReason::Broke); } - +#endif void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready) { ultramodern::set_native_thread_name("SP Task Thread"); @@ -251,10 +251,14 @@ void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_r // Run the correct function based on the task type if (task->t.type == M_AUDTASK) { + #if 0 run_rsp_microcode(rdram, task, aspMain); + #endif } else if (task->t.type == M_NJPEGTASK) { + #if 0 run_rsp_microcode(rdram, task, njpgdspMain); + #endif } else { fprintf(stderr, "Unknown task type: %" PRIu32 "\n", task->t.type); @@ -315,6 +319,8 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re ultramodern::RT64Context rt64{rdram, window_handle, cur_config.load().developer_mode}; + auto& user_callbacks = ultramodern::get_user_callbacks(); + if (!rt64.valid()) { // TODO move recomp code out of ultramodern. rt64_setup_result.store(rt64.get_setup_result()); @@ -323,8 +329,9 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re return; } - // TODO move recomp code out of ultramodern. - recomp::update_supported_options(); + if (user_callbacks.update_supported_options != nullptr) { + user_callbacks.update_supported_options(); + } rsp_constants_init(); @@ -372,8 +379,10 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re } } } - // TODO move recomp code out of ultramodern. - recomp::destroy_ui(); + + if (user_callbacks.destroy_ui != nullptr) { + user_callbacks.destroy_ui(); + } rt64.shutdown(); } @@ -571,7 +580,7 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle) events_context.rdram = rdram; events_context.sp.gfx_thread = std::thread{ gfx_thread_func, rdram, &gfx_thread_ready, window_handle }; events_context.sp.task_thread = std::thread{ task_thread_func, rdram, &task_thread_ready }; - + // Wait for the two sp threads to be ready before continuing to prevent the game from // running before we're able to handle RSP tasks. gfx_thread_ready.wait(); @@ -580,9 +589,18 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle) ultramodern::RT64SetupResult setup_result = rt64_setup_result.load(); if (rt64_setup_result != ultramodern::RT64SetupResult::Success) { auto show_rt64_error = [](const std::string& msg) { - // TODO move recomp code out of ultramodern (message boxes). - recomp::message_box(("An error has been encountered on startup: " + msg).c_str()); + auto& user_callbacks = ultramodern::get_user_callbacks(); + std::string error_msg = "An error has been encountered on startup: " + msg; + + // We print the message to stderr since the user may not have provided a message_box callback + // TODO: is fprintf ok? or do we prefer using something more C++'ish? + fprintf(stderr, "%s\n", error_msg.c_str()); + + if (user_callbacks.message_box != nullptr) { + user_callbacks.message_box(error_msg.c_str()); + } }; + const std::string driver_os_suffix = "\nPlease make sure your GPU drivers and your OS are up to date."; switch (rt64_setup_result) { case ultramodern::RT64SetupResult::DynamicLibrariesNotFound: diff --git a/ultramodern/src/mesgqueue.cpp b/ultramodern/src/mesgqueue.cpp index b13a3c0..b792bcd 100644 --- a/ultramodern/src/mesgqueue.cpp +++ b/ultramodern/src/mesgqueue.cpp @@ -4,7 +4,6 @@ #include "ultra64.h" #include "ultramodern.hpp" -#include "recomp.h" struct QueuedMessage { PTR(OSMesgQueue) mq; diff --git a/ultramodern/src/user_callbacks.cpp b/ultramodern/src/user_callbacks.cpp new file mode 100644 index 0000000..677e012 --- /dev/null +++ b/ultramodern/src/user_callbacks.cpp @@ -0,0 +1,11 @@ +#include "ultramodern/user_callbacks.hpp" + +static ultramodern::UserCallbacks s_user_callbacks {}; + +void ultramodern::register_user_callbacks(UserCallbacks& callbacks) { + s_user_callbacks = callbacks; +} + +const ultramodern::UserCallbacks& ultramodern::get_user_callbacks() { + return s_user_callbacks; +}