From 49d3b675edc579c2dcfb6a5254eb01dda12a8dd6 Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 30 Mar 2025 04:36:55 +0300 Subject: [PATCH 01/10] Implement a mechanism to survive from GPU driver crashes on Windows. (#1480) --- UnleashedRecomp/gpu/video.cpp | 45 ++++++++++++++++++++++++++++++++--- UnleashedRecomp/gpu/video.h | 2 +- UnleashedRecomp/main.cpp | 6 +++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 6028de9..27b9609 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #if defined(ASYNC_PSO_DEBUG) || defined(PSO_CACHING) #include @@ -1652,7 +1653,7 @@ static void ApplyLowEndDefaults() } } -bool Video::CreateHostDevice(const char *sdlVideoDriver) +bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) { for (uint32_t i = 0; i < 16; i++) g_inputSlots[i].index = i; @@ -1672,6 +1673,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) std::vector interfaceFunctions; #ifdef UNLEASHED_RECOMP_D3D12 + if (graphicsApiRetry) + { + // If we are attempting to create again after a reboot due to a crash, swap the order. + g_vulkan = !g_vulkan; + } + interfaceFunctions.push_back(g_vulkan ? CreateVulkanInterfaceWrapper : CreateD3D12Interface); interfaceFunctions.push_back(g_vulkan ? CreateD3D12Interface : CreateVulkanInterfaceWrapper); #else @@ -1680,9 +1687,17 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) for (RenderInterfaceFunction *interfaceFunction : interfaceFunctions) { - g_interface = interfaceFunction(); - if (g_interface != nullptr) +#ifdef UNLEASHED_RECOMP_D3D12 + // Wrap the device creation in __try/__except to survive from driver crashes. + __try +#endif { + g_interface = interfaceFunction(); + if (g_interface == nullptr) + { + continue; + } + g_device = g_interface->createDevice(Config::GraphicsDevice); if (g_device != nullptr) { @@ -1719,6 +1734,22 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) break; } } +#ifdef UNLEASHED_RECOMP_D3D12 + __except (EXCEPTION_EXECUTE_HANDLER) + { + if (graphicsApiRetry) + { + // If we were retrying, and this also failed, then we'll show the user neither of the graphics APIs succeeded. + return false; + } + else + { + // If this is the first crash we ran into, reboot and try the other graphics API. + os::process::StartProcess(os::process::GetExecutablePath(), { "--graphics-api-retry" }); + std::_Exit(0); + } + } +#endif } if (g_device == nullptr) @@ -1726,6 +1757,14 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) return false; } +#ifdef UNLEASHED_RECOMP_D3D12 + if (graphicsApiRetry) + { + // If we managed to create a device after retrying it in a reboot, remember the one we picked. + Config::GraphicsAPI = g_vulkan ? EGraphicsAPI::Vulkan : EGraphicsAPI::D3D12; + } +#endif + g_capabilities = g_device->getCapabilities(); LoadEmbeddedResources(); diff --git a/UnleashedRecomp/gpu/video.h b/UnleashedRecomp/gpu/video.h index 3a394be..b07169b 100644 --- a/UnleashedRecomp/gpu/video.h +++ b/UnleashedRecomp/gpu/video.h @@ -18,7 +18,7 @@ struct Video static inline uint32_t s_viewportWidth; static inline uint32_t s_viewportHeight; - static bool CreateHostDevice(const char *sdlVideoDriver); + static bool CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry); static void WaitOnSwapChain(); static void Present(); static void StartPipelinePrecompilation(); diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index 7cf0747..04e3fb1 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -208,6 +208,7 @@ int main(int argc, char *argv[]) bool forceDLCInstaller = false; bool useDefaultWorkingDirectory = false; bool forceInstallationCheck = false; + bool graphicsApiRetry = false; const char *sdlVideoDriver = nullptr; for (uint32_t i = 1; i < argc; i++) @@ -216,6 +217,7 @@ int main(int argc, char *argv[]) forceDLCInstaller = forceDLCInstaller || (strcmp(argv[i], "--install-dlc") == 0); useDefaultWorkingDirectory = useDefaultWorkingDirectory || (strcmp(argv[i], "--use-cwd") == 0); forceInstallationCheck = forceInstallationCheck || (strcmp(argv[i], "--install-check") == 0); + graphicsApiRetry = graphicsApiRetry || (strcmp(argv[i], "--graphics-api-retry") == 0); if (strcmp(argv[i], "--sdl-video-driver") == 0) { @@ -326,7 +328,7 @@ int main(int argc, char *argv[]) bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled; if (runInstallerWizard) { - if (!Video::CreateHostDevice(sdlVideoDriver)) + if (!Video::CreateHostDevice(sdlVideoDriver, graphicsApiRetry)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, GameWindow::GetTitle(), Localise("Video_BackendError").c_str(), GameWindow::s_pWindow); std::_Exit(1); @@ -346,7 +348,7 @@ int main(int argc, char *argv[]) if (!runInstallerWizard) { - if (!Video::CreateHostDevice(sdlVideoDriver)) + if (!Video::CreateHostDevice(sdlVideoDriver, graphicsApiRetry)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, GameWindow::GetTitle(), Localise("Video_BackendError").c_str(), GameWindow::s_pWindow); std::_Exit(1); From f5f92d0761443c1303ccc30443ad224f13eb8e39 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sun, 30 Mar 2025 05:53:11 -0700 Subject: [PATCH 02/10] Prevent rendering ownership change between command lists. (#1486) --- UnleashedRecomp/gpu/video.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 27b9609..58ec13d 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -736,10 +736,13 @@ static void DestructTempResources() } static std::thread::id g_presentThreadId = std::this_thread::get_id(); +static std::atomic g_readyForCommands; PPC_FUNC_IMPL(__imp__sub_824ECA00); PPC_FUNC(sub_824ECA00) { + // Guard against thread ownership changes when between command lists. + g_readyForCommands.wait(false); g_presentThreadId = std::this_thread::get_id(); __imp__sub_824ECA00(ctx, base); } @@ -1624,6 +1627,9 @@ static void BeginCommandList() commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 1); commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 2); commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 3); + + g_readyForCommands = true; + g_readyForCommands.notify_one(); } template @@ -2749,6 +2755,8 @@ static std::atomic g_executedCommandList; void Video::Present() { + g_readyForCommands = false; + RenderCommand cmd; cmd.type = RenderCommandType::ExecutePendingStretchRectCommands; g_renderQueue.enqueue(cmd); From f7c823eeaf723d1bc3e3b6cc90b404a2716bdd72 Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:42:37 +0300 Subject: [PATCH 03/10] Fix staffroll text getting cropped at narrow aspect ratios. (#1489) --- .../patches/aspect_ratio_patches.cpp | 36 +++++++++++++++++++ UnleashedRecompLib/config/SWA.toml | 35 ++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/UnleashedRecomp/patches/aspect_ratio_patches.cpp b/UnleashedRecomp/patches/aspect_ratio_patches.cpp index d1780b1..02f49ee 100644 --- a/UnleashedRecomp/patches/aspect_ratio_patches.cpp +++ b/UnleashedRecomp/patches/aspect_ratio_patches.cpp @@ -1650,3 +1650,39 @@ PPC_FUNC(sub_82E54950) __imp__sub_82E54950(ctx, base); } } + +// Credits while Sonic is running are offseted by 133 pixels at 16:9. +// We can make this dynamic by remembering the anchoring and shifting accordingly. +void EndingTextAllocMidAsmHook(PPCRegister& r3) +{ + r3.u32 += sizeof(uint32_t); +} + +static constexpr uint32_t ENDING_TEXT_SIZE = 0x164; + +void EndingTextCtorRightMidAsmHook(PPCRegister& r3) +{ + *reinterpret_cast(g_memory.base + r3.u32 + ENDING_TEXT_SIZE) = ALIGN_RIGHT; +} + +void EndingTextCtorLeftMidAsmHook(PPCRegister& r3) +{ + *reinterpret_cast(g_memory.base + r3.u32 + ENDING_TEXT_SIZE) = ALIGN_LEFT; +} + +void EndingTextCtorCenterMidAsmHook(PPCRegister& r3) +{ + *reinterpret_cast(g_memory.base + r3.u32 + ENDING_TEXT_SIZE) = ALIGN_CENTER; +} + +void EndingTextPositionMidAsmHook(PPCRegister& r31, PPCRegister& f13) +{ + uint32_t align = *reinterpret_cast(g_memory.base + r31.u32 + ENDING_TEXT_SIZE); + + // Since widescreen is always forced, 133 offset will always be part of the position. + if (align == ALIGN_RIGHT) + f13.f64 += -133.0 * (1.0 - g_aspectRatioNarrowScale); + + else if (align == ALIGN_LEFT) + f13.f64 += 133.0 * (1.0 - g_aspectRatioNarrowScale); +} diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index db5bf2d..eb871b8 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -1106,3 +1106,38 @@ name = "UseAlternateTitleMidAsmHook" address = 0x82580F44 jump_address_on_true = 0x82580F48 jump_address_on_false = 0x82580FA0 + +[[midasm_hook]] +name = "EndingTextAllocMidAsmHook" +address = 0x8257E284 +registers = ["r3"] + +[[midasm_hook]] +name = "EndingTextAllocMidAsmHook" +address = 0x8257E45C +registers = ["r3"] + +[[midasm_hook]] +name = "EndingTextAllocMidAsmHook" +address = 0x8257EDD8 +registers = ["r3"] + +[[midasm_hook]] +name = "EndingTextCtorRightMidAsmHook" +address = 0x8257E304 +registers = ["r3"] + +[[midasm_hook]] +name = "EndingTextCtorLeftMidAsmHook" +address = 0x8257E4DC +registers = ["r3"] + +[[midasm_hook]] +name = "EndingTextCtorCenterMidAsmHook" +address = 0x8257EE40 +registers = ["r3"] + +[[midasm_hook]] +name = "EndingTextPositionMidAsmHook" +address = 0x82580168 +registers = ["r31", "f13"] From 837031245404b7d68fa9b91f4f1546927b24a7e3 Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:06:03 +0300 Subject: [PATCH 04/10] Redirect Intel GPUs to Vulkan on auto graphics API mode. (#1491) --- UnleashedRecomp/gpu/video.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 58ec13d..1f06291 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -1712,6 +1712,8 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) #ifdef UNLEASHED_RECOMP_D3D12 if (interfaceFunction == CreateD3D12Interface) { + bool redirectToVulkan = false; + if (deviceDescription.vendor == RenderDeviceVendor::AMD) { // AMD Drivers before this version have a known issue where MSAA resolve targets will fail to work correctly. @@ -1719,11 +1721,23 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) // just work incorrectly otherwise and result in visual glitches and 3D rendering not working in general. constexpr uint64_t MinimumAMDDriverVersion = 0x1F00005DC2005CULL; // 31.0.24002.92 if ((Config::GraphicsAPI == EGraphicsAPI::Auto) && (deviceDescription.driverVersion < MinimumAMDDriverVersion)) - { - g_device.reset(); - g_interface.reset(); - continue; - } + redirectToVulkan = true; + } + else if (deviceDescription.vendor == RenderDeviceVendor::INTEL) + { + // Intel drivers on D3D12 are extremely buggy, introducing various graphical glitches. + // We will redirect users to Vulkan until a workaround can be found. + if (Config::GraphicsAPI == EGraphicsAPI::Auto) + redirectToVulkan = true; + } + + // Allow redirection to Vulkan only if we are not retrying after a crash, + // so the user can at least boot the game with D3D12 if Vulkan fails to work. + if (!graphicsApiRetry && redirectToVulkan) + { + g_device.reset(); + g_interface.reset(); + continue; } // Hardware resolve seems to be completely bugged on Intel D3D12 drivers. From 21be4e17fb98988294fd521125d9bbcb43b3af7e Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 3 Apr 2025 16:02:30 +0300 Subject: [PATCH 05/10] Try creating the D3D12 device again if redirection to Vulkan fails. (#1504) --- UnleashedRecomp/gpu/video.cpp | 68 ++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 1f06291..8815bb8 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -1679,10 +1679,16 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) std::vector interfaceFunctions; #ifdef UNLEASHED_RECOMP_D3D12 + bool allowVulkanRedirection = true; + if (graphicsApiRetry) { // If we are attempting to create again after a reboot due to a crash, swap the order. g_vulkan = !g_vulkan; + + // Don't allow redirection to Vulkan if we are retrying after a crash, + // so the user can at least boot the game with D3D12 if Vulkan fails to work. + allowVulkanRedirection = false; } interfaceFunctions.push_back(g_vulkan ? CreateVulkanInterfaceWrapper : CreateD3D12Interface); @@ -1691,8 +1697,10 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) interfaceFunctions.push_back(CreateVulkanInterfaceWrapper); #endif - for (RenderInterfaceFunction *interfaceFunction : interfaceFunctions) + for (size_t i = 0; i < interfaceFunctions.size(); i++) { + RenderInterfaceFunction* interfaceFunction = interfaceFunctions[i]; + #ifdef UNLEASHED_RECOMP_D3D12 // Wrap the device creation in __try/__except to survive from driver crashes. __try @@ -1712,32 +1720,42 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) #ifdef UNLEASHED_RECOMP_D3D12 if (interfaceFunction == CreateD3D12Interface) { - bool redirectToVulkan = false; + if (allowVulkanRedirection) + { + bool redirectToVulkan = false; - if (deviceDescription.vendor == RenderDeviceVendor::AMD) - { - // AMD Drivers before this version have a known issue where MSAA resolve targets will fail to work correctly. - // If no specific graphics API was selected, we silently destroy this one and move to the next option as it'll - // just work incorrectly otherwise and result in visual glitches and 3D rendering not working in general. - constexpr uint64_t MinimumAMDDriverVersion = 0x1F00005DC2005CULL; // 31.0.24002.92 - if ((Config::GraphicsAPI == EGraphicsAPI::Auto) && (deviceDescription.driverVersion < MinimumAMDDriverVersion)) - redirectToVulkan = true; - } - else if (deviceDescription.vendor == RenderDeviceVendor::INTEL) - { - // Intel drivers on D3D12 are extremely buggy, introducing various graphical glitches. - // We will redirect users to Vulkan until a workaround can be found. - if (Config::GraphicsAPI == EGraphicsAPI::Auto) - redirectToVulkan = true; - } + if (deviceDescription.vendor == RenderDeviceVendor::AMD) + { + // AMD Drivers before this version have a known issue where MSAA resolve targets will fail to work correctly. + // If no specific graphics API was selected, we silently destroy this one and move to the next option as it'll + // just work incorrectly otherwise and result in visual glitches and 3D rendering not working in general. + constexpr uint64_t MinimumAMDDriverVersion = 0x1F00005DC2005CULL; // 31.0.24002.92 + if ((Config::GraphicsAPI == EGraphicsAPI::Auto) && (deviceDescription.driverVersion < MinimumAMDDriverVersion)) + redirectToVulkan = true; + } + else if (deviceDescription.vendor == RenderDeviceVendor::INTEL) + { + // Intel drivers on D3D12 are extremely buggy, introducing various graphical glitches. + // We will redirect users to Vulkan until a workaround can be found. + if (Config::GraphicsAPI == EGraphicsAPI::Auto) + redirectToVulkan = true; + } - // Allow redirection to Vulkan only if we are not retrying after a crash, - // so the user can at least boot the game with D3D12 if Vulkan fails to work. - if (!graphicsApiRetry && redirectToVulkan) - { - g_device.reset(); - g_interface.reset(); - continue; + if (redirectToVulkan) + { + g_device.reset(); + g_interface.reset(); + + // In case Vulkan fails to initialize, we will try D3D12 again afterwards, + // just to get the game to boot. This only really happens in very old Intel GPU drivers. + if (!g_vulkan) + { + interfaceFunctions.push_back(CreateD3D12Interface); + allowVulkanRedirection = false; + } + + continue; + } } // Hardware resolve seems to be completely bugged on Intel D3D12 drivers. From ff5aae2595f47b7ab4706c127153ad589048fe5f Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:14:29 +0300 Subject: [PATCH 06/10] Fix persistent save data getting loaded before mods. (#1505) --- UnleashedRecomp/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index 04e3fb1..e8123b3 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -236,9 +236,6 @@ int main(int argc, char *argv[]) } Config::Load(); - - if (!PersistentStorageManager::LoadBinary()) - LOGFN_ERROR("Failed to load persistent storage binary... (status code {})", (int)PersistentStorageManager::BinStatus); if (forceInstallationCheck) { @@ -342,6 +339,9 @@ int main(int argc, char *argv[]) ModLoader::Init(); + if (!PersistentStorageManager::LoadBinary()) + LOGFN_ERROR("Failed to load persistent storage binary... (status code {})", (int)PersistentStorageManager::BinStatus); + KiSystemStartup(); uint32_t entry = LdrLoadModule(modulePath); From 30aa528f8476b994ed54ffccf69f42031c4beb63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90e=C3=A4Th?= <55578911+DeaTh-G@users.noreply.github.com> Date: Thu, 3 Apr 2025 19:49:40 +0200 Subject: [PATCH 07/10] Fix line splitting issues from localization changes (#1503) * fix wrongly split lines from localization changes * skip 0x200B line split guidance like new line if line starts with it --- UnleashedRecomp/locale/config_locale.cpp | 6 +++--- UnleashedRecomp/locale/locale.cpp | 2 +- UnleashedRecomp/ui/imgui_utils.cpp | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/UnleashedRecomp/locale/config_locale.cpp b/UnleashedRecomp/locale/config_locale.cpp index 7da6dc8..1242e4e 100644 --- a/UnleashedRecomp/locale/config_locale.cpp +++ b/UnleashedRecomp/locale/config_locale.cpp @@ -233,7 +233,7 @@ CONFIG_DEFINE_ENUM_LOCALE(EControllerIcons) { ELanguage::English, { - { EControllerIcons::Auto, { "AUTO", "Auto : the game will determine which icons to use based on the current input device." } }, + { EControllerIcons::Auto, { "AUTO", "Auto: the game will determine which icons to use based on the current input device." } }, { EControllerIcons::Xbox, { "XBOX", "" } }, { EControllerIcons::PlayStation, { "PLAYSTATION", "" } } } @@ -407,7 +407,7 @@ CONFIG_DEFINE_LOCALE(EffectsVolume) CONFIG_DEFINE_LOCALE(MusicAttenuation) { { ELanguage::English, { "Music Attenuation", "Fade out the game's music when external media is playing." } }, - { ELanguage::Japanese, { "BGM[減衰:げんすい]", "[外部:がいぶ]メディアを\u200B[再生:さいせい]すると\u200Bゲームの\u200B[音楽:おんがく]を\u200Bフェードアウトします" } }, + { ELanguage::Japanese, { "BGM[減衰:げんすい]", "[外部:がいぶ]メディアを\u200B[再生:さいせい]すると\u200Bゲームの\u200B[音楽:おんがく]を\u200Bフェードアウト\u200Bします" } }, { ELanguage::German, { "Musikdämpfung", "Stelle die Musik des Spiels stumm während externe Medien abgespielt werden." } }, { ELanguage::French, { "Atténuation audio", "Abaisse le volume des musiques du jeu lorsqu'un média externe est en cours de lecture." } }, { ELanguage::Spanish, { "Atenuación de música", "Atenúa la música del juego cuando un reproductor multimedia se encuentra activo." } }, @@ -508,7 +508,7 @@ CONFIG_DEFINE_LOCALE(BattleTheme) CONFIG_DEFINE_LOCALE(WindowSize) { { ELanguage::English, { "Window Size", "Adjust the size of the game window in windowed mode." } }, - { ELanguage::Japanese, { "ウィンドウサイズ", "ウィンドウモードでの\u200Bゲームの\u200Bウィンドウサイズを\u200B[調整:ちょうせい]できます" } }, + { ELanguage::Japanese, { "ウィンドウサイズ", "ウィンドウ\u200Bモードでの\u200Bゲームの\u200Bウィンドウサイズを\u200B[調整:ちょうせい]できます" } }, { ELanguage::German, { "Fenstergröße", "Ändere die Größe des Spielfensters im Fenstermodus." } }, { ELanguage::French, { "Taille de la fenêtre", "Modifie la taille de la fenêtre de jeu en mode fenêtré." } }, { ELanguage::Spanish, { "Tamaño de ventana", "Ajusta el tamaño de la ventana de juego." } }, diff --git a/UnleashedRecomp/locale/locale.cpp b/UnleashedRecomp/locale/locale.cpp index 27bf6f2..7544f31 100644 --- a/UnleashedRecomp/locale/locale.cpp +++ b/UnleashedRecomp/locale/locale.cpp @@ -366,7 +366,7 @@ std::unordered_map> { ELanguage::English, "Installation complete!\nThis project is brought to you by:" }, { ELanguage::Japanese, "インストール[完了:かんりょう]!\nプロジェクト[制作:せいさく]:" }, { ELanguage::German, "Installation abgeschlossen!\nDieses Projekt wird präsentiert von:" }, - { ELanguage::French, "Installation terminée !\nCe projet vous est présenté par :" }, + { ELanguage::French, "Installation terminée !\nCe projet vous est présenté\npar :" }, { ELanguage::Spanish, "¡Instalación completada!\nEste proyecto ha sido posible gracias a:" }, { ELanguage::Italian, "Installazione completata!\nQuesto progetto è stato creato da:" } } diff --git a/UnleashedRecomp/ui/imgui_utils.cpp b/UnleashedRecomp/ui/imgui_utils.cpp index be085b4..31592bf 100644 --- a/UnleashedRecomp/ui/imgui_utils.cpp +++ b/UnleashedRecomp/ui/imgui_utils.cpp @@ -510,6 +510,11 @@ std::vector Split(const char* strStart, const ImFont* font, float f if (*str == '\n') str++; + if (strncmp(str, "\u200B", 3) == 0) + { + str += 3; + } + lineStart = str; continue; } From 5fca044662d9b05a1ae772131730cb8a4f6d7ca6 Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 3 Apr 2025 21:55:21 +0300 Subject: [PATCH 08/10] Update version to v1.0.3. (#1492) --- UnleashedRecomp/res/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnleashedRecomp/res/version.txt b/UnleashedRecomp/res/version.txt index a486ce0..d9130f4 100644 --- a/UnleashedRecomp/res/version.txt +++ b/UnleashedRecomp/res/version.txt @@ -1,4 +1,4 @@ VERSION_MILESTONE="" VERSION_MAJOR=1 VERSION_MINOR=0 -VERSION_REVISION=2 +VERSION_REVISION=3 From 1555b97b8a666abb345b3bb1efa7e278906d5a5c Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 3 Apr 2025 23:12:24 +0300 Subject: [PATCH 09/10] Fix half pixel getting applied twice to reverse Z vertex shaders. (#1506) --- tools/XenosRecomp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/XenosRecomp b/tools/XenosRecomp index 4897cf7..56738e5 160000 --- a/tools/XenosRecomp +++ b/tools/XenosRecomp @@ -1 +1 @@ -Subproject commit 4897cf7ef2070120310c28a1a672b427d745dad8 +Subproject commit 56738e5893ed7c4dc108996590475c52726623e3 From 325e4d34a0adaa34808b7212594c0f25b88bfb96 Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Fri, 4 Apr 2025 00:17:00 +0300 Subject: [PATCH 10/10] Fix profiler crashing in the installer. (#1507) --- UnleashedRecomp/gpu/video.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 8815bb8..2333dfb 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -2437,18 +2437,22 @@ static void DrawProfiler() ImGui::NewLine(); - O1HeapDiagnostics diagnostics, physicalDiagnostics; + if (g_userHeap.heap != nullptr && g_userHeap.physicalHeap != nullptr) { - std::lock_guard lock(g_userHeap.mutex); - diagnostics = o1heapGetDiagnostics(g_userHeap.heap); + O1HeapDiagnostics diagnostics, physicalDiagnostics; + { + std::lock_guard lock(g_userHeap.mutex); + diagnostics = o1heapGetDiagnostics(g_userHeap.heap); + } + { + std::lock_guard lock(g_userHeap.physicalMutex); + physicalDiagnostics = o1heapGetDiagnostics(g_userHeap.physicalHeap); + } + + ImGui::Text("Heap Allocated: %d MB", int32_t(diagnostics.allocated / (1024 * 1024))); + ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024))); } - { - std::lock_guard lock(g_userHeap.physicalMutex); - physicalDiagnostics = o1heapGetDiagnostics(g_userHeap.physicalHeap); - } - - ImGui::Text("Heap Allocated: %d MB", int32_t(diagnostics.allocated / (1024 * 1024))); - ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024))); + ImGui::Text("GPU Waits: %d", int32_t(g_waitForGPUCount)); ImGui::Text("Buffer Uploads: %d", int32_t(g_bufferUploadCount)); ImGui::NewLine();