From 83b08cace75f557a218ca9543c77dbdf5437971a Mon Sep 17 00:00:00 2001 From: Vova Date: Wed, 20 Aug 2025 20:25:30 +1000 Subject: [PATCH 1/6] Fix Crash TMNT Shredder's Revenges --- src/Ryujinx.Common/Configuration/DirtyHack.cs | 3 ++- .../HOS/Services/Nv/INvDrvServices.cs | 19 +++++++++++++++++++ .../ConfigurationState.Migration.cs | 1 + .../Configuration/ConfigurationState.Model.cs | 7 +++++++ .../UI/ViewModels/SettingsHacksViewModel.cs | 12 +++++++++++- .../UI/ViewModels/SettingsViewModel.cs | 1 + .../UI/Views/Settings/SettingsHacksView.axaml | 14 ++++++++++++++ 7 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Common/Configuration/DirtyHack.cs b/src/Ryujinx.Common/Configuration/DirtyHack.cs index ae3416a27..dae46ddba 100644 --- a/src/Ryujinx.Common/Configuration/DirtyHack.cs +++ b/src/Ryujinx.Common/Configuration/DirtyHack.cs @@ -10,7 +10,8 @@ namespace Ryujinx.Common.Configuration { Xc2MenuSoftlockFix = 1, // ShaderTranslationDelay = 2 - NifmServiceDisableIsAnyInternetRequestAccepted = 3 + NifmServiceDisableIsAnyInternetRequestAccepted = 3, + TMNT_SRFix = 4 } public readonly struct EnabledDirtyHack(DirtyHack hack, int value) diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index fea09ef47..60c428c1a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -1,4 +1,5 @@ using Ryujinx.Common; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; @@ -12,6 +13,7 @@ using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; using Ryujinx.HLE.HOS.Services.Nv.Types; +using Ryujinx.HLE.HOS.Tamper.Operations; using Ryujinx.Memory; using System; using System.Collections.Generic; @@ -46,6 +48,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv { "/dev/nvhost-dbg-gpu", typeof(NvHostDbgGpuDeviceFile) }, { "/dev/nvhost-prof-gpu", typeof(NvHostProfGpuDeviceFile) }, }; + + + private const string TMNT_SRTitleId = "0100fe701475a000"; + private static bool IsTMNT_SR => TitleIDs.CurrentApplication.Value.OrDefault() is TMNT_SRTitleId; public static IdDictionary DeviceFileIdRegistry = new(); @@ -248,6 +254,19 @@ namespace Ryujinx.HLE.HOS.Services.Nv int fd = context.RequestData.ReadInt32(); NvIoctl ioctlCommand = context.RequestData.ReadStruct(); + if (context.Device.DirtyHacks.IsEnabled(DirtyHack.TMNT_SRFix) && IsTMNT_SR) + { + // Fix emulator crash before splash screen for + // TMNT Shredder's Revenges + + if ((ioctlCommand.Type == NvIoctl.NvMapCustomMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x09)) || + (ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) + { + System.Threading.Thread.Sleep(50); + Logger.Notice.Print(LogClass.ServiceNv, $"Type_{ioctlCommand.Type}, Command_{ioctlCommand.Number} Delay!"); + } + } + errorCode = GetIoctlArgument(context, ioctlCommand, out Span arguments); if (errorCode == NvResult.Success) diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs index 57619aa70..373164b7d 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs @@ -166,6 +166,7 @@ namespace Ryujinx.Ava.Systems.Configuration DirtyHacks hacks = new(cff.DirtyHacks ?? []); Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix); + Hacks.TMNT_SRFix.Value = hacks.IsEnabled(DirtyHack.TMNT_SRFix); } diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs index bc8fdb40a..39872ebea 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs @@ -743,6 +743,8 @@ namespace Ryujinx.Ava.Systems.Configuration public ReactiveObject Xc2MenuSoftlockFix { get; private set; } + public ReactiveObject TMNT_SRFix { get; private set; } + public ReactiveObject DisableNifmIsAnyInternetRequestAccepted { get; private set; } public HacksSection() @@ -752,6 +754,8 @@ namespace Ryujinx.Ava.Systems.Configuration Xc2MenuSoftlockFix.Event += HackChanged; DisableNifmIsAnyInternetRequestAccepted = new ReactiveObject(); DisableNifmIsAnyInternetRequestAccepted.Event += HackChanged; + TMNT_SRFix = new ReactiveObject(); + TMNT_SRFix.Event += HackChanged; } private void HackChanged(object sender, ReactiveEventArgs rxe) @@ -785,6 +789,9 @@ namespace Ryujinx.Ava.Systems.Configuration if (DisableNifmIsAnyInternetRequestAccepted) Apply(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted); + if (TMNT_SRFix) + Apply(DirtyHack.TMNT_SRFix); + return enabledHacks.ToArray(); void Apply(DirtyHack hack, int value = 0) diff --git a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs index 230887e34..b9637cd7f 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Ava.UI.ViewModels [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; [ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted; - + [ObservableProperty] private bool _TMNT_SRFix = ConfigurationState.Instance.Hacks.TMNT_SRFix; public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => { sb.AppendLine( @@ -39,5 +39,15 @@ namespace Ryujinx.Ava.UI.ViewModels sb.Append("Lets DOOM 2016 go in game."); }); + + public static string TMNT_SRFixTooltip { get; } = Lambda.String(sb => + { + sb.AppendLine( + "This fix adds an extra 50 ms to some Ioctl service calls. This prevents the game from crashing when the cutscene starts.") + .AppendLine(); + + sb.Append( + "Just give the game some time to properly interact with guest memory"); + }); } } diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 54fd951fb..4c920baa1 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -856,6 +856,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; config.Hacks.DisableNifmIsAnyInternetRequestAccepted.Value = DirtyHacks.NifmDisableIsAnyInternetRequestAccepted; + config.Hacks.TMNT_SRFix.Value = DirtyHacks.TMNT_SRFix; config.ToFileFormat().SaveConfig(Program.ConfigurationPath); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml index 229f9e866..256ce7af9 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml @@ -55,6 +55,20 @@ VerticalAlignment="Center" Text="Disable IsAnyInternetRequestAccepted" /> + + + + + + From 1f273418f346620c4d7b62003f08e66060890d99 Mon Sep 17 00:00:00 2001 From: Vova Date: Tue, 26 Aug 2025 09:45:00 +1000 Subject: [PATCH 2/6] Optimization: Removed additional delays for services that did not affect the solution of the problem --- src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index 60c428c1a..05954b927 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -259,8 +259,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv // Fix emulator crash before splash screen for // TMNT Shredder's Revenges - if ((ioctlCommand.Type == NvIoctl.NvMapCustomMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x09)) || - (ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) + if ((ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) { System.Threading.Thread.Sleep(50); Logger.Notice.Print(LogClass.ServiceNv, $"Type_{ioctlCommand.Type}, Command_{ioctlCommand.Number} Delay!"); From 86179dbeafa8eccb159cd5a7a9d54cf100e32462 Mon Sep 17 00:00:00 2001 From: Vova Date: Wed, 20 Aug 2025 20:25:30 +1000 Subject: [PATCH 3/6] Fix Crash TMNT Shredder's Revenges --- src/Ryujinx.Common/Configuration/DirtyHack.cs | 3 ++- .../HOS/Services/Nv/INvDrvServices.cs | 19 +++++++++++++++++++ .../ConfigurationState.Migration.cs | 1 + .../Configuration/ConfigurationState.Model.cs | 7 +++++++ .../UI/ViewModels/SettingsHacksViewModel.cs | 12 +++++++++++- .../UI/ViewModels/SettingsViewModel.cs | 1 + .../UI/Views/Settings/SettingsHacksView.axaml | 14 ++++++++++++++ 7 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Common/Configuration/DirtyHack.cs b/src/Ryujinx.Common/Configuration/DirtyHack.cs index ae3416a27..dae46ddba 100644 --- a/src/Ryujinx.Common/Configuration/DirtyHack.cs +++ b/src/Ryujinx.Common/Configuration/DirtyHack.cs @@ -10,7 +10,8 @@ namespace Ryujinx.Common.Configuration { Xc2MenuSoftlockFix = 1, // ShaderTranslationDelay = 2 - NifmServiceDisableIsAnyInternetRequestAccepted = 3 + NifmServiceDisableIsAnyInternetRequestAccepted = 3, + TMNT_SRFix = 4 } public readonly struct EnabledDirtyHack(DirtyHack hack, int value) diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index fea09ef47..60c428c1a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -1,4 +1,5 @@ using Ryujinx.Common; +using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.Exceptions; @@ -12,6 +13,7 @@ using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; using Ryujinx.HLE.HOS.Services.Nv.Types; +using Ryujinx.HLE.HOS.Tamper.Operations; using Ryujinx.Memory; using System; using System.Collections.Generic; @@ -46,6 +48,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv { "/dev/nvhost-dbg-gpu", typeof(NvHostDbgGpuDeviceFile) }, { "/dev/nvhost-prof-gpu", typeof(NvHostProfGpuDeviceFile) }, }; + + + private const string TMNT_SRTitleId = "0100fe701475a000"; + private static bool IsTMNT_SR => TitleIDs.CurrentApplication.Value.OrDefault() is TMNT_SRTitleId; public static IdDictionary DeviceFileIdRegistry = new(); @@ -248,6 +254,19 @@ namespace Ryujinx.HLE.HOS.Services.Nv int fd = context.RequestData.ReadInt32(); NvIoctl ioctlCommand = context.RequestData.ReadStruct(); + if (context.Device.DirtyHacks.IsEnabled(DirtyHack.TMNT_SRFix) && IsTMNT_SR) + { + // Fix emulator crash before splash screen for + // TMNT Shredder's Revenges + + if ((ioctlCommand.Type == NvIoctl.NvMapCustomMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x09)) || + (ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) + { + System.Threading.Thread.Sleep(50); + Logger.Notice.Print(LogClass.ServiceNv, $"Type_{ioctlCommand.Type}, Command_{ioctlCommand.Number} Delay!"); + } + } + errorCode = GetIoctlArgument(context, ioctlCommand, out Span arguments); if (errorCode == NvResult.Success) diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs index 57619aa70..373164b7d 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs @@ -166,6 +166,7 @@ namespace Ryujinx.Ava.Systems.Configuration DirtyHacks hacks = new(cff.DirtyHacks ?? []); Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix); + Hacks.TMNT_SRFix.Value = hacks.IsEnabled(DirtyHack.TMNT_SRFix); } diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs index bc8fdb40a..39872ebea 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs @@ -743,6 +743,8 @@ namespace Ryujinx.Ava.Systems.Configuration public ReactiveObject Xc2MenuSoftlockFix { get; private set; } + public ReactiveObject TMNT_SRFix { get; private set; } + public ReactiveObject DisableNifmIsAnyInternetRequestAccepted { get; private set; } public HacksSection() @@ -752,6 +754,8 @@ namespace Ryujinx.Ava.Systems.Configuration Xc2MenuSoftlockFix.Event += HackChanged; DisableNifmIsAnyInternetRequestAccepted = new ReactiveObject(); DisableNifmIsAnyInternetRequestAccepted.Event += HackChanged; + TMNT_SRFix = new ReactiveObject(); + TMNT_SRFix.Event += HackChanged; } private void HackChanged(object sender, ReactiveEventArgs rxe) @@ -785,6 +789,9 @@ namespace Ryujinx.Ava.Systems.Configuration if (DisableNifmIsAnyInternetRequestAccepted) Apply(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted); + if (TMNT_SRFix) + Apply(DirtyHack.TMNT_SRFix); + return enabledHacks.ToArray(); void Apply(DirtyHack hack, int value = 0) diff --git a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs index 230887e34..b9637cd7f 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Ava.UI.ViewModels [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; [ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted; - + [ObservableProperty] private bool _TMNT_SRFix = ConfigurationState.Instance.Hacks.TMNT_SRFix; public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => { sb.AppendLine( @@ -39,5 +39,15 @@ namespace Ryujinx.Ava.UI.ViewModels sb.Append("Lets DOOM 2016 go in game."); }); + + public static string TMNT_SRFixTooltip { get; } = Lambda.String(sb => + { + sb.AppendLine( + "This fix adds an extra 50 ms to some Ioctl service calls. This prevents the game from crashing when the cutscene starts.") + .AppendLine(); + + sb.Append( + "Just give the game some time to properly interact with guest memory"); + }); } } diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 54fd951fb..4c920baa1 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -856,6 +856,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; config.Hacks.DisableNifmIsAnyInternetRequestAccepted.Value = DirtyHacks.NifmDisableIsAnyInternetRequestAccepted; + config.Hacks.TMNT_SRFix.Value = DirtyHacks.TMNT_SRFix; config.ToFileFormat().SaveConfig(Program.ConfigurationPath); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml index 229f9e866..256ce7af9 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml @@ -55,6 +55,20 @@ VerticalAlignment="Center" Text="Disable IsAnyInternetRequestAccepted" /> + + + + + + From 0e57943d37191f3084fcc0f429bf2cc75b39bc57 Mon Sep 17 00:00:00 2001 From: Vova Date: Tue, 26 Aug 2025 09:45:00 +1000 Subject: [PATCH 4/6] Optimization: Removed additional delays for services that did not affect the solution of the problem --- src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index 60c428c1a..05954b927 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -259,8 +259,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv // Fix emulator crash before splash screen for // TMNT Shredder's Revenges - if ((ioctlCommand.Type == NvIoctl.NvMapCustomMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x09)) || - (ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) + if ((ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) { System.Threading.Thread.Sleep(50); Logger.Notice.Print(LogClass.ServiceNv, $"Type_{ioctlCommand.Type}, Command_{ioctlCommand.Number} Delay!"); From c49b49ba6eb8ac40a76b7c8d632b79723b093bc5 Mon Sep 17 00:00:00 2001 From: Vova Date: Wed, 27 Aug 2025 21:37:09 +1000 Subject: [PATCH 5/6] Renamed variables. Corrected description for hack. Log information is now output via debug level. --- src/Ryujinx.Common/Configuration/DirtyHack.cs | 2 +- src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs | 14 ++++++++------ .../Configuration/ConfigurationState.Migration.cs | 2 +- .../Configuration/ConfigurationState.Model.cs | 10 +++++----- .../UI/ViewModels/SettingsHacksViewModel.cs | 8 ++++---- src/Ryujinx/UI/ViewModels/SettingsViewModel.cs | 2 +- .../UI/Views/Settings/SettingsHacksView.axaml | 6 +++--- 7 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Ryujinx.Common/Configuration/DirtyHack.cs b/src/Ryujinx.Common/Configuration/DirtyHack.cs index dae46ddba..94d53558a 100644 --- a/src/Ryujinx.Common/Configuration/DirtyHack.cs +++ b/src/Ryujinx.Common/Configuration/DirtyHack.cs @@ -11,7 +11,7 @@ namespace Ryujinx.Common.Configuration Xc2MenuSoftlockFix = 1, // ShaderTranslationDelay = 2 NifmServiceDisableIsAnyInternetRequestAccepted = 3, - TMNT_SRFix = 4 + TmntSrCutsceneCrashFix = 4 } public readonly struct EnabledDirtyHack(DirtyHack hack, int value) diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index 05954b927..4f7727b28 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -50,8 +50,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv }; - private const string TMNT_SRTitleId = "0100fe701475a000"; - private static bool IsTMNT_SR => TitleIDs.CurrentApplication.Value.OrDefault() is TMNT_SRTitleId; + private const string TmntSrTitleId = "0100fe701475a000"; + private static bool IsTmntSr => TitleIDs.CurrentApplication.Value.OrDefault() is TmntSrTitleId; public static IdDictionary DeviceFileIdRegistry = new(); @@ -254,15 +254,17 @@ namespace Ryujinx.HLE.HOS.Services.Nv int fd = context.RequestData.ReadInt32(); NvIoctl ioctlCommand = context.RequestData.ReadStruct(); - if (context.Device.DirtyHacks.IsEnabled(DirtyHack.TMNT_SRFix) && IsTMNT_SR) + if (context.Device.DirtyHacks.IsEnabled(DirtyHack.TmntSrCutsceneCrashFix) && IsTmntSr) { - // Fix emulator crash before splash screen for - // TMNT Shredder's Revenges + // This fixes an emulator crash before the cutscene for + // TMNT Shredder's Revenge. + // + // NOTE: Delay of 50ms is a stable value. Trying to reduce latency will crash when going to intro cutscene if ((ioctlCommand.Type == NvIoctl.NvGpuAsMagic && (ioctlCommand.Number == 0x05 || ioctlCommand.Number == 0x06))) { System.Threading.Thread.Sleep(50); - Logger.Notice.Print(LogClass.ServiceNv, $"Type_{ioctlCommand.Type}, Command_{ioctlCommand.Number} Delay!"); + Logger.Debug?.Print(LogClass.ServiceNv, $"Type_{ioctlCommand.Type}, Command_{ioctlCommand.Number} Delay!"); } } diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs index 373164b7d..10d82aabd 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Migration.cs @@ -166,7 +166,7 @@ namespace Ryujinx.Ava.Systems.Configuration DirtyHacks hacks = new(cff.DirtyHacks ?? []); Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix); - Hacks.TMNT_SRFix.Value = hacks.IsEnabled(DirtyHack.TMNT_SRFix); + Hacks.TmntSrCutsceneCrashFix.Value = hacks.IsEnabled(DirtyHack.TmntSrCutsceneCrashFix); } diff --git a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs index 39872ebea..2ced604f8 100644 --- a/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Systems/Configuration/ConfigurationState.Model.cs @@ -743,7 +743,7 @@ namespace Ryujinx.Ava.Systems.Configuration public ReactiveObject Xc2MenuSoftlockFix { get; private set; } - public ReactiveObject TMNT_SRFix { get; private set; } + public ReactiveObject TmntSrCutsceneCrashFix { get; private set; } public ReactiveObject DisableNifmIsAnyInternetRequestAccepted { get; private set; } @@ -754,8 +754,8 @@ namespace Ryujinx.Ava.Systems.Configuration Xc2MenuSoftlockFix.Event += HackChanged; DisableNifmIsAnyInternetRequestAccepted = new ReactiveObject(); DisableNifmIsAnyInternetRequestAccepted.Event += HackChanged; - TMNT_SRFix = new ReactiveObject(); - TMNT_SRFix.Event += HackChanged; + TmntSrCutsceneCrashFix = new ReactiveObject(); + TmntSrCutsceneCrashFix.Event += HackChanged; } private void HackChanged(object sender, ReactiveEventArgs rxe) @@ -789,8 +789,8 @@ namespace Ryujinx.Ava.Systems.Configuration if (DisableNifmIsAnyInternetRequestAccepted) Apply(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted); - if (TMNT_SRFix) - Apply(DirtyHack.TMNT_SRFix); + if (TmntSrCutsceneCrashFix) + Apply(DirtyHack.TmntSrCutsceneCrashFix); return enabledHacks.ToArray(); diff --git a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs index b9637cd7f..46b297c7c 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Ava.UI.ViewModels [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; [ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted; - [ObservableProperty] private bool _TMNT_SRFix = ConfigurationState.Instance.Hacks.TMNT_SRFix; + [ObservableProperty] private bool _TmntSrCutsceneCrashFix = ConfigurationState.Instance.Hacks.TmntSrCutsceneCrashFix; public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => { sb.AppendLine( @@ -40,14 +40,14 @@ namespace Ryujinx.Ava.UI.ViewModels sb.Append("Lets DOOM 2016 go in game."); }); - public static string TMNT_SRFixTooltip { get; } = Lambda.String(sb => + public static string TmntSrCutsceneCrashFixTooltip { get; } = Lambda.String(sb => { sb.AppendLine( - "This fix adds an extra 50 ms to some Ioctl service calls. This prevents the game from crashing when the cutscene starts.") + "This hack adds a 50ms delay to NvGpuAsMagic NvIoctl calls. This prevents the game from crashing when the cutscene starts.") .AppendLine(); sb.Append( - "Just give the game some time to properly interact with guest memory"); + "This simply just gives the game some time to properly interact with guest memory"); }); } } diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 4c920baa1..fab0e0b67 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -856,7 +856,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.Hacks.Xc2MenuSoftlockFix.Value = DirtyHacks.Xc2MenuSoftlockFix; config.Hacks.DisableNifmIsAnyInternetRequestAccepted.Value = DirtyHacks.NifmDisableIsAnyInternetRequestAccepted; - config.Hacks.TMNT_SRFix.Value = DirtyHacks.TMNT_SRFix; + config.Hacks.TmntSrCutsceneCrashFix.Value = DirtyHacks.TmntSrCutsceneCrashFix; config.ToFileFormat().SaveConfig(Program.ConfigurationPath); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml index 256ce7af9..0c123b73a 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsHacksView.axaml @@ -60,13 +60,13 @@ Margin="0,10,0,0" Orientation="Horizontal" HorizontalAlignment="Center" - ToolTip.Tip="{Binding DirtyHacks.TMNT_SRFixTooltip}"> + ToolTip.Tip="{Binding DirtyHacks.TmntSrCutsceneCrashFixTooltip}"> + IsChecked="{Binding DirtyHacks.TmntSrCutsceneCrashFix}"/> + Text="TMNT Shredder's Revenge Fix" /> From ea9baf8ea93e57ce65d55f8d9c4be46eb0138884 Mon Sep 17 00:00:00 2001 From: Vova Date: Tue, 2 Sep 2025 08:13:42 +1000 Subject: [PATCH 6/6] Variable is cast to _tmntSrCutsceneCrashFix in accordance with C# standards --- src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs index 46b297c7c..6087449c8 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsHacksViewModel.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Ava.UI.ViewModels [ObservableProperty] private bool _xc2MenuSoftlockFix = ConfigurationState.Instance.Hacks.Xc2MenuSoftlockFix; [ObservableProperty] private bool _nifmDisableIsAnyInternetRequestAccepted = ConfigurationState.Instance.Hacks.DisableNifmIsAnyInternetRequestAccepted; - [ObservableProperty] private bool _TmntSrCutsceneCrashFix = ConfigurationState.Instance.Hacks.TmntSrCutsceneCrashFix; + [ObservableProperty] private bool _tmntSrCutsceneCrashFix = ConfigurationState.Instance.Hacks.TmntSrCutsceneCrashFix; public static string Xc2MenuFixTooltip { get; } = Lambda.String(sb => { sb.AppendLine(