Update codebase with changes for Zelda 64: Recompiled 1.2

This commit is contained in:
Mr-Wiseguy
2025-06-03 01:16:09 -04:00
parent 6a10095c88
commit 1e19dad587
71 changed files with 4913 additions and 674 deletions
+82 -18
View File
@@ -1,5 +1,10 @@
cmake_minimum_required(VERSION 3.20)
project(BanjoRecompiled)
if (APPLE)
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum OS X deployment version")
endif()
project(BanjoRecompiled LANGUAGES C CXX)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -16,6 +21,14 @@ if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR")
endif()
if (APPLE)
enable_language(OBJC OBJCXX)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
option(RECOMP_FLATPAK "Configure the build for Flatpak compatibility." OFF)
endif()
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
cmake_policy(SET CMP0135 NEW)
@@ -32,6 +45,10 @@ set(RT64_STATIC TRUE)
set(RT64_SDL_WINDOW_VULKAN TRUE)
add_compile_definitions(HLSL_CPU)
if (RECOMP_FLATPAK)
add_compile_definitions(RECOMP_FLATPAK)
endif()
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/rt64 ${CMAKE_BINARY_DIR}/rt64)
# set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
@@ -42,6 +59,7 @@ add_subdirectory(${CMAKE_SOURCE_DIR}/lib/lunasvg)
SET(RMLUI_SVG_PLUGIN ON CACHE BOOL "" FORCE)
SET(RMLUI_TESTS_ENABLED OFF CACHE BOOL "" FORCE)
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RmlUi)
target_compile_definitions(rmlui_core PRIVATE LUNASVG_BUILD_STATIC)
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime)
@@ -110,7 +128,7 @@ add_custom_target(PatchesBin
# Generate patches_bin.c from patches.bin
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches_bin.c
COMMAND file_to_c ${CMAKE_SOURCE_DIR}/patches/patches.bin bk_patches_bin ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches_bin.c ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches_bin.h
COMMAND file_to_c ${CMAKE_SOURCE_DIR}/patches/patches.bin bk_patches_bin ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches_bin.c ${CMAKE_SOURCE_DIR}/RecompiledPatches/patches_bin.h
DEPENDS ${CMAKE_SOURCE_DIR}/patches/patches.bin
)
@@ -126,22 +144,12 @@ add_custom_command(OUTPUT
DEPENDS ${CMAKE_SOURCE_DIR}/patches/patches.elf
)
# Download controller db file for controller support via SDL2
set(GAMECONTROLLERDB_COMMIT "b1e4090b3d4266e55feb0793efa35792e05faf66")
set(GAMECONTROLLERDB_URL "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/${GAMECONTROLLERDB_COMMIT}/gamecontrollerdb.txt")
file(DOWNLOAD ${GAMECONTROLLERDB_URL} ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt
TLS_VERIFY ON)
add_custom_target(DownloadGameControllerDB
DEPENDS ${CMAKE_SOURCE_DIR}/gamecontrollerdb.txt)
# Main executable
add_executable(BanjoRecompiled)
add_dependencies(BanjoRecompiled DownloadGameControllerDB)
set (SOURCES
${CMAKE_SOURCE_DIR}/src/main/main.cpp
${CMAKE_SOURCE_DIR}/src/main/support.cpp
${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp
${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp
${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp
@@ -151,20 +159,26 @@ set (SOURCES
${CMAKE_SOURCE_DIR}/src/game/config.cpp
${CMAKE_SOURCE_DIR}/src/game/debug.cpp
${CMAKE_SOURCE_DIR}/src/game/recomp_api.cpp
${CMAKE_SOURCE_DIR}/src/game/recomp_mem_api.cpp
${CMAKE_SOURCE_DIR}/src/game/recomp_actor_api.cpp
${CMAKE_SOURCE_DIR}/src/game/recomp_data_api.cpp
${CMAKE_SOURCE_DIR}/src/game/rom_decompression.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_renderer.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_state.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_launcher.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_config.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_prompt.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_config_sub_menu.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_details_panel.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_installer.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_api.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_api_events.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_api_images.cpp
${CMAKE_SOURCE_DIR}/src/ui/ui_utils.cpp
${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
${CMAKE_SOURCE_DIR}/src/ui/core/ui_context.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_button.cpp
@@ -176,6 +190,7 @@ set (SOURCES
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_radio.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_scroll_container.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_slider.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_span.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_text_input.cpp
${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp
@@ -185,6 +200,10 @@ set (SOURCES
${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp
)
if (APPLE)
list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/src/main/support_apple.mm)
endif()
target_include_directories(BanjoRecompiled PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/N64Recomp/include
@@ -221,6 +240,12 @@ endif()
if (MSVC)
# Disable identical code folding, since this breaks mod function patching as multiple functions can get merged into one.
target_link_options(BanjoRecompiled PRIVATE /OPT:NOICF)
elseif (APPLE)
# Use a wrapper around ld64 that respects segprot's `max_prot` value in order
# to make our executable memory writable (required for mod function patching)
target_link_options(BanjoRecompiled PRIVATE
"-fuse-ld=${CMAKE_SOURCE_DIR}/.github/macos/ld64"
)
endif()
if (WIN32)
@@ -263,6 +288,20 @@ if (WIN32)
)
# target_sources(BanjoRecompiled PRIVATE ${CMAKE_SOURCE_DIR}/icons/app.rc)
target_link_libraries(BanjoRecompiled PRIVATE SDL2)
endif()
if (APPLE)
find_package(SDL2 REQUIRED)
target_include_directories(BanjoRecompiled PRIVATE ${SDL2_INCLUDE_DIRS})
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
target_link_libraries(BanjoRecompiled PRIVATE ${CMAKE_DL_LIBS} Threads::Threads SDL2::SDL2)
include(${CMAKE_SOURCE_DIR}/.github/macos/apple_bundle.cmake)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -273,7 +312,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
# Generate icon_bytes.c from the app icon PNG.
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
DEPENDS ${CMAKE_SOURCE_DIR}/icons/512.png
)
target_sources(BanjoRecompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c)
@@ -298,7 +337,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
message(STATUS "FREETYPE_LIBRARIES = ${FREETYPE_LIBRARIES}")
include_directories(${FREETYPE_LIBRARIES})
target_link_libraries(BanjoRecompiled PRIVATE ${FREETYPE_LIBRARIES})
target_link_libraries(BanjoRecompiled PRIVATE ${FREETYPE_LIBRARIES} SDL2::SDL2)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
@@ -310,7 +349,6 @@ endif()
target_link_libraries(BanjoRecompiled PRIVATE
PatchesLib
RecompiledFuncs
SDL2
librecomp
ultramodern
rt64
@@ -338,9 +376,14 @@ else()
if (APPLE)
# Apple's binary is universal, so it'll work on both x86_64 and arm64
set (DXC "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/arm64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/arm64/dxc-macos")
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
set(SPIRVCROSS "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/spirv-cross/lib/x64" "${PROJECT_SOURCE_DIR}/lib/rt64//src/contrib/spirv-cross/bin/x64/spirv-cross")
else()
set(SPIRVCROSS "DYLD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/spirv-cross/lib/arm64" "${PROJECT_SOURCE_DIR}/lib/rt64//src/contrib/spirv-cross/bin/x64/spirv-cross")
endif()
else()
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
set (DXC "LD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/x64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/x64/dxc")
set (DXC "LD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/x64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/x64/dxc-linux")
else()
set (DXC "LD_LIBRARY_PATH=${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/lib/arm64" "${PROJECT_SOURCE_DIR}/lib/rt64/src/contrib/dxc/bin/arm64/dxc-linux")
endif()
@@ -350,6 +393,27 @@ endif()
build_vertex_shader(BanjoRecompiled "shaders/InterfaceVS.hlsl" "shaders/InterfaceVS.hlsl")
build_pixel_shader(BanjoRecompiled "shaders/InterfacePS.hlsl" "shaders/InterfacePS.hlsl")
# Embed all .nrm files in the "mods" directory
file(GLOB NRM_FILES "${CMAKE_SOURCE_DIR}/mods/*.nrm")
set(GENERATED_NRM_SOURCES "")
foreach(NRM_FILE ${NRM_FILES})
get_filename_component(NRM_NAME ${NRM_FILE} NAME_WE)
set(OUT_C "${CMAKE_CURRENT_BINARY_DIR}/mods/${NRM_NAME}.c")
set(OUT_H "${CMAKE_CURRENT_BINARY_DIR}/mods/${NRM_NAME}.h")
add_custom_command(
OUTPUT ${OUT_C} ${OUT_H}
COMMAND file_to_c ${NRM_FILE} ${NRM_NAME} ${OUT_C} ${OUT_H}
DEPENDS ${NRM_FILE}
)
list(APPEND GENERATED_NRM_SOURCES ${OUT_C})
endforeach()
target_sources(BanjoRecompiled PRIVATE ${GENERATED_NRM_SOURCES})
target_sources(BanjoRecompiled PRIVATE ${SOURCES})
set_property(TARGET BanjoRecompiled PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
+15 -3
View File
@@ -14,6 +14,8 @@ namespace RT64 {
namespace banjo {
namespace renderer {
inline const std::string special_option_texture_pack_enabled = "_recomp_texture_pack_enabled";
class RT64Context final : public ultramodern::renderer::RendererContext {
public:
~RT64Context() override;
@@ -30,9 +32,12 @@ namespace banjo {
uint32_t get_display_framerate() const override;
float get_resolution_scale() const override;
protected:
private:
std::unique_ptr<RT64::Application> app;
std::unordered_set<std::filesystem::path> enabled_texture_packs;
std::unordered_set<std::string> enabled_texture_packs;
std::unordered_set<std::string> secondary_disabled_texture_packs;
void check_texture_pack_actions();
};
std::unique_ptr<ultramodern::renderer::RendererContext> create_render_context(uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode);
@@ -41,8 +46,15 @@ namespace banjo {
bool RT64SamplePositionsSupported();
bool RT64HighPrecisionFBEnabled();
void enable_texture_pack(const recomp::mods::ModHandle& mod);
void trigger_texture_pack_update();
void enable_texture_pack(const recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod);
void disable_texture_pack(const recomp::mods::ModHandle& mod);
void secondary_enable_texture_pack(const std::string& mod_id);
void secondary_disable_texture_pack(const std::string& mod_id);
// Texture pack enable option. Must be an enum with two options.
// The first option is treated as disabled and the second option is treated as enabled.
bool is_texture_pack_enable_config_option(const recomp::mods::ConfigOption& option, bool show_errors);
}
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef __BANJO_SUPPORT_H__
#define __BANJO_SUPPORT_H__
#include <functional>
#include <filesystem>
#include <vector>
#include <optional>
#include <list>
namespace banjo {
std::filesystem::path get_program_path();
std::filesystem::path get_asset_path(const char* asset);
void open_file_dialog(std::function<void(bool success, const std::filesystem::path& path)> callback);
void open_file_dialog_multiple(std::function<void(bool success, const std::list<std::filesystem::path>& paths)> callback);
void show_error_message_box(const char *title, const char *message);
// Apple specific methods that usually require Objective-C. Implemented in support_apple.mm.
#ifdef __APPLE__
void dispatch_on_ui_thread(std::function<void()> func);
std::optional<std::filesystem::path> get_application_support_directory();
std::filesystem::path get_bundle_resource_directory();
std::filesystem::path get_bundle_directory();
#endif
}
#endif
+10
View File
@@ -0,0 +1,10 @@
#ifndef __OVERLOADED_H__
#define __OVERLOADED_H__
// Helper for std::visit
template<class... Ts>
struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;
#endif
+3 -1
View File
@@ -1,9 +1,11 @@
#ifndef __RECOMP_DATA_H__
#define __RECOMP_DATA_H__
namespace recomp {
namespace recomputil {
void init_extended_actor_data();
void reset_actor_data();
void register_data_api_exports();
}
#endif
+45 -15
View File
@@ -4,6 +4,7 @@
#include <memory>
#include <string>
#include <string_view>
#include <list>
// TODO move this file into src/ui
@@ -29,7 +30,7 @@ namespace recompui {
class MenuController {
public:
virtual ~MenuController() {}
virtual Rml::ElementDocument* load_document(Rml::Context* context) = 0;
virtual void load_document() = 0;
virtual void register_events(UiEventListenerInstancer& listener) = 0;
virtual void make_bindings(Rml::Context* context) = 0;
};
@@ -49,13 +50,14 @@ namespace recompui {
void hide_context(ContextId context);
void hide_all_contexts();
bool is_context_shown(ContextId context);
bool is_context_taking_input();
bool is_context_capturing_input();
bool is_context_capturing_mouse();
bool is_any_context_shown();
ContextId try_close_current_context();
ContextId get_launcher_context_id();
ContextId get_config_context_id();
ContextId get_config_sub_menu_context_id();
ContextId get_close_prompt_context_id();
enum class ConfigTab {
General,
@@ -67,6 +69,11 @@ namespace recompui {
};
void set_config_tab(ConfigTab tab);
int config_tab_to_index(ConfigTab tab);
Rml::ElementTabSet* get_config_tabset();
Rml::Element* get_mod_tab();
void set_config_tabset_mod_nav();
void focus_mod_configure_button();
enum class ButtonVariant {
Primary,
@@ -78,19 +85,37 @@ namespace recompui {
NumVariants,
};
void open_prompt(
const std::string& headerText,
const std::string& contentText,
const std::string& confirmLabelText,
const std::string& cancelLabelText,
std::function<void()> confirmCb,
std::function<void()> cancelCb,
ButtonVariant _confirmVariant = ButtonVariant::Success,
ButtonVariant _cancelVariant = ButtonVariant::Error,
bool _focusOnCancel = true,
const std::string& _returnElementId = ""
void init_styling(const std::filesystem::path& rcss_file);
void init_prompt_context();
void open_choice_prompt(
const std::string& header_text,
const std::string& content_text,
const std::string& confirm_label_text,
const std::string& cancel_label_text,
std::function<void()> confirm_action,
std::function<void()> cancel_action,
ButtonVariant confirm_variant = ButtonVariant::Success,
ButtonVariant cancel_variant = ButtonVariant::Error,
bool focus_on_cancel = true,
const std::string& return_element_id = ""
);
void open_info_prompt(
const std::string& header_text,
const std::string& content_text,
const std::string& okay_label_text,
std::function<void()> okay_action,
ButtonVariant okay_variant = ButtonVariant::Error,
const std::string& return_element_id = ""
);
void open_notification(
const std::string& header_text,
const std::string& content_text,
const std::string& return_element_id = ""
);
void close_prompt();
bool is_prompt_open();
void update_mod_list(bool scan_mods = true);
void process_game_started();
void apply_color_hack();
void get_window_size(int& width, int& height);
@@ -109,8 +134,13 @@ namespace recompui {
Rml::ElementPtr create_custom_element(Rml::Element* parent, std::string tag);
Rml::ElementDocument* load_document(const std::filesystem::path& path);
Rml::ElementDocument* create_empty_document();
void queue_image_from_bytes(const std::string &src, const std::vector<char> &bytes);
Rml::Element* get_child_by_tag(Rml::Element* parent, const std::string& tag);
void queue_image_from_bytes_rgba32(const std::string &src, const std::vector<char> &bytes, uint32_t width, uint32_t height);
void queue_image_from_bytes_file(const std::string &src, const std::vector<char> &bytes);
void release_image(const std::string &src);
void drop_files(const std::list<std::filesystem::path> &file_list);
}
#endif
+14
View File
@@ -0,0 +1,14 @@
#ifndef __MEM_FUNCS_H__
#define __MEM_FUNCS_H__
#include "patch_helpers.h"
DECLARE_FUNC(u32, recomp_register_actor_extension, u32 actor_type, u32 size);
DECLARE_FUNC(u32, recomp_register_actor_extension_generic, u32 size);
DECLARE_FUNC(void, recomp_clear_all_actor_data);
DECLARE_FUNC(u32, recomp_create_actor_data, u32 actor_type);
DECLARE_FUNC(void, recomp_destroy_actor_data, u32 actor_handle);
DECLARE_FUNC(void*, recomp_get_actor_data, u32 actor_handle, u32 extension_handle, u32 actor_type);
DECLARE_FUNC(u32, recomp_get_actor_spawn_index, u32 actor_handle);
#endif
-55
View File
@@ -1,60 +1,5 @@
#include "patches.h"
typedef struct Cube_s Cube;
RECOMP_PATCH bool viewport_cube_isInFrustum(Cube *cube) {
// f32 sp24[3];
// f32 sp18[3];
// sp24[0] = (f32) ((cube->x * 1000) - 150);
// sp24[1] = (f32) ((cube->y * 1000) - 150);
// sp24[2] = (f32) ((cube->z * 1000) - 150);
// sp18[0] = sp24[0] + 1300.0f;
// sp18[1] = sp24[1] + 1300.0f;
// sp18[2] = sp24[2] + 1300.0f;
// return func_8024D374(sp24, sp18);
return TRUE;
}
RECOMP_PATCH bool viewport_cube_isInFrustum2(Cube *cube) {
// f32 sp34[3];
// f32 sp28[3];
// f32 sp1C[3];
// if (cube->x == -0x10) {
// return TRUE;
// }
// sp1C[0] = (f32) ((cube->x * 1000) + 500) - viewportPosition[0];
// sp1C[1] = (f32) ((cube->y * 1000) + 500) - viewportPosition[1];
// sp1C[2] = (f32) ((cube->z * 1000) + 500) - viewportPosition[2];
// if (LENGTH_SQ_VEC3F(sp1C) > 1.6e7f) {
// return FALSE;
// }
// sp34[0] = (f32) ((cube->x * 1000) - 150);
// sp34[1] = (f32) ((cube->y * 1000) - 150);
// sp34[2] = (f32) ((cube->z * 1000) - 150);
// sp28[0] = sp34[0] + 1300.0f;
// sp28[1] = sp34[1] + 1300.0f;
// sp28[2] = sp34[2] + 1300.0f;
// return func_8024D374(sp34, sp28);
return TRUE;
}
RECOMP_PATCH bool viewport_func_8024DB50(f32 arg0[3], f32 arg1) {
// f32 sp3C[3];
// s32 i;
// sp3C[0] = arg0[0] - viewportPosition[0];
// sp3C[1] = arg0[1] - viewportPosition[1];
// sp3C[2] = arg0[2] - viewportPosition[2];
// for(i = 0; i < 4; i++){
// if(arg1 <= ml_dotProduct_vec3f(sp3C, D_80280ED0[i])){
// return FALSE;
// }
// }
return TRUE;
}
RECOMP_PATCH bool viewport_isBoundingBoxInFrustum(f32 arg0[3], f32 arg1[3]) {
return TRUE;
}
-1
View File
@@ -19,7 +19,6 @@ extern RecompAimingOverideMode recomp_aiming_override_mode;
DECLARE_FUNC(void, recomp_get_gyro_deltas, float* x, float* y);
DECLARE_FUNC(void, recomp_get_mouse_deltas, float* x, float* y);
DECLARE_FUNC(s32, recomp_get_targeting_mode);
DECLARE_FUNC(void, recomp_get_inverted_axes, s32* x, s32* y);
DECLARE_FUNC(s32, recomp_get_analog_cam_enabled);
DECLARE_FUNC(void, recomp_get_analog_inverted_axes, s32* x, s32* y);
+52
View File
@@ -0,0 +1,52 @@
#ifndef __UI_FUNCS_H__
#define __UI_FUNCS_H__
// These two enums must be kept in sync with src/ui/elements/ui_types.h!
typedef enum {
UI_EVENT_NONE,
UI_EVENT_CLICK,
UI_EVENT_FOCUS,
UI_EVENT_HOVER,
UI_EVENT_ENABLE,
UI_EVENT_DRAG,
UI_EVENT_RESERVED1, // Would be UI_EVENT_TEXT but text events aren't usable in mods currently
UI_EVENT_UPDATE,
UI_EVENT_COUNT
} RecompuiEventType;
typedef enum {
UI_DRAG_NONE,
UI_DRAG_START,
UI_DRAG_MOVE,
UI_DRAG_END
} RecompuiDragPhase;
typedef struct {
RecompuiEventType type;
union {
struct {
float x;
float y;
} click;
struct {
bool active;
} focus;
struct {
bool active;
} hover;
struct {
bool active;
} enable;
struct {
float x;
float y;
RecompuiDragPhase phase;
} drag;
} data;
} RecompuiEventData;
#endif
+6
View File
@@ -0,0 +1,6 @@
#ifndef __TRANSFORM_IDS_H__
#define __TRANSFORM_IDS_H__
#endif
+3
View File
@@ -0,0 +1,3 @@
#include "patches.h"
#include "transform_ids.h"
+9
View File
@@ -0,0 +1,9 @@
#ifndef __UI_FUNCS_INTERNAL_H__
#define __UI_FUNCS_INTERNAL_H__
#include "patch_helpers.h"
#include "recompui_event_structs.h"
DECLARE_FUNC(void, recomp_run_ui_callbacks);
#endif
+30 -8
View File
@@ -2,6 +2,7 @@
#include "recomp_input.h"
#include "banjo_sound.h"
#include "banjo_render.h"
#include "banjo_support.h"
#include "ultramodern/config.hpp"
#include "librecomp/files.hpp"
#include <filesystem>
@@ -13,6 +14,8 @@
#elif defined(__linux__)
#include <unistd.h>
#include <pwd.h>
#elif defined(__APPLE__)
#include "apple/rt64_apple.h"
#endif
constexpr std::u8string_view general_filename = u8"general.json";
@@ -71,7 +74,7 @@ T from_or_default(const json& j, const std::string& key, T default_value) {
else {
ret = default_value;
}
return ret;
}
@@ -129,11 +132,19 @@ namespace recomp {
}
std::filesystem::path banjo::get_app_folder_path() {
// directly check for portable.txt (windows and native linux binary)
// directly check for portable.txt (windows and native linux binary)
if (std::filesystem::exists("portable.txt")) {
return std::filesystem::current_path();
}
#if defined(__APPLE__)
// Check for portable file in the directory containing the app bundle.
const auto app_bundle_path = banjo::get_bundle_directory().parent_path();
if (std::filesystem::exists(app_bundle_path / "portable.txt")) {
return app_bundle_path;
}
#endif
std::filesystem::path recomp_dir{};
#if defined(_WIN32)
@@ -145,16 +156,27 @@ std::filesystem::path banjo::get_app_folder_path() {
}
CoTaskMemFree(known_path);
#elif defined(__linux__)
// check for APP_FOLDER_PATH env var used by AppImage
#elif defined(__linux__) || defined(__APPLE__)
// check for APP_FOLDER_PATH env var
if (getenv("APP_FOLDER_PATH") != nullptr) {
return std::filesystem::path{getenv("APP_FOLDER_PATH")};
}
#if defined(__APPLE__)
const auto supportdir = banjo::get_application_support_directory();
if (supportdir) {
return *supportdir / banjo::program_id;
}
#endif
const char *homedir;
if ((homedir = getenv("HOME")) == nullptr) {
#if defined(__linux__)
homedir = getpwuid(getuid())->pw_dir;
#elif defined(__APPLE__)
homedir = GetHomeDirectory();
#endif
}
if (homedir != nullptr) {
@@ -206,7 +228,7 @@ bool save_json_with_backups(const std::filesystem::path& path, const nlohmann::j
return recomp::finalize_output_file_with_backup(path);
}
bool save_general_config(const std::filesystem::path& path) {
bool save_general_config(const std::filesystem::path& path) {
nlohmann::json config_json{};
recomp::to_json(config_json["background_input_mode"], recomp::get_background_input_mode());
@@ -218,7 +240,7 @@ bool save_general_config(const std::filesystem::path& path) {
config_json["analog_cam_mode"] = banjo::get_analog_cam_mode();
config_json["analog_camera_invert_mode"] = banjo::get_analog_camera_invert_mode();
config_json["debug_mode"] = banjo::get_debug_mode_enabled();
return save_json_with_backups(path, config_json);
}
@@ -433,7 +455,7 @@ bool save_sound_config(const std::filesystem::path& path) {
config_json["main_volume"] = banjo::get_main_volume();
config_json["bgm_volume"] = banjo::get_bgm_volume();
return save_json_with_backups(path, config_json);
}
@@ -494,7 +516,7 @@ void banjo::save_config() {
}
std::filesystem::create_directories(recomp_dir);
// TODO error handling for failing to save config files.
save_general_config(recomp_dir / general_filename);
+129 -102
View File
@@ -31,7 +31,7 @@ static struct {
std::mutex cur_controllers_mutex;
std::vector<SDL_GameController*> cur_controllers{};
std::unordered_map<SDL_JoystickID, ControllerState> controller_states;
std::array<float, 2> rotation_delta{};
std::array<float, 2> mouse_delta{};
std::mutex pending_input_mutex;
@@ -42,6 +42,10 @@ static struct {
bool rumble_active;
} InputState;
static struct {
std::list<std::filesystem::path> files_dropped;
} DropState;
std::atomic<recomp::InputDevice> scanning_device = recomp::InputDevice::COUNT;
std::atomic<recomp::InputField> scanned_input;
@@ -93,85 +97,82 @@ bool should_override_keystate(SDL_Scancode key, SDL_Keymod mod) {
}
}
return false;
return false;
}
bool sdl_event_filter(void* userdata, SDL_Event* event) {
switch (event->type) {
case SDL_EventType::SDL_KEYDOWN:
{
SDL_KeyboardEvent* keyevent = &event->key;
{
SDL_KeyboardEvent* keyevent = &event->key;
// Skip repeated events when not in the menu
if (!recompui::is_context_taking_input() &&
event->key.repeat) {
break;
}
// Skip repeated events when not in the menu
if (!recompui::is_context_capturing_input() &&
event->key.repeat) {
break;
}
if ((keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_RETURN && (keyevent->keysym.mod & SDL_Keymod::KMOD_ALT)) ||
keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_F11
if ((keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_RETURN && (keyevent->keysym.mod & SDL_Keymod::KMOD_ALT)) ||
keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_F11
) {
recompui::toggle_fullscreen();
recompui::toggle_fullscreen();
}
if (scanning_device != recomp::InputDevice::COUNT) {
if (keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_ESCAPE) {
recomp::cancel_scanning_input();
}
if (scanning_device != recomp::InputDevice::COUNT) {
if (keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_ESCAPE) {
recomp::cancel_scanning_input();
} else if (scanning_device == recomp::InputDevice::Keyboard) {
set_scanned_input({(uint32_t)InputType::Keyboard, keyevent->keysym.scancode});
}
} else {
if (!should_override_keystate(keyevent->keysym.scancode, static_cast<SDL_Keymod>(keyevent->keysym.mod))) {
queue_if_enabled(event);
}
else if (scanning_device == recomp::InputDevice::Keyboard) {
set_scanned_input({ (uint32_t)InputType::Keyboard, keyevent->keysym.scancode });
}
}
break;
else {
if (!should_override_keystate(keyevent->keysym.scancode, static_cast<SDL_Keymod>(keyevent->keysym.mod))) {
queue_if_enabled(event);
}
}
}
break;
case SDL_EventType::SDL_CONTROLLERDEVICEADDED:
{
SDL_ControllerDeviceEvent* controller_event = &event->cdevice;
SDL_GameController* controller = SDL_GameControllerOpen(controller_event->which);
printf("Controller added: %d\n", controller_event->which);
if (controller != nullptr) {
printf(" Instance ID: %d\n", SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller)));
ControllerState& state = InputState.controller_states[SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))];
state.controller = controller;
{
SDL_ControllerDeviceEvent* controller_event = &event->cdevice;
SDL_GameController* controller = SDL_GameControllerOpen(controller_event->which);
printf("Controller added: %d\n", controller_event->which);
if (controller != nullptr) {
printf(" Instance ID: %d\n", SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller)));
ControllerState& state = InputState.controller_states[SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))];
state.controller = controller;
if (SDL_GameControllerHasSensor(controller, SDL_SensorType::SDL_SENSOR_GYRO) && SDL_GameControllerHasSensor(controller, SDL_SensorType::SDL_SENSOR_ACCEL)) {
SDL_GameControllerSetSensorEnabled(controller, SDL_SensorType::SDL_SENSOR_GYRO, SDL_TRUE);
SDL_GameControllerSetSensorEnabled(controller, SDL_SensorType::SDL_SENSOR_ACCEL, SDL_TRUE);
}
if (SDL_GameControllerHasSensor(controller, SDL_SensorType::SDL_SENSOR_GYRO) && SDL_GameControllerHasSensor(controller, SDL_SensorType::SDL_SENSOR_ACCEL)) {
SDL_GameControllerSetSensorEnabled(controller, SDL_SensorType::SDL_SENSOR_GYRO, SDL_TRUE);
SDL_GameControllerSetSensorEnabled(controller, SDL_SensorType::SDL_SENSOR_ACCEL, SDL_TRUE);
}
}
break;
}
break;
case SDL_EventType::SDL_CONTROLLERDEVICEREMOVED:
{
SDL_ControllerDeviceEvent* controller_event = &event->cdevice;
printf("Controller removed: %d\n", controller_event->which);
InputState.controller_states.erase(controller_event->which);
}
break;
{
SDL_ControllerDeviceEvent* controller_event = &event->cdevice;
printf("Controller removed: %d\n", controller_event->which);
InputState.controller_states.erase(controller_event->which);
}
break;
case SDL_EventType::SDL_QUIT: {
if (!ultramodern::is_game_started()) {
ultramodern::quit();
return true;
}
recompui::ContextId config_context_id = recompui::get_config_context_id();
if (!recompui::is_context_shown(config_context_id)) {
recompui::show_context(config_context_id, "");
}
banjo::open_quit_game_prompt();
recompui::activate_mouse();
break;
}
case SDL_EventType::SDL_MOUSEWHEEL:
{
SDL_MouseWheelEvent* wheel_event = &event->wheel;
InputState.mouse_wheel_pos.fetch_add(wheel_event->y * (wheel_event->direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1));
}
queue_if_enabled(event);
break;
{
SDL_MouseWheelEvent* wheel_event = &event->wheel;
InputState.mouse_wheel_pos.fetch_add(wheel_event->y * (wheel_event->direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1));
}
queue_if_enabled(event);
break;
case SDL_EventType::SDL_CONTROLLERBUTTONDOWN:
if (scanning_device != recomp::InputDevice::COUNT) {
auto menuToggleBinding0 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 0, recomp::InputDevice::Controller);
@@ -180,22 +181,24 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
if ((menuToggleBinding0.input_type != 0 && event->cbutton.button == menuToggleBinding0.input_id) ||
(menuToggleBinding1.input_type != 0 && event->cbutton.button == menuToggleBinding1.input_id)) {
recomp::cancel_scanning_input();
} else if (scanning_device == recomp::InputDevice::Controller) {
}
else if (scanning_device == recomp::InputDevice::Controller) {
SDL_ControllerButtonEvent* button_event = &event->cbutton;
auto scanned_input_index = recomp::get_scanned_input_index();
if ((scanned_input_index == static_cast<int>(recomp::GameInput::TOGGLE_MENU) ||
scanned_input_index == static_cast<int>(recomp::GameInput::ACCEPT_MENU) ||
scanned_input_index == static_cast<int>(recomp::GameInput::APPLY_MENU)) && (
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP ||
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN ||
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT ||
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
scanned_input_index == static_cast<int>(recomp::GameInput::ACCEPT_MENU) ||
scanned_input_index == static_cast<int>(recomp::GameInput::APPLY_MENU)) && (
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP ||
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN ||
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT ||
button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
break;
}
set_scanned_input({(uint32_t)InputType::ControllerDigital, button_event->button});
set_scanned_input({ (uint32_t)InputType::ControllerDigital, button_event->button });
}
} else {
}
else {
queue_if_enabled(event);
}
break;
@@ -217,8 +220,8 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
set_stick_return_event.user.data1 = nullptr;
set_stick_return_event.user.data2 = nullptr;
recompui::queue_event(set_stick_return_event);
set_scanned_input({(uint32_t)InputType::ControllerAnalog, axis_event->axis + 1});
set_scanned_input({ (uint32_t)InputType::ControllerAnalog, axis_event->axis + 1 });
}
else if (axis_value < -axis_threshold) {
SDL_Event set_stick_return_event;
@@ -228,9 +231,10 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
set_stick_return_event.user.data2 = nullptr;
recompui::queue_event(set_stick_return_event);
set_scanned_input({(uint32_t)InputType::ControllerAnalog, -axis_event->axis - 1});
set_scanned_input({ (uint32_t)InputType::ControllerAnalog, -axis_event->axis - 1 });
}
} else {
}
else {
queue_if_enabled(event);
}
break;
@@ -276,6 +280,22 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
InputState.pending_mouse_delta[0] += motion_event->xrel;
InputState.pending_mouse_delta[1] += motion_event->yrel;
}
queue_if_enabled(event);
break;
case SDL_EventType::SDL_DROPBEGIN:
DropState.files_dropped.clear();
break;
case SDL_EventType::SDL_DROPFILE:
DropState.files_dropped.emplace_back(std::filesystem::path(std::u8string_view((const char8_t*)(event->drop.file))));
SDL_free(event->drop.file);
break;
case SDL_EventType::SDL_DROPCOMPLETE:
recompui::drop_files(DropState.files_dropped);
break;
case SDL_EventType::SDL_CONTROLLERBUTTONUP:
// Always queue button up events to avoid missing them during binding.
recompui::queue_event(*event);
break;
default:
queue_if_enabled(event);
break;
@@ -285,6 +305,7 @@ bool sdl_event_filter(void* userdata, SDL_Event* event) {
void recomp::handle_events() {
SDL_Event cur_event;
static bool started = false;
static bool exited = false;
while (SDL_PollEvent(&cur_event) && !exited) {
exited = sdl_event_filter(nullptr, &cur_event);
@@ -301,6 +322,11 @@ void recomp::handle_events() {
SDL_ShowCursor(cursor_visible ? SDL_ENABLE : SDL_DISABLE);
SDL_SetRelativeMouseMode(cursor_locked ? SDL_TRUE : SDL_FALSE);
}
if (!started && ultramodern::is_game_started()) {
started = true;
recompui::process_game_started();
}
}
constexpr SDL_GameControllerButton SDL_CONTROLLER_BUTTON_SOUTH = SDL_CONTROLLER_BUTTON_A;
@@ -465,7 +491,7 @@ void recomp::poll_inputs() {
// Read the deltas while resetting them to zero.
{
std::lock_guard lock{ InputState.pending_input_mutex };
InputState.rotation_delta = InputState.pending_rotation_delta;
InputState.pending_rotation_delta = { 0.0f, 0.0f };
@@ -482,14 +508,14 @@ void recomp::set_rumble(int controller_num, bool on) {
ultramodern::input::connected_device_info_t recomp::get_connected_device_info(int controller_num) {
switch (controller_num) {
case 0:
return ultramodern::input::connected_device_info_t {
.connected_device = ultramodern::input::Device::Controller,
.connected_pak = ultramodern::input::Pak::RumblePak,
};
case 0:
return ultramodern::input::connected_device_info_t{
.connected_device = ultramodern::input::Device::Controller,
.connected_pak = ultramodern::input::Pak::RumblePak,
};
}
return ultramodern::input::connected_device_info_t {
return ultramodern::input::connected_device_info_t{
.connected_device = ultramodern::input::Device::None,
.connected_pak = ultramodern::input::Pak::None,
};
@@ -506,7 +532,8 @@ void recomp::update_rumble() {
if (InputState.rumble_active) {
InputState.cur_rumble += 0.17f;
if (InputState.cur_rumble > 1) InputState.cur_rumble = 1;
} else {
}
else {
InputState.cur_rumble *= 0.92f;
InputState.cur_rumble -= 0.01f;
if (InputState.cur_rumble < 0) InputState.cur_rumble = 0;
@@ -647,13 +674,13 @@ void recomp::get_mouse_deltas(float* x, float* y) {
void recomp::apply_joystick_deadzone(float x_in, float y_in, float* x_out, float* y_out) {
float joystick_deadzone = (float)recomp::get_joystick_deadzone() / 100.0f;
if(fabsf(x_in) < joystick_deadzone) {
if (fabsf(x_in) < joystick_deadzone) {
x_in = 0.0f;
}
else {
if(x_in > 0.0f) {
if (x_in > 0.0f) {
x_in -= joystick_deadzone;
}
}
else {
x_in += joystick_deadzone;
}
@@ -661,13 +688,13 @@ void recomp::apply_joystick_deadzone(float x_in, float y_in, float* x_out, float
x_in /= (1.0f - joystick_deadzone);
}
if(fabsf(y_in) < joystick_deadzone) {
if (fabsf(y_in) < joystick_deadzone) {
y_in = 0.0f;
}
else {
if(y_in > 0.0f) {
if (y_in > 0.0f) {
y_in -= joystick_deadzone;
}
}
else {
y_in += joystick_deadzone;
}
@@ -695,7 +722,7 @@ void recomp::set_right_analog_suppressed(bool suppressed) {
bool recomp::game_input_disabled() {
// Disable input if any menu that blocks input is open.
return recompui::is_context_taking_input();
return recompui::is_context_capturing_input();
}
bool recomp::all_input_disabled() {
@@ -735,16 +762,16 @@ std::string controller_button_to_string(SDL_GameControllerButton button) {
return PF_DPAD_LEFT;
case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
return PF_DPAD_RIGHT;
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_MISC1:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE1:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE2:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE3:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE4:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_MISC1:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE1:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE2:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE3:
// return "";
// case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE4:
// return "";
case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_TOUCHPAD:
return PF_SONY_TOUCHPAD;
default:
@@ -752,7 +779,7 @@ std::string controller_button_to_string(SDL_GameControllerButton button) {
}
}
std::unordered_map<SDL_Scancode, std::string> scancode_codepoints {
std::unordered_map<SDL_Scancode, std::string> scancode_codepoints{
{SDL_SCANCODE_LEFT, PF_KEYBOARD_LEFT},
// NOTE: UP and RIGHT are swapped with promptfont.
{SDL_SCANCODE_UP, PF_KEYBOARD_RIGHT},
@@ -856,15 +883,15 @@ std::string controller_axis_to_string(int axis) {
std::string recomp::InputField::to_string() const {
switch ((InputType)input_type) {
case InputType::None:
return "";
case InputType::ControllerDigital:
return controller_button_to_string((SDL_GameControllerButton)input_id);
case InputType::ControllerAnalog:
return controller_axis_to_string(input_id);
case InputType::Keyboard:
return keyboard_input_to_string((SDL_Scancode)input_id);
default:
return std::to_string(input_type) + "," + std::to_string(input_id);
case InputType::None:
return "";
case InputType::ControllerDigital:
return controller_button_to_string((SDL_GameControllerButton)input_id);
case InputType::ControllerAnalog:
return controller_axis_to_string(input_id);
case InputType::Keyboard:
return keyboard_input_to_string((SDL_Scancode)input_id);
default:
return std::to_string(input_type) + "," + std::to_string(input_id);
}
}
@@ -8,7 +8,7 @@
#include "ultramodern/error_handling.hpp"
#include "recomp_ui.h"
#include "recomp_data.h"
#include "../patches/mem_funcs.h"
#include "../patches/actor_funcs.h"
struct ExtensionInfo {
// Either the actor's type ID, or 0xFFFFFFFF if this is for generic data.
@@ -41,7 +41,7 @@ bool can_register = false;
size_t alloc_count = 0;
size_t free_count = 0;
void recomp::init_extended_actor_data() {
void recomputil::init_extended_actor_data() {
std::lock_guard lock{ actor_data_mutex };
actor_data_sizes.clear();
@@ -54,7 +54,7 @@ void recomp::init_extended_actor_data() {
actor_extensions.push_back({});
}
void recomp::reset_actor_data() {
void recomputil::reset_actor_data() {
std::lock_guard lock{ actor_data_mutex };
actor_data.reset();
actor_spawn_count = 0;
@@ -113,7 +113,7 @@ extern "C" void recomp_register_actor_extension_generic(uint8_t* rdram, recomp_c
extern "C" void recomp_clear_all_actor_data(uint8_t* rdram, recomp_context* ctx) {
(void)rdram;
(void)ctx;
recomp::reset_actor_data();
recomputil::reset_actor_data();
}
extern "C" void recomp_create_actor_data(uint8_t* rdram, recomp_context* ctx) {
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More