From 5a8a1cb2ba6936a10a3d4a78df1e8e6f0919740a Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Sat, 28 Sep 2024 16:50:58 -0400 Subject: [PATCH] Update runtime for custom mod content types and add RT64 texture pack support --- include/zelda_render.h | 8 +++++ lib/N64ModernRuntime | 2 +- src/game/config.cpp | 1 - src/main/main.cpp | 23 ++++++++++++++ src/main/rt64_render_context.cpp | 54 ++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/include/zelda_render.h b/include/zelda_render.h index 684672b..2d909e4 100644 --- a/include/zelda_render.h +++ b/include/zelda_render.h @@ -1,8 +1,12 @@ #ifndef __ZELDA_RENDER_H__ #define __ZELDA_RENDER_H__ +#include +#include + #include "common/rt64_user_configuration.h" #include "ultramodern/renderer_context.hpp" +#include "librecomp/mods.hpp" namespace RT64 { struct Application; @@ -29,6 +33,7 @@ namespace zelda64 { protected: std::unique_ptr app; + std::unordered_set enabled_texture_packs; }; std::unique_ptr create_render_context(uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode); @@ -36,6 +41,9 @@ namespace zelda64 { RT64::UserConfiguration::Antialiasing RT64MaxMSAA(); bool RT64SamplePositionsSupported(); bool RT64HighPrecisionFBEnabled(); + + void enable_texture_pack(const recomp::mods::ModHandle& mod); + void disable_texture_pack(const recomp::mods::ModHandle& mod); } } diff --git a/lib/N64ModernRuntime b/lib/N64ModernRuntime index 46797d6..a4f5ee1 160000 --- a/lib/N64ModernRuntime +++ b/lib/N64ModernRuntime @@ -1 +1 @@ -Subproject commit 46797d6cadca6ff78377e7065d073a176d988025 +Subproject commit a4f5ee10c8303474d9028468e84845b192e9297d diff --git a/src/game/config.cpp b/src/game/config.cpp index ac8ebff..ab24e0a 100644 --- a/src/game/config.cpp +++ b/src/game/config.cpp @@ -19,7 +19,6 @@ constexpr std::u8string_view general_filename = u8"general.json"; constexpr std::u8string_view graphics_filename = u8"graphics.json"; constexpr std::u8string_view controls_filename = u8"controls.json"; constexpr std::u8string_view sound_filename = u8"sound.json"; -constexpr std::u8string_view program_id = u8"Zelda64Recompiled"; constexpr auto res_default = ultramodern::renderer::Resolution::Auto; constexpr auto hr_default = ultramodern::renderer::HUDRatioMode::Clamp16x9; diff --git a/src/main/main.cpp b/src/main/main.cpp index 6007ffa..cbeb63a 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -528,6 +528,16 @@ void release_preload(PreloadContext& context) { #endif +void enable_texture_pack(recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod) { + (void)context; + zelda64::renderer::enable_texture_pack(mod); +} + +void disable_texture_pack(recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod) { + (void)context; + zelda64::renderer::disable_texture_pack(mod); +} + int main(int argc, char** argv) { recomp::Version project_version{}; if (!recomp::Version::from_string(version_string, project_version)) { @@ -629,6 +639,18 @@ int main(int argc, char** argv) { .get_game_thread_name = zelda64::get_game_thread_name, }; + // Register the texture pack content type with rt64.json as its content file. + recomp::mods::ModContentType texture_pack_content_type{ + .content_filename = "rt64.json", + .allow_runtime_toggle = true, + .on_enabled = enable_texture_pack, + .on_disabled = disable_texture_pack, + }; + auto texture_pack_content_type_id = recomp::mods::register_mod_content_type(texture_pack_content_type); + + // Register the .rtz texture pack file format with the previous content type as its only allowed content type. + recomp::mods::register_mod_container_type("rtz", std::vector{ texture_pack_content_type_id }, false); + recomp::mods::scan_mods(); printf("Found mods:\n"); @@ -641,6 +663,7 @@ int main(int argc, char** argv) { printf(", %s", author.c_str()); } printf("\n"); + printf(" Runtime toggleable: %d\n", mod.runtime_toggleable); } if (!mod.dependencies.empty()) { printf(" Dependencies: %s:%s", mod.dependencies[0].mod_id.c_str(), mod.dependencies[0].version.to_string().c_str()); diff --git a/src/main/rt64_render_context.cpp b/src/main/rt64_render_context.cpp index 497e504..8d5c735 100644 --- a/src/main/rt64_render_context.cpp +++ b/src/main/rt64_render_context.cpp @@ -1,5 +1,6 @@ #include #include +#include #define HLSL_CPU #include "hle/rt64_application.h" @@ -10,6 +11,13 @@ #include "zelda_render.h" #include "recomp_ui.h" +#include "concurrentqueue.h" + +// Helper class for variant visiting. +template +struct overloaded : Ts... { using Ts::operator()...; }; +template +overloaded(Ts...) -> overloaded; static RT64::UserConfiguration::Antialiasing device_max_msaa = RT64::UserConfiguration::Antialiasing::None; static bool sample_positions_supported = false; @@ -18,6 +26,18 @@ static bool high_precision_fb_enabled = false; static uint8_t DMEM[0x1000]; static uint8_t IMEM[0x1000]; +struct TexturePackEnableAction { + std::filesystem::path path; +}; + +struct TexturePackDisableAction { + std::filesystem::path path; +}; + +using TexturePackAction = std::variant; + +static moodycamel::ConcurrentQueue texture_pack_action_queue; + unsigned int MI_INTR_REG = 0; unsigned int DPC_START_REG = 0; @@ -286,6 +306,32 @@ zelda64::renderer::RT64Context::RT64Context(uint8_t* rdram, ultramodern::rendere zelda64::renderer::RT64Context::~RT64Context() = default; void zelda64::renderer::RT64Context::send_dl(const OSTask* task) { + bool packs_disabled = false; + TexturePackAction cur_action; + while (texture_pack_action_queue.try_dequeue(cur_action)) { + std::visit(overloaded{ + [&](TexturePackDisableAction& to_disable) { + enabled_texture_packs.erase(to_disable.path); + packs_disabled = true; + }, + [&](TexturePackEnableAction& to_enable) { + enabled_texture_packs.insert(to_enable.path); + // Load the pack now if no packs have been disabled. + if (!packs_disabled) { + app->textureCache->loadReplacementDirectory(to_enable.path); + } + } + }, cur_action); + } + + // If any packs were disabled, unload all packs and load all the active ones. + if (packs_disabled) { + app->textureCache->clearReplacementDirectories(); + for (const std::filesystem::path& cur_pack_path : enabled_texture_packs) { + app->textureCache->loadReplacementDirectory(cur_pack_path); + } + } + app->state->rsp->reset(); app->interpreter->loadUCodeGBI(task->t.ucode & 0x3FFFFFF, task->t.ucode_data & 0x3FFFFFF, true); app->processDisplayLists(app->core.RDRAM, task->t.data_ptr & 0x3FFFFFF, 0, true); @@ -376,3 +422,11 @@ bool zelda64::renderer::RT64SamplePositionsSupported() { bool zelda64::renderer::RT64HighPrecisionFBEnabled() { return high_precision_fb_enabled; } + +void zelda64::renderer::enable_texture_pack(const recomp::mods::ModHandle& mod) { + texture_pack_action_queue.enqueue(TexturePackEnableAction{mod.manifest.mod_root_path}); +} + +void zelda64::renderer::disable_texture_pack(const recomp::mods::ModHandle& mod) { + texture_pack_action_queue.enqueue(TexturePackDisableAction{mod.manifest.mod_root_path}); +}