mirror of
https://github.com/izzy2lost/BanjoRecomp.git
synced 2026-06-19 01:16:11 -07:00
Update codebase with changes for Zelda 64: Recompiled 1.2
This commit is contained in:
+82
-18
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
+1
-1
Submodule lib/N64ModernRuntime updated: 6ffd6b8856...c5e268aa0f
+1
-1
Submodule lib/lunasvg updated: 610b8bf514...4166d0cccf
+1
-1
Submodule lib/rt64 updated: 1db8c347ca...cf75b17fc2
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef __TRANSFORM_IDS_H__
|
||||
#define __TRANSFORM_IDS_H__
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
#include "patches.h"
|
||||
#include "transform_ids.h"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user