Compare commits

..

2 commits

Author SHA1 Message Date
GreemDev
61677eb9cb Merge branch 'fix/xcxde' into 'master'
Stub nn::ssl::sf::ISslServiceForSystem

See merge request ryubing/ryujinx!8
2025-03-20 07:56:18 +00:00
GreemDev
4777c7c8e9 Revert "HLE: Remove Ignore Missing Services"
This reverts commit 20b36ac8a2.
2025-03-20 02:51:33 -05:00
16 changed files with 167 additions and 17 deletions

View file

@ -265,13 +265,13 @@ namespace Ryujinx.HLE.HOS
HorizonFsClient fsClient = new(this);
ServiceTable = new ServiceTable();
IEnumerable<ServiceEntry> services = ServiceTable.GetServices(new HorizonOptions(
IEnumerable<ServiceEntry> services = ServiceTable.GetServices(new HorizonOptions
(Device.Configuration.IgnoreMissingServices,
LibHacHorizonManager.BcatClient,
fsClient,
AccountManager,
Device.AudioDeviceDriver,
TickSource
));
TickSource));
foreach (ServiceEntry service in services)
{

View file

@ -113,13 +113,27 @@ namespace Ryujinx.HLE.HOS.Services
bool serviceExists = service.CmifCommands.TryGetValue(commandId, out MethodInfo processRequest);
if (serviceExists)
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
{
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
Logger.Trace?.Print(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}");
ResultCode result = ResultCode.Success;
ResultCode result = (ResultCode)processRequest.Invoke(service, [context]);
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
if (serviceExists)
{
Logger.Trace?.Print(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}");
result = (ResultCode)processRequest.Invoke(service, [context]);
}
else
{
string serviceName;
serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
}
if (_isDomain)
{
@ -152,13 +166,27 @@ namespace Ryujinx.HLE.HOS.Services
bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest);
if (serviceExists)
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
{
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}");
ResultCode result = ResultCode.Success;
ResultCode result = (ResultCode)processRequest.Invoke(this, [context]);
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
if (serviceExists)
{
Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}");
result = (ResultCode)processRequest.Invoke(this, [context]);
}
else
{
string serviceName;
serviceName = (this is not DummyService dummyService) ? GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);

View file

@ -102,7 +102,14 @@ namespace Ryujinx.HLE.HOS.Services.Sm
}
else
{
throw new NotImplementedException(name);
if (context.Device.Configuration.IgnoreMissingServices)
{
Logger.Warning?.Print(LogClass.Service, $"Missing service {name} ignored");
}
else
{
throw new NotImplementedException(name);
}
}
if (context.Process.HandleTable.GenerateHandle(session.ClientSession, out int handle) != Result.Success)

View file

@ -137,6 +137,13 @@ namespace Ryujinx.HLE
/// </summary>
public MemoryManagerMode MemoryManagerMode { internal get; set; }
/// <summary>
/// Control the initial state of the ignore missing services setting.
/// If this is set to true, when a missing service is encountered, it will try to automatically handle it instead of throwing an exception.
/// </summary>
/// TODO: Update this again.
public bool IgnoreMissingServices { internal get; set; }
/// <summary>
/// Aspect Ratio applied to the renderer window by the SurfaceFlinger service.
/// </summary>
@ -200,6 +207,7 @@ namespace Ryujinx.HLE
long systemTimeOffset,
string timeZone,
MemoryManagerMode memoryManagerMode,
bool ignoreMissingServices,
AspectRatio aspectRatio,
float audioVolume,
bool useHypervisor,
@ -224,6 +232,7 @@ namespace Ryujinx.HLE
SystemTimeOffset = systemTimeOffset;
TimeZone = timeZone;
MemoryManagerMode = memoryManagerMode;
IgnoreMissingServices = ignoreMissingServices;
AspectRatio = aspectRatio;
AudioVolume = audioVolume;
UseHypervisor = useHypervisor;

View file

@ -8,6 +8,7 @@ namespace Ryujinx.Horizon
{
public readonly struct HorizonOptions
{
public bool IgnoreMissingServices { get; }
public bool ThrowOnInvalidCommandIds { get; }
public HorizonClient BcatClient { get; }
@ -17,12 +18,14 @@ namespace Ryujinx.Horizon
public ITickSource TickSource { get; }
public HorizonOptions(
bool ignoreMissingServices,
HorizonClient bcatClient,
IFsClient fsClient,
IEmulatorAccountManager accountManager,
IHardwareDeviceDriver audioDeviceDriver,
ITickSource tickSource)
{
IgnoreMissingServices = ignoreMissingServices;
ThrowOnInvalidCommandIds = true;
BcatClient = bcatClient;
FsClient = fsClient;

View file

@ -39,7 +39,18 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
if (!entries.TryGetValue((int)commandId, out CommandHandler commandHandler))
{
if (HorizonStatic.Options.ThrowOnInvalidCommandIds)
if (HorizonStatic.Options.IgnoreMissingServices)
{
// If ignore missing services is enabled, just pretend that everything is fine.
PrepareForStubReply(ref context, out Span<byte> outRawData);
CommandHandler.GetCmifOutHeaderPointer(ref outHeader, ref outRawData);
outHeader[0] = new CmifOutHeader { Magic = CmifMessage.CmifOutHeaderMagic, Result = Result.Success };
Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored");
return Result.Success;
}
else if (HorizonStatic.Options.ThrowOnInvalidCommandIds)
{
throw new NotImplementedException($"{objectName} command ID: {commandId} is not implemented");
}

View file

@ -5247,6 +5247,31 @@
"zh_TW": ""
}
},
{
"ID": "SettingsTabSystemIgnoreMissingServices",
"Translations": {
"ar_SA": "تجاهل الخدمات المفقودة",
"de_DE": "Ignoriere fehlende Dienste",
"el_GR": "Αγνόηση υπηρεσιών που λείπουν",
"en_US": "Ignore Missing Services",
"es_ES": "Ignorar servicios no implementados",
"fr_FR": "Ignorer les services manquants",
"he_IL": "התעלם משירותים חסרים",
"it_IT": "Ignora servizi mancanti",
"ja_JP": "未実装サービスを無視する",
"ko_KR": "누락된 서비스 무시",
"no_NO": "Ignorer manglende tjenester",
"pl_PL": "Ignoruj Brakujące Usługi",
"pt_BR": "Ignorar Serviços Ausentes",
"ru_RU": "Игнорировать отсутствующие службы",
"sv_SE": "Ignorera saknade tjänster",
"th_TH": "เมินเฉยบริการที่หายไป",
"tr_TR": "Eksik Servisleri Görmezden Gel",
"uk_UA": "Ігнорувати відсутні служби",
"zh_CN": "忽略缺失的服务",
"zh_TW": "忽略缺少的模擬器功能"
}
},
{
"ID": "SettingsTabSystemIgnoreControllerApplet",
"Translations": {
@ -16622,6 +16647,31 @@
"zh_TW": "利用另一種 MemoryMode 配置來模仿 Switch 開發模式。\n\n這僅對高解析度紋理套件或 4K 解析度模組有用。不會提高效能。\n\n如果不確定請設定為 4GiB。"
}
},
{
"ID": "IgnoreMissingServicesTooltip",
"Translations": {
"ar_SA": "يتجاهل خدمات نظام هوريزون غير المنفذة. قد يساعد هذا في تجاوز الأعطال عند تشغيل ألعاب معينة.\n\nاتركه معطلا إذا كنت غير متأكد.",
"de_DE": "Durch diese Option werden nicht implementierte Dienste der Switch-Firmware ignoriert. Dies kann dabei helfen, Abstürze beim Starten bestimmter Spiele zu umgehen.\n\nIm Zweifelsfall AUS lassen.",
"el_GR": "Ενεργοποίηση ή απενεργοποίηση της αγνοώησης για υπηρεσίες που λείπουν",
"en_US": "Ignores unimplemented Horizon OS services. This may help in bypassing crashes when booting certain games.\n\nLeave OFF if unsure.",
"es_ES": "Hack para ignorar servicios no implementados del Horizon OS. Esto puede ayudar a sobrepasar crasheos cuando inicies ciertos juegos.\n\nDesactívalo si no sabes qué hacer.",
"fr_FR": "Ignore les services Horizon OS non-intégrés. Cela peut aider à contourner les plantages lors du démarrage de certains jeux.\n\nLaissez désactivé en cas d'incertitude.",
"he_IL": "מתעלם מפעולות שלא קיבלו מימוש במערכת ההפעלה Horizon OS. זה עלול לעזור לעקוף קריסות של היישום במשחקים מסויימים.\n\nמוטב להשאיר כבוי אם לא בטוחים.",
"it_IT": "Ignora i servizi non implementati del sistema operativo Horizon. Può aiutare ad aggirare gli arresti anomali che si verificano avviando alcuni giochi.\n\nNel dubbio, lascia l'opzione disattivata.",
"ja_JP": "未実装の Horizon OS サービスを無視します. 特定のゲームにおいて起動時のクラッシュを回避できる場合があります.\n\nよくわからない場合はオフのままにしてください.",
"ko_KR": "구현되지 않은 Horizon OS 서비스는 무시됩니다. 특정 게임을 부팅할 때, 발생하는 충돌을 우회하는 데 도움이 될 수 있습니다.\n\n모르면 끔으로 두세요.",
"no_NO": "Ignorerer ikke implementerte Horisont OS-tjenester. Dette kan hjelpe med å omgå krasj ved oppstart av enkelte spill.\n\nLa AV hvis du er usikker.",
"pl_PL": "Ignoruje niezaimplementowane usługi Horizon OS. Może to pomóc w ominięciu awarii podczas uruchamiania niektórych gier.\n\nW razie wątpliwości pozostaw WYŁĄCZONE.",
"pt_BR": "Ignora serviços não implementados do Horizon OS. Isso pode ajudar a contornar travamentos ao inicializar certos jogos.\n\nDeixe OFF se não tiver certeza.",
"ru_RU": "Игнорирует нереализованные сервисы Horizon в новых прошивках. Эта настройка поможет избежать вылеты при запуске определенных игр.\n\nРекомендуется оставить выключенным.",
"sv_SE": "Ignorerar Horizon OS-tjänster som inte har implementerats. Detta kan avhjälpa krascher när vissa spel startar upp.\n\nLämna AV om du är osäker.",
"th_TH": "ละเว้นบริการ Horizon OS ที่ยังไม่ได้ใช้งาน วิธีนี้อาจช่วยในการหลีกเลี่ยงข้อผิดพลาดเมื่อบูตเกมบางเกม\n\nปล่อยให้ปิดหากคุณไม่แน่ใจ",
"tr_TR": "Henüz programlanmamış Horizon işletim sistemi servislerini görmezden gelir. Bu seçenek belirli oyunların açılırken çökmesinin önüne geçmeye yardımcı olabilir.\n\nEmin değilseniz devre dışı bırakın.",
"uk_UA": "Ігнорує нереалізовані служби Horizon OS. Це може допомогти в обході збоїв під час завантаження певних ігор.\n\nЗалиште вимкненим якщо не впевнені.",
"zh_CN": "开启后,游戏会忽略未实现的系统服务,从而继续运行。\n少部分新发布的游戏由于使用了新的未知系统服务可能需要此选项来避免闪退。\n模拟器更新完善系统服务之后则无需开启此选项。\n\n如果不确定请保持关闭状态。",
"zh_TW": "忽略未實現的 Horizon OS 服務。這可能有助於在啟動某些遊戲時避免崩潰。\n\n如果不確定請保持關閉狀態。"
}
},
{
"ID": "IgnoreControllerAppletTooltip",
"Translations": {

View file

@ -327,6 +327,7 @@ namespace Ryujinx.Headless
options.SystemTimeOffset,
options.SystemTimeZone,
options.MemoryManagerMode,
options.IgnoreMissingServices,
options.AspectRatio,
options.AudioVolume,
options.UseHypervisor ?? true,

View file

@ -145,6 +145,9 @@ namespace Ryujinx.Headless
if (NeedsOverride(nameof(DramSize)))
DramSize = configurationState.System.DramSize;
if (NeedsOverride(nameof(IgnoreMissingServices)))
IgnoreMissingServices = configurationState.System.IgnoreMissingServices;
if (NeedsOverride(nameof(IgnoreControllerApplet)))
IgnoreControllerApplet = configurationState.System.IgnoreControllerApplet;
@ -404,6 +407,9 @@ namespace Ryujinx.Headless
[Option("dram-size", Required = false, Default = MemoryConfiguration.MemoryConfiguration4GiB, HelpText = "Set the RAM amount on the emulated system.")]
public MemoryConfiguration DramSize { get; set; }
[Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")]
public bool IgnoreMissingServices { get; set; }
[Option("ignore-controller-applet", Required = false, Default = false, HelpText = "Enable ignoring the controller applet when your game loses connection to your controller.")]
public bool IgnoreControllerApplet { get; set; }

View file

@ -193,7 +193,8 @@ namespace Ryujinx.Ava.Systems
_invisibleCursorWin = CreateEmptyCursor();
_defaultCursorWin = CreateArrowCursor();
}
ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState;
ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState;
ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState;
ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
@ -486,6 +487,14 @@ namespace Ryujinx.Ava.Systems
Exit();
}
private void UpdateIgnoreMissingServicesState(object sender, ReactiveEventArgs<bool> args)
{
if (Device != null)
{
Device.Configuration.IgnoreMissingServices = args.NewValue;
}
}
private void UpdateAspectRatioState(object sender, ReactiveEventArgs<AspectRatio> args)
{
if (Device != null)
@ -599,7 +608,9 @@ namespace Ryujinx.Ava.Systems
{
if (Device.Processes != null)
MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText);
ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState;
ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState;
ConfigurationState.Instance.System.EnableDockedMode.Event -= UpdateDockedModeState;
ConfigurationState.Instance.System.AudioVolume.Event -= UpdateAudioVolumeState;

View file

@ -294,6 +294,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// </summary>
public MemoryConfiguration DramSize { get; set; }
/// <summary>
/// Enable or disable ignoring missing services
/// </summary>
public bool IgnoreMissingServices { get; set; }
/// <summary>
/// Used to toggle columns in the GUI
/// </summary>

View file

@ -100,6 +100,7 @@ namespace Ryujinx.Ava.Systems.Configuration
System.AudioVolume.Value = cff.AudioVolume;
System.MemoryManagerMode.Value = cff.MemoryManagerMode;
System.DramSize.Value = cff.DramSize;
System.IgnoreMissingServices.Value = cff.IgnoreMissingServices;
System.IgnoreControllerApplet.Value = cff.IgnoreApplet;
System.UseHypervisor.Value = cff.UseHypervisor;

View file

@ -379,6 +379,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// Defines the amount of RAM available on the emulated system, and how it is distributed
/// </summary>
public ReactiveObject<MemoryConfiguration> DramSize { get; private set; }
/// <summary>
/// Enable or disable ignoring missing services
/// </summary>
public ReactiveObject<bool> IgnoreMissingServices { get; private set; }
/// <summary>
/// Ignore Controller Applet
@ -422,6 +427,8 @@ namespace Ryujinx.Ava.Systems.Configuration
MemoryManagerMode.LogChangesToValue(nameof(MemoryManagerMode));
DramSize = new ReactiveObject<MemoryConfiguration>();
DramSize.LogChangesToValue(nameof(DramSize));
IgnoreMissingServices = new ReactiveObject<bool>();
IgnoreMissingServices.LogChangesToValue(nameof(IgnoreMissingServices));
IgnoreControllerApplet = new ReactiveObject<bool>();
IgnoreControllerApplet.LogChangesToValue(nameof(IgnoreControllerApplet));
AudioVolume = new ReactiveObject<float>();
@ -845,6 +852,7 @@ namespace Ryujinx.Ava.Systems.Configuration
: System.SystemTimeOffset,
System.TimeZone,
System.MemoryManagerMode,
System.IgnoreMissingServices,
Graphics.AspectRatio,
System.AudioVolume,
System.UseHypervisor,

View file

@ -79,6 +79,7 @@ namespace Ryujinx.Ava.Systems.Configuration
AudioVolume = System.AudioVolume,
MemoryManagerMode = System.MemoryManagerMode,
DramSize = System.DramSize,
IgnoreMissingServices = System.IgnoreMissingServices,
IgnoreApplet = System.IgnoreControllerApplet,
UseHypervisor = System.UseHypervisor,
GuiColumns = new GuiColumns
@ -202,6 +203,7 @@ namespace Ryujinx.Ava.Systems.Configuration
System.AudioVolume.Value = 1;
System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
System.DramSize.Value = MemoryConfiguration.MemoryConfiguration4GiB;
System.IgnoreMissingServices.Value = false;
System.IgnoreControllerApplet.Value = false;
System.UseHypervisor.Value = true;
Multiplayer.LanInterfaceId.Value = "0";

View file

@ -208,6 +208,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableLowPowerPptc { get; set; }
public bool EnableInternetAccess { get; set; }
public bool EnableFsIntegrityChecks { get; set; }
public bool IgnoreMissingServices { get; set; }
public MemoryConfiguration DramSize { get; set; }
public bool EnableShaderCache { get; set; }
public bool EnableTextureRecompression { get; set; }
@ -583,6 +584,7 @@ namespace Ryujinx.Ava.UI.ViewModels
VSyncMode = config.Graphics.VSyncMode;
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
DramSize = config.System.DramSize;
IgnoreMissingServices = config.System.IgnoreMissingServices;
IgnoreApplet = config.System.IgnoreControllerApplet;
// CPU
@ -684,6 +686,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
config.System.DramSize.Value = DramSize;
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
config.System.IgnoreControllerApplet.Value = IgnoreApplet;
// CPU

View file

@ -313,6 +313,11 @@
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical">
<CheckBox
IsChecked="{Binding IgnoreMissingServices}"
ToolTip.Tip="{ext:Locale IgnoreMissingServicesTooltip}">
<TextBlock Text="{ext:Locale SettingsTabSystemIgnoreMissingServices}" />
</CheckBox>
<CheckBox
IsChecked="{Binding IgnoreApplet}"
ToolTip.Tip="{ext:Locale IgnoreControllerAppletTooltip}">