From 288bd11a29c935eb888daccf24372f3bede57d3d Mon Sep 17 00:00:00 2001 From: angie Date: Wed, 29 May 2024 16:32:40 -0400 Subject: [PATCH 1/5] Remove unnecessary headers --- librecomp/include/disable_warnings.h | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 librecomp/include/disable_warnings.h diff --git a/librecomp/include/disable_warnings.h b/librecomp/include/disable_warnings.h deleted file mode 100644 index 6526983..0000000 --- a/librecomp/include/disable_warnings.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wimplicit-function-declaration" -#endif From 6a10d4ed43e75842c505015b163a98508cf08376 Mon Sep 17 00:00:00 2001 From: Reonu Date: Wed, 29 May 2024 16:46:51 -0400 Subject: [PATCH 2/5] Support for high precision framebuffers and dither noise (RT64) From Zelda64Recomp/Zelda64Recomp#252 commit 23eb6b7eea9fd12f93d31c313faa335245bbfb3c Co-authored-by: Mr-Wiseguy --- rt64 | 2 +- ultramodern/include/ultramodern/config.hpp | 13 +++++++ ultramodern/include/ultramodern/rt64_layer.h | 4 +- .../include/ultramodern/ultramodern.hpp | 2 +- ultramodern/src/events.cpp | 6 +++ ultramodern/src/rt64_layer.cpp | 39 +++++++++++++++++++ 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/rt64 b/rt64 index ca26fb8..64b9e16 160000 --- a/rt64 +++ b/rt64 @@ -1 +1 @@ -Subproject commit ca26fb8096b9af117c668e8dfaa49fdde815c3b7 +Subproject commit 64b9e166f75b4dc44a59983b67c3e9ecc1f4cfd7 diff --git a/ultramodern/include/ultramodern/config.hpp b/ultramodern/include/ultramodern/config.hpp index a8b99e2..7212034 100644 --- a/ultramodern/include/ultramodern/config.hpp +++ b/ultramodern/include/ultramodern/config.hpp @@ -28,6 +28,12 @@ namespace ultramodern { Vulkan, OptionCount }; + enum class HighPrecisionFramebuffer { + Auto, + On, + Off, + OptionCount + }; struct GraphicsConfig { Resolution res_option; @@ -38,6 +44,7 @@ namespace ultramodern { RT64::UserConfiguration::AspectRatio ar_option; RT64::UserConfiguration::Antialiasing msaa_option; RT64::UserConfiguration::RefreshRate rr_option; + HighPrecisionFramebuffer hpfb_option; int rr_manual_value; int ds_option; bool developer_mode; @@ -70,6 +77,12 @@ namespace ultramodern { {ultramodern::GraphicsApi::D3D12, "D3D12"}, {ultramodern::GraphicsApi::Vulkan, "Vulkan"}, }); + + NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::HighPrecisionFramebuffer, { + {ultramodern::HighPrecisionFramebuffer::Auto, "Auto"}, + {ultramodern::HighPrecisionFramebuffer::On, "On"}, + {ultramodern::HighPrecisionFramebuffer::Off, "Off"}, + }); }; #endif diff --git a/ultramodern/include/ultramodern/rt64_layer.h b/ultramodern/include/ultramodern/rt64_layer.h index 0928d06..4b9f31a 100644 --- a/ultramodern/include/ultramodern/rt64_layer.h +++ b/ultramodern/include/ultramodern/rt64_layer.h @@ -32,14 +32,16 @@ namespace ultramodern { void shutdown(); void set_dummy_vi(); uint32_t get_display_framerate(); + float get_resolution_scale(); void load_shader_cache(std::span cache_binary); private: RT64SetupResult setup_result; std::unique_ptr app; }; - + RT64::UserConfiguration::Antialiasing RT64MaxMSAA(); bool RT64SamplePositionsSupported(); + bool RT64HighPrecisionFBEnabled(); } void set_rt64_hooks(); diff --git a/ultramodern/include/ultramodern/ultramodern.hpp b/ultramodern/include/ultramodern/ultramodern.hpp index 547fba1..871abee 100644 --- a/ultramodern/include/ultramodern/ultramodern.hpp +++ b/ultramodern/include/ultramodern/ultramodern.hpp @@ -122,9 +122,9 @@ void sleep_milliseconds(uint32_t millis); void sleep_until(const std::chrono::high_resolution_clock::time_point& time_point); // Graphics -void get_window_size(uint32_t& width, uint32_t& height); uint32_t get_target_framerate(uint32_t original); uint32_t get_display_refresh_rate(); +float get_resolution_scale(); void load_shader_cache(std::span cache_data); // Audio diff --git a/ultramodern/src/events.cpp b/ultramodern/src/events.cpp index 7fba7b6..9ca13c2 100644 --- a/ultramodern/src/events.cpp +++ b/ultramodern/src/events.cpp @@ -241,6 +241,7 @@ ultramodern::GraphicsConfig ultramodern::get_graphics_config() { } std::atomic_uint32_t display_refresh_rate = 60; +std::atomic resolution_scale = 1.0f; uint32_t ultramodern::get_target_framerate(uint32_t original) { ultramodern::GraphicsConfig graphics_config = ultramodern::get_graphics_config(); @@ -260,6 +261,10 @@ uint32_t ultramodern::get_display_refresh_rate() { return display_refresh_rate.load(); } +float ultramodern::get_resolution_scale() { + return resolution_scale.load(); +} + void ultramodern::load_shader_cache(std::span cache_data) { events_context.action_queue.enqueue(LoadShaderCacheAction{cache_data}); } @@ -322,6 +327,7 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re events_context.vi.current_buffer = events_context.vi.next_buffer; rt64.update_screen(swap_action->origin); display_refresh_rate = rt64.get_display_framerate(); + resolution_scale = rt64.get_resolution_scale(); } else if (const auto* config_action = std::get_if(&action)) { ultramodern::GraphicsConfig new_config = cur_config; diff --git a/ultramodern/src/rt64_layer.cpp b/ultramodern/src/rt64_layer.cpp index 45290b1..dbc0e76 100644 --- a/ultramodern/src/rt64_layer.cpp +++ b/ultramodern/src/rt64_layer.cpp @@ -11,6 +11,7 @@ ultramodern::RT64Context::~RT64Context() = default; static RT64::UserConfiguration::Antialiasing device_max_msaa = RT64::UserConfiguration::Antialiasing::None; static bool sample_positions_supported = false; +static bool high_precision_fb_enabled = false; static uint8_t DMEM[0x1000]; static uint8_t IMEM[0x1000]; @@ -58,6 +59,19 @@ RT64::UserConfiguration::Antialiasing compute_max_supported_aa(RT64::RenderSampl return RT64::UserConfiguration::Antialiasing::None; } +RT64::UserConfiguration::InternalColorFormat to_rt64(ultramodern::HighPrecisionFramebuffer option) { + switch (option) { + case ultramodern::HighPrecisionFramebuffer::Off: + return RT64::UserConfiguration::InternalColorFormat::Standard; + case ultramodern::HighPrecisionFramebuffer::On: + return RT64::UserConfiguration::InternalColorFormat::High; + case ultramodern::HighPrecisionFramebuffer::Auto: + return RT64::UserConfiguration::InternalColorFormat::Automatic; + default: + return RT64::UserConfiguration::InternalColorFormat::OptionCount; + } +} + void set_application_user_config(RT64::Application* application, const ultramodern::GraphicsConfig& config) { switch (config.res_option) { default: @@ -95,6 +109,7 @@ void set_application_user_config(RT64::Application* application, const ultramode application->userConfig.antialiasing = config.msaa_option; application->userConfig.refreshRate = config.rr_option; application->userConfig.refreshRateTarget = config.rr_manual_value; + application->userConfig.internalColorFormat = to_rt64(config.hpfb_option); } ultramodern::RT64SetupResult map_setup_result(RT64::Application::SetupResult rt64_result) { @@ -223,6 +238,8 @@ ultramodern::RT64Context::RT64Context(uint8_t* rdram, ultramodern::WindowHandle device_max_msaa = RT64::UserConfiguration::Antialiasing::None; sample_positions_supported = false; } + + high_precision_fb_enabled = app->shaderLibrary->usesHDR; } void ultramodern::RT64Context::send_dl(const OSTask* task) { @@ -268,6 +285,24 @@ uint32_t ultramodern::RT64Context::get_display_framerate() { return app->presentQueue->ext.sharedResources->swapChainRate; } +float ultramodern::RT64Context::get_resolution_scale() { + constexpr int ReferenceHeight = 240; + switch (app->userConfig.resolution) { + case RT64::UserConfiguration::Resolution::WindowIntegerScale: + if (app->sharedQueueResources->swapChainHeight > 0) { + return std::max(float((app->sharedQueueResources->swapChainHeight + ReferenceHeight - 1) / ReferenceHeight), 1.0f); + } + else { + return 1.0f; + } + case RT64::UserConfiguration::Resolution::Manual: + return float(app->userConfig.resolutionMultiplier); + case RT64::UserConfiguration::Resolution::Original: + default: + return 1.0f; + } +} + void ultramodern::RT64Context::load_shader_cache(std::span cache_binary) { // TODO figure out how to avoid a copy here. std::istringstream cache_stream{std::string{cache_binary.data(), cache_binary.size()}}; @@ -285,3 +320,7 @@ RT64::UserConfiguration::Antialiasing ultramodern::RT64MaxMSAA() { bool ultramodern::RT64SamplePositionsSupported() { return sample_positions_supported; } + +bool ultramodern::RT64HighPrecisionFBEnabled() { + return high_precision_fb_enabled; +} From eb666c9e013b4587e7d993ef01c175bf44e915fe Mon Sep 17 00:00:00 2001 From: Reonu Date: Wed, 29 May 2024 16:56:54 -0400 Subject: [PATCH 3/5] Automatic save backup system From Zelda64Recomp/Zelda64Recomp#260 commit 4ebe71bfccbef17268c8941bed8d428d445268ca Co-authored-by: Mr-Wiseguy --- librecomp/src/pi.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/librecomp/src/pi.cpp b/librecomp/src/pi.cpp index 2234f82..eb7157f 100644 --- a/librecomp/src/pi.cpp +++ b/librecomp/src/pi.cpp @@ -101,15 +101,30 @@ std::filesystem::path get_save_file_path() { return config_path / save_folder / (std::u8string{recomp::current_game_id()} + u8".bin"); } +std::filesystem::path get_save_file_path_temp() { + return config_path / save_folder / (recomp::current_game_id() + u8".bin.temp"); +} + +std::filesystem::path get_save_file_path_backup() { + return config_path / save_folder / (recomp::current_game_id() + u8".bin.bak"); +} + void update_save_file() { - std::ofstream save_file{ get_save_file_path(), std::ios_base::binary }; + std::ofstream save_file{ get_save_file_path_temp(), std::ios_base::binary }; if (save_file.good()) { std::lock_guard lock{ save_context.save_buffer_mutex }; save_file.write(save_context.save_buffer.data(), save_context.save_buffer.size()); + + if (std::filesystem::exists(get_save_file_path())) { + std::filesystem::rename(get_save_file_path(), get_save_file_path_backup()); + } else { + printf("\nSavefile doesn't exist. Skip renaming.\n"); + } + std::filesystem::rename(get_save_file_path_temp(), get_save_file_path()); } else { - fprintf(stderr, "Failed to save!\n"); - std::exit(EXIT_FAILURE); + ultramodern::error_handling::message_box("Failed to write to the save file. Check your file permissions. If you have moved your appdata folder to Dropbox or similar, this can cause issues."); + // std::exit(EXIT_FAILURE); } } @@ -176,6 +191,7 @@ void save_clear(uint32_t start, uint32_t size, char value) { void ultramodern::init_saving(RDRAM_ARG1) { std::filesystem::path save_file_path = get_save_file_path(); + std::filesystem::path save_file_path_backup = get_save_file_path_backup(); // Ensure the save file directory exists. std::filesystem::create_directories(save_file_path.parent_path()); @@ -185,8 +201,14 @@ void ultramodern::init_saving(RDRAM_ARG1) { if (save_file.good()) { save_file.read(save_context.save_buffer.data(), save_context.save_buffer.size()); } else { - // Otherwise clear the save file to all zeroes. - save_context.save_buffer.fill(0); + // Reading the save file faield, so try to read the backup save file. + std::ifstream save_file_backup{ save_file_path_backup, std::ios_base::binary }; + if (save_file_backup.good()) { + save_file_backup.read(save_context.save_buffer.data(), save_context.save_buffer.size()); + } else { + // Otherwise clear the save file to all zeroes. + save_context.save_buffer.fill(0); + } } save_context.saving_thread = std::thread{saving_thread_func, PASS_RDRAM}; From e41c7cce6d27660018cfad2c92c96d5dc8211047 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Wed, 29 May 2024 17:00:18 -0400 Subject: [PATCH 4/5] Fixed Windows filesystem error crash From Zelda64Recomp/Zelda64Recomp#271 commit 1ea7d4ebe9dcf522faa13cab513f88c3217ba011 --- librecomp/src/pi.cpp | 31 +++++++++++++++++++------------ rt64 | 2 +- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/librecomp/src/pi.cpp b/librecomp/src/pi.cpp index eb7157f..715e458 100644 --- a/librecomp/src/pi.cpp +++ b/librecomp/src/pi.cpp @@ -110,21 +110,28 @@ std::filesystem::path get_save_file_path_backup() { } void update_save_file() { - std::ofstream save_file{ get_save_file_path_temp(), std::ios_base::binary }; + { + std::ofstream save_file{ get_save_file_path_temp(), std::ios_base::binary }; - if (save_file.good()) { - std::lock_guard lock{ save_context.save_buffer_mutex }; - save_file.write(save_context.save_buffer.data(), save_context.save_buffer.size()); - - if (std::filesystem::exists(get_save_file_path())) { - std::filesystem::rename(get_save_file_path(), get_save_file_path_backup()); - } else { - printf("\nSavefile doesn't exist. Skip renaming.\n"); + if (save_file.good()) { + std::lock_guard lock{ save_context.save_buffer_mutex }; + save_file.write(save_context.save_buffer.data(), save_context.save_buffer.size()); } - std::filesystem::rename(get_save_file_path_temp(), get_save_file_path()); - } else { + else { + ultramodern::error_handling::message_box("Failed to write to the save file. Check your file permissions. If you have moved your appdata folder to Dropbox or similar, this can cause issues."); + } + } + + std::error_code ec; + if (std::filesystem::exists(get_save_file_path(), ec)) { + std::filesystem::copy_file(get_save_file_path(), get_save_file_path_backup(), std::filesystem::copy_options::overwrite_existing, ec); + if (ec) { + printf("[ERROR] Failed to copy save file backup\n"); + } + } + std::filesystem::copy_file(get_save_file_path_temp(), get_save_file_path(), std::filesystem::copy_options::overwrite_existing, ec); + if (ec) { ultramodern::error_handling::message_box("Failed to write to the save file. Check your file permissions. If you have moved your appdata folder to Dropbox or similar, this can cause issues."); - // std::exit(EXIT_FAILURE); } } diff --git a/rt64 b/rt64 index 64b9e16..1adcbea 160000 --- a/rt64 +++ b/rt64 @@ -1 +1 @@ -Subproject commit 64b9e166f75b4dc44a59983b67c3e9ecc1f4cfd7 +Subproject commit 1adcbea31a04f2403da729eb5dfed3950dd7ec52 From a5ff2f4c771b061e966addde55900a82c4923543 Mon Sep 17 00:00:00 2001 From: Angie Date: Thu, 30 May 2024 23:45:23 -0400 Subject: [PATCH 5/5] Set NOMINMAX on the CMakeLists file --- ultramodern/CMakeLists.txt | 1 + ultramodern/src/rt64_layer.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ultramodern/CMakeLists.txt b/ultramodern/CMakeLists.txt index 94356b1..336fd16 100644 --- a/ultramodern/CMakeLists.txt +++ b/ultramodern/CMakeLists.txt @@ -61,6 +61,7 @@ if (WIN32) target_link_directories(ultramodern PRIVATE ${sdl2_SOURCE_DIR}/lib/x64 ) + add_compile_definitions(NOMINMAX) elseif (APPLE) find_package(SDL2 REQUIRED) target_include_directories(ultramodern PRIVATE ${SDL2_INCLUDE_DIRS}) diff --git a/ultramodern/src/rt64_layer.cpp b/ultramodern/src/rt64_layer.cpp index dbc0e76..adc09f9 100644 --- a/ultramodern/src/rt64_layer.cpp +++ b/ultramodern/src/rt64_layer.cpp @@ -1,6 +1,5 @@ #include #include -// #include #define HLSL_CPU #include "hle/rt64_application.h"