mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2026-05-11 03:12:15 +00:00
Start setting up user callbacks system
This commit is contained in:
parent
6dce8c2fc2
commit
0df06daf44
6 changed files with 76 additions and 36 deletions
|
|
@ -43,11 +43,6 @@ target_include_directories(ultramodern PRIVATE
|
||||||
"${PROJECT_SOURCE_DIR}/../rt64/src/contrib/nativefiledialog-extended/src/include"
|
"${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)
|
if (WIN32)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
# Fetch SDL2 on windows
|
# Fetch SDL2 on windows
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
29
ultramodern/include/ultramodern/user_callbacks.hpp
Normal file
29
ultramodern/include/ultramodern/user_callbacks.hpp
Normal file
|
|
@ -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
|
||||||
|
|
@ -15,11 +15,7 @@
|
||||||
#include "ultramodern.hpp"
|
#include "ultramodern.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "rt64_layer.h"
|
#include "rt64_layer.h"
|
||||||
#include "recomp_ui.h"
|
#include "user_callbacks.hpp"
|
||||||
#include "recomp.h"
|
|
||||||
#include "recomp_game.h"
|
|
||||||
#include "recomp_input.h"
|
|
||||||
#include "rsp.h"
|
|
||||||
|
|
||||||
struct SpTaskAction {
|
struct SpTaskAction {
|
||||||
OSTask task;
|
OSTask task;
|
||||||
|
|
@ -118,6 +114,7 @@ void vi_thread_func() {
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
int remaining_retraces = events_context.vi.retrace_count;
|
int remaining_retraces = events_context.vi.retrace_count;
|
||||||
|
auto& user_callbacks = ultramodern::get_user_callbacks();
|
||||||
|
|
||||||
while (!exited) {
|
while (!exited) {
|
||||||
// Determine the next VI time (more accurate than adding 16ms each VI interrupt)
|
// Determine the next VI time (more accurate than adding 16ms each VI interrupt)
|
||||||
|
|
@ -177,8 +174,9 @@ void vi_thread_func() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO move recomp code out of ultramodern.
|
if (user_callbacks.update_rumble != nullptr) {
|
||||||
recomp::update_rumble();
|
user_callbacks.update_rumble();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,9 +196,11 @@ uint8_t dmem[0x1000];
|
||||||
uint16_t rspReciprocals[512];
|
uint16_t rspReciprocals[512];
|
||||||
uint16_t rspInverseSquareRoots[512];
|
uint16_t rspInverseSquareRoots[512];
|
||||||
|
|
||||||
|
#if 0
|
||||||
using RspUcodeFunc = RspExitReason(uint8_t* rdram);
|
using RspUcodeFunc = RspExitReason(uint8_t* rdram);
|
||||||
extern RspUcodeFunc njpgdspMain;
|
extern RspUcodeFunc njpgdspMain;
|
||||||
extern RspUcodeFunc aspMain;
|
extern RspUcodeFunc aspMain;
|
||||||
|
#endif
|
||||||
|
|
||||||
// From Ares emulator. For license details, see rsp_vu.h
|
// From Ares emulator. For license details, see rsp_vu.h
|
||||||
void rsp_constants_init() {
|
void rsp_constants_init() {
|
||||||
|
|
@ -219,7 +219,7 @@ void rsp_constants_init() {
|
||||||
rspInverseSquareRoots[index] = u16(b >> 1);
|
rspInverseSquareRoots[index] = u16(b >> 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
// Runs a recompiled RSP microcode
|
// Runs a recompiled RSP microcode
|
||||||
void run_rsp_microcode(uint8_t* rdram, const OSTask* task, RspUcodeFunc* ucode_func) {
|
void run_rsp_microcode(uint8_t* rdram, const OSTask* task, RspUcodeFunc* ucode_func) {
|
||||||
// Load the OSTask into DMEM
|
// 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
|
// Ensure that the ucode exited correctly
|
||||||
assert(exit_reason == RspExitReason::Broke);
|
assert(exit_reason == RspExitReason::Broke);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready) {
|
void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready) {
|
||||||
ultramodern::set_native_thread_name("SP Task Thread");
|
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
|
// Run the correct function based on the task type
|
||||||
if (task->t.type == M_AUDTASK) {
|
if (task->t.type == M_AUDTASK) {
|
||||||
|
#if 0
|
||||||
run_rsp_microcode(rdram, task, aspMain);
|
run_rsp_microcode(rdram, task, aspMain);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (task->t.type == M_NJPEGTASK) {
|
else if (task->t.type == M_NJPEGTASK) {
|
||||||
|
#if 0
|
||||||
run_rsp_microcode(rdram, task, njpgdspMain);
|
run_rsp_microcode(rdram, task, njpgdspMain);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Unknown task type: %" PRIu32 "\n", task->t.type);
|
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};
|
ultramodern::RT64Context rt64{rdram, window_handle, cur_config.load().developer_mode};
|
||||||
|
|
||||||
|
auto& user_callbacks = ultramodern::get_user_callbacks();
|
||||||
|
|
||||||
if (!rt64.valid()) {
|
if (!rt64.valid()) {
|
||||||
// TODO move recomp code out of ultramodern.
|
// TODO move recomp code out of ultramodern.
|
||||||
rt64_setup_result.store(rt64.get_setup_result());
|
rt64_setup_result.store(rt64.get_setup_result());
|
||||||
|
|
@ -323,8 +329,9 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO move recomp code out of ultramodern.
|
if (user_callbacks.update_supported_options != nullptr) {
|
||||||
recomp::update_supported_options();
|
user_callbacks.update_supported_options();
|
||||||
|
}
|
||||||
|
|
||||||
rsp_constants_init();
|
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();
|
rt64.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -580,9 +589,18 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::WindowHandle window_handle)
|
||||||
ultramodern::RT64SetupResult setup_result = rt64_setup_result.load();
|
ultramodern::RT64SetupResult setup_result = rt64_setup_result.load();
|
||||||
if (rt64_setup_result != ultramodern::RT64SetupResult::Success) {
|
if (rt64_setup_result != ultramodern::RT64SetupResult::Success) {
|
||||||
auto show_rt64_error = [](const std::string& msg) {
|
auto show_rt64_error = [](const std::string& msg) {
|
||||||
// TODO move recomp code out of ultramodern (message boxes).
|
auto& user_callbacks = ultramodern::get_user_callbacks();
|
||||||
recomp::message_box(("An error has been encountered on startup: " + msg).c_str());
|
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.";
|
const std::string driver_os_suffix = "\nPlease make sure your GPU drivers and your OS are up to date.";
|
||||||
switch (rt64_setup_result) {
|
switch (rt64_setup_result) {
|
||||||
case ultramodern::RT64SetupResult::DynamicLibrariesNotFound:
|
case ultramodern::RT64SetupResult::DynamicLibrariesNotFound:
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "ultramodern.hpp"
|
#include "ultramodern.hpp"
|
||||||
#include "recomp.h"
|
|
||||||
|
|
||||||
struct QueuedMessage {
|
struct QueuedMessage {
|
||||||
PTR(OSMesgQueue) mq;
|
PTR(OSMesgQueue) mq;
|
||||||
|
|
|
||||||
11
ultramodern/src/user_callbacks.cpp
Normal file
11
ultramodern/src/user_callbacks.cpp
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue