Compare commits

...

10 commits

Author SHA1 Message Date
GreemDev
b4d596b976 Merge branch 'removal/ims' into 'master'
Make 'Ignore Missing Services' Debug-only

See merge request ryubing/ryujinx!16
2025-03-30 22:45:41 -05:00
Goodfeat
6602693477 feature: add the ability to skip profile select dialog when opening games that use it
the skip behavior is done by passing the user id of the profile you have selected in Options > Manage User Profiles.

See merge request ryubing/ryujinx!9
2025-03-30 22:29:57 -05:00
GreemDev
0a26f42dd1 Merge branch 'master' into removal/ims 2025-03-29 03:52:29 -05:00
GreemDev
c8f4861702 Merge branch 'master' into removal/ims 2025-03-29 02:39:59 -05:00
GreemDev
28526214ba misc: chore: Simplify usages of HLEConfiguration constructor 2025-03-29 02:37:01 -05:00
GreemDev
6a2116f71a Merge branch 'master' into removal/ims 2025-03-29 02:33:14 -05:00
GreemDev
68aee26c89 Merge branch 'master' into removal/ims 2025-03-24 21:47:51 -05:00
GreemDev
96ed38a9ea Merge branch 'master' into removal/ims 2025-03-24 18:13:31 -05:00
GreemDev
1ece186254 Log ims in switch ctor instead of apphost so all initializers get the same behavior 2025-03-21 04:26:41 +00:00
GreemDev
1e7e4322b4 Remove Ignore Missing Services from the release, and restrict it to Debug builds only. 2025-03-21 04:26:41 +00:00
19 changed files with 234 additions and 127 deletions

View file

@ -5322,31 +5322,6 @@
"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": {
@ -5372,6 +5347,31 @@
"zh_TW": "忽略控制器小程式"
}
},
{
"ID": "SettingsTabSystemSkipUserProfilesManager",
"Translations": {
"ar_SA": "تخطي مربع حوار 'إدارة الملفات الشخصية للمستخدم'",
"de_DE": "Überspringen des Dialogs 'Benutzerprofile verwalten'",
"el_GR": "Παράκαμψη διαλόγου 'Διαχείριση Προφίλ _Χρηστών'",
"en_US": "Skip dialog 'Manage User Profiles'",
"es_ES": "Omitir el diálogo 'Gestionar perfiles de usuario'",
"fr_FR": "Ignorer le dialogue 'Gérer les profils d'utilisateurs'",
"he_IL": "דילוג על הדיאלוג 'נהל פרופילי משתמש'",
"it_IT": "Salta la finestra di dialogo 'Gestisci i profili utente'",
"ja_JP": "「ユーザプロファイルを管理」ダイアログをスキップ",
"ko_KR": "'사용자 프로필 관리' 대화 상자 건너뛰기",
"no_NO": "Hopp over dialogen 'Administrere Brukerprofiler'",
"pl_PL": "Pomiń okno dialogowe 'Zarządzaj profilami użytkowników'",
"pt_BR": "Ignorar a caixa de diálogo 'Gerenciar Perfis de Usuário'",
"ru_RU": "Пропустить диалог 'Менеджер учётных записей'",
"sv_SE": "Hoppa över dialogen 'Hantera användarprofiler'",
"th_TH": "ข้ามหน้าต่างโต้ตอบ 'จัดการโปรไฟล์ผู้ใช้งาน'",
"tr_TR": "'Kullanıcı Profillerini Yönet' iletişim kutusunu atla",
"uk_UA": "Пропустити діалог 'Керувати профілями користувачів'",
"zh_CN": "跳过对话框“管理用户账户”",
"zh_TW": "略過對話框「管理使用者設定檔」"
}
},
{
"ID": "SettingsTabGraphics",
"Translations": {
@ -16722,31 +16722,6 @@
"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": {
@ -16772,6 +16747,31 @@
"zh_TW": "在模擬應用程式時如果遊戲手柄中斷連線則不會顯示控制器小程式。\n\n如果不確定請保持關閉狀態。"
}
},
{
"ID": "SkipUserProfilesTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "Diese Option überspringt den Dialog 'Benutzerprofile verwalten' während des Spiels und verwendet ein voreingestelltes Profil.\n\nDie Profilumschaltung finden Sie unter 'Einstellungen' - 'Benutzerprofile verwalten'. Wählen Sie das gewünschte Profil aus, bevor Sie das Spiel laden.",
"el_GR": "Αυτή η επιλογή παρακάμπτει το παράθυρο διαλόγου 'Διαχειριστής Προφίλ Χρήστη' κατά τη διάρκεια του παιχνιδιού, χρησιμοποιώντας ένα προεπιλεγμένο προφίλ.\n\nΗ εναλλαγή προφίλ βρίσκεται στις 'Ρυθμίσεις' - 'Διαχειριστής Προφίλ Χρήστη'. Επιλέξτε το επιθυμητό προφίλ πριν φορτώσετε το παιχνίδι.",
"en_US": "This option skips the 'Manage User Profiles' dialog during gameplay, using a pre-selected profile.\n\nProfile switching is found in 'Settings' - 'Manager User Profiles'. Select the desired profile before loading the game.",
"es_ES": "Esta opción omite el diálogo de 'Gestionar perfiles de usuario' durante el juego, utilizando un perfil preseleccionado.\n\nEl cambio de perfil se encuentra en 'Configuración' - 'Gestionar perfiles de usuario'. Seleccione el perfil deseado antes de cargar el juego.",
"fr_FR": "Cette option permet d'éviter le dialogue du 'Gérer les profils d'utilisateurs' pendant le jeu, en utilisant un profil pré-sélectionné.\n\nLa sélection du profil se trouve dans 'Paramètres' - 'Gérer les profils d'utilisateurs'. Sélectionnez le profil souhaité avant de charger la partie.",
"he_IL": "",
"it_IT": "Questa opzione salta la finestra di dialogo 'Gestisci i profili utente' durante il gioco, utilizzando un profilo pre-selezionato.\n\nIl cambio del profilo si trova in 'Impostazioni' - 'Gestisci i profili utente'. Seleziona il profilo desiderato prima di caricare il gioco.",
"ja_JP": "このオプションは、ゲームプレイ中に「ユーザプロファイルを管理」ダイアログをスキップし、事前に選択されたプロファイルを使用します。\n\nプロファイルの切り替えは、「設定」-「ユーザプロファイルを管理」で見つけることができます。ゲームのロード前に目的のプロファイルをを選択してください。",
"ko_KR": "이 옵션은 게임 플레이 중 '사용자 프로필 관리' 대화 상자를 건너뛰고, 미리 선택된 프로필을 사용합니다.\n\n프로필 전환은 '설정' - '사용자 프로필 관리'에서 찾을 수 있습니다. 게임 로드 전에 원하는 프로필을 선택하세요.",
"no_NO": "Dette alternativet hopper over dialogen 'Administrere Brukerprofiler' under spilling, og bruker en forhåndsvalgt profil.\n\nProfilbytte finnes i 'Innstillinger' - 'Administrer Brukerprofiler'. Velg ønsket profil før du laster spillet.",
"pl_PL": "Ta opcja pomija okno dialogowe 'Zarządzaj profilami użytkowników' podczas gry, używając wcześniej wybrany profil.\n\nPrzełączanie profili można znaleźć w 'Ustawienia' - 'Zarządzaj Profilami Użytkowników'. Wybierz żądany profil przed załadowaniem gry.",
"pt_BR": "Esta opção ignora a caixa de diálogo 'Gerenciar Perfis de Usuário' durante o jogo, usando um perfil pré-selecionado.\n\nO gerenciamento de perfis pode ser encontrado em 'Configurações' - 'Gerenciar Perfis de Usuários'. Selecione o perfil desejado antes de carregar o jogo.",
"ru_RU": "Эта опция пропускает диалоговое окно 'Менеджер учётных записей' во время игры, используя предварительно выбранный профиль.\n\nПереключение профилей можно найти в 'Параметры' - 'Менеджер учётных записей'. Выберите желаемый профиль перед загрузкой игры.",
"sv_SE": "Det här alternativet hoppar över dialogrutan 'Hantera användarprofiler' under spelet och använder en förvald profil.\n\nProfilväxling finns i 'Inställningar' - 'Hantera användarprofiler'. Välj önskad profil innan du laddar spelet.",
"th_TH": "ตัวเลือกนี้จะข้ามหน้าต่าง 'จัดการโปรไฟล์ผู้ใช้งาน' ระหว่างเล่นเกม โดยใช้โปรไฟล์ที่เลือกไว้ล่วงหน้า\n\nการสลับโปรไฟล์สามารถพบได้ใน 'ตั้งค่า' - 'จัดการโปรไฟล์ผู้ใช้งาน' เลือกโปรไฟล์ที่คุณต้องการก่อนโหลดเกม",
"tr_TR": "Bu seçenek, oyun sırasında 'Kullanıcı Profillerini Yönet' iletişim kutusunu atlar ve önceden seçilmiş bir profil kullanır.\n\nProfil değiştirme 'Seçenekler' - 'Kullanıcı Profillerini Yönet' bölümünde bulunur. Oyunu yüklemeden önce istediğiniz profili seçin.",
"uk_UA": "Ця опція пропускає діалогове вікно 'Керувати профілями користувачів' під час гри, використовуючи попередньо вибраний профіль.\n\nПеремикання профілів можна знайти в 'Налаштування' - 'Керувати профілями користувачів'. Виберіть потрібний профіль перед завантаженням гри.",
"zh_CN": "此选项跳过游戏过程中的“管理用户账户”对话框,使用预选的配置。\n\n可以在“设置” - “管理用户账户”中找到配置文件切换。 在加载游戏之前选择所需的配置文件。",
"zh_TW": "這個選項跳過遊戲過程中的「管理使用者設定檔」對話框,使用預先選取的設定。\n\n可以在「設定」-「管理使用者設定檔」中找到設定檔切換。 在載入遊戲前選擇您需要的設定檔。"
}
},
{
"ID": "GraphicsBackendThreadingTooltip",
"Translations": {

View file

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

View file

@ -135,7 +135,8 @@ namespace Ryujinx.HLE.HOS.Services
int commandId = (int)context.RequestData.ReadInt64();
bool serviceExists = service.CmifCommands.TryGetValue(commandId, out MethodInfo processRequest);
#if DEBUG
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
{
ResultCode result = ResultCode.Success;
@ -178,6 +179,39 @@ namespace Ryujinx.HLE.HOS.Services
throw new ServiceNotImplementedException(service, context, dbgMessage);
}
#else
if (serviceExists)
{
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
Logger.Trace?.Print(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}");
ResultCode result = (ResultCode)processRequest.Invoke(service, [context]);
if (_isDomain)
{
foreach (int id in context.Response.ObjectIds)
{
context.ResponseData.Write(id);
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write(context.Response.ObjectIds.Count);
}
context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin);
context.ResponseData.Write(IpcMagic.Sfco);
context.ResponseData.Write((long)result);
}
else
{
string dbgMessage = $"{service.GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(service, context, dbgMessage);
}
#endif
}
public void CallTipcMethod(ServiceCtx context)
@ -186,6 +220,7 @@ namespace Ryujinx.HLE.HOS.Services
bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest);
#if DEBUG
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
{
ResultCode result = ResultCode.Success;
@ -218,6 +253,26 @@ namespace Ryujinx.HLE.HOS.Services
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
#else
if (serviceExists)
{
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}");
ResultCode result = (ResultCode)processRequest.Invoke(this, [context]);
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write((uint)result);
}
else
{
string dbgMessage = $"{GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
#endif
}
protected void MakeObject(ServiceCtx context, IpcService obj)

View file

@ -102,11 +102,13 @@ namespace Ryujinx.HLE.HOS.Services.Sm
}
else
{
#if DEBUG
if (context.Device.Configuration.IgnoreMissingServices)
{
Logger.Warning?.Print(LogClass.Service, $"Missing service {name} ignored");
}
else
#endif
{
throw new NotImplementedException(name);
}

View file

@ -142,12 +142,14 @@ namespace Ryujinx.HLE
/// </summary>
public MemoryManagerMode MemoryManagerMode { internal get; set; }
#if DEBUG
/// <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; }
public bool IgnoreMissingServices { get; set; }
#endif
/// <summary>
/// Aspect Ratio applied to the renderer window by the SurfaceFlinger service.
@ -213,7 +215,9 @@ namespace Ryujinx.HLE
long systemTimeOffset,
string timeZone,
MemoryManagerMode memoryManagerMode,
#if DEBUG
bool ignoreMissingServices,
#endif
AspectRatio aspectRatio,
float audioVolume,
bool useHypervisor,
@ -239,7 +243,9 @@ namespace Ryujinx.HLE
SystemTimeOffset = systemTimeOffset;
TimeZone = timeZone;
MemoryManagerMode = memoryManagerMode;
#if DEBUG
IgnoreMissingServices = ignoreMissingServices;
#endif
AspectRatio = aspectRatio;
AudioVolume = audioVolume;
UseHypervisor = useHypervisor;

View file

@ -4,6 +4,7 @@ using Ryujinx.Audio.Backends.CompatLayer;
using Ryujinx.Audio.Integration;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.FileSystem;
@ -93,6 +94,11 @@ namespace Ryujinx.HLE
UpdateVSyncInterval();
#pragma warning restore IDE0055
#if DEBUG
if (Configuration.IgnoreMissingServices)
Logger.Notice.Print(LogClass.Emulation, "Ignore Missing Services is enabled.", nameof(Switch));
#endif
Shared = this;
}

View file

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

View file

@ -39,6 +39,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
if (!entries.TryGetValue((int)commandId, out CommandHandler commandHandler))
{
#if DEBUG
if (HorizonStatic.Options.IgnoreMissingServices)
{
// If ignore missing services is enabled, just pretend that everything is fine.
@ -49,8 +50,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored");
return Result.Success;
}
else if (HorizonStatic.Options.ThrowOnInvalidCommandIds)
}
#endif
if (HorizonStatic.Options.ThrowOnInvalidCommandIds)
{
throw new NotImplementedException($"{objectName} command ID: {commandId} is not implemented");
}

View file

@ -312,34 +312,37 @@ namespace Ryujinx.Headless
return new OpenGLRenderer();
}
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) =>
new(
new HleConfiguration(
options.DramSize,
options.SystemLanguage,
options.SystemRegion,
options.VSyncMode,
!options.DisableDockedMode,
!options.DisablePTC,
ITickSource.RealityTickScalar,
options.EnableInternetAccess,
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
options.FsGlobalAccessLogMode,
options.SystemTimeOffset,
options.SystemTimeZone,
options.MemoryManagerMode,
options.IgnoreMissingServices,
options.AspectRatio,
options.AudioVolume,
options.UseHypervisor ?? true,
options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
false,
string.Empty,
string.Empty,
options.CustomVSyncInterval
)
options.DramSize,
options.SystemLanguage,
options.SystemRegion,
options.VSyncMode,
!options.DisableDockedMode,
!options.DisablePTC,
ITickSource.RealityTickScalar,
options.EnableInternetAccess,
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
options.FsGlobalAccessLogMode,
options.SystemTimeOffset,
options.SystemTimeZone,
options.MemoryManagerMode,
#if DEBUG
options.IgnoreMissingServices,
#endif
options.AspectRatio,
options.AudioVolume,
options.UseHypervisor ?? true,
options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
false,
string.Empty,
string.Empty,
options.CustomVSyncInterval
)
.Configure(
_virtualFileSystem,
_libHacHorizonManager,

View file

@ -145,12 +145,12 @@ 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;
if (NeedsOverride(nameof(SkipUserProfilesManager)))
SkipUserProfilesManager = configurationState.System.SkipUserProfilesManager;
return;
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
@ -408,12 +408,17 @@ 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; }
#if DEBUG
[Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")]
public bool IgnoreMissingServices { get; set; }
#endif
[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; }
[Option("skip-user-profiles-manager", Required = false, Default = false, HelpText = "Enable skips the Profiles Manager popup during gameplay. Select the desired profile before starting the game")]
public bool SkipUserProfilesManager { get; set; }
// Values
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]

View file

@ -195,7 +195,6 @@ namespace Ryujinx.Ava.Systems
_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;
@ -488,14 +487,6 @@ 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)
@ -609,9 +600,7 @@ 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

@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Systems.Configuration
/// <summary>
/// The current version of the file format
/// </summary>
public const int CurrentVersion = 68;
public const int CurrentVersion = 69;
/// <summary>
/// Version of the configuration file format
@ -187,6 +187,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// </summary>
public bool IgnoreApplet { get; set; }
/// <summary>
/// Skip user profiles manager dialog during gameplay(the used profile in the configuration will be selected)
/// </summary>
public bool SkipUserProfiles { get; set; }
/// <summary>
/// Enables or disables save window size, position and state on close.
/// </summary>
@ -299,11 +304,6 @@ 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

@ -101,8 +101,8 @@ 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.SkipUserProfilesManager.Value = cff.SkipUserProfiles;
System.UseHypervisor.Value = cff.UseHypervisor;
UI.GuiColumns.FavColumn.Value = shouldLoadFromFile ? cff.GuiColumns.FavColumn : UI.GuiColumns.FavColumn.Value;
@ -459,7 +459,8 @@ namespace Ryujinx.Ava.Systems.Configuration
TurboMode = Key.Unbound,
TurboModeWhileHeld = false
};
})
}),
(69, static cff => cff.SkipUserProfiles = false)
);
}
}

View file

@ -3,6 +3,7 @@ using Gommon;
using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI;
using Ryujinx.Ava.Utilities;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
@ -384,17 +385,17 @@ 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
/// </summary>
public ReactiveObject<bool> IgnoreControllerApplet { get; private set; }
/// <summary>
/// Skip User Profiles Manager
/// </summary>
public ReactiveObject<bool> SkipUserProfilesManager { get; private set; }
/// <summary>
/// Uses Hypervisor over JIT if available
/// </summary>
@ -441,10 +442,10 @@ 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));
SkipUserProfilesManager = new ReactiveObject<bool>();
SkipUserProfilesManager.LogChangesToValue(nameof(SkipUserProfilesManager));
AudioVolume = new ReactiveObject<float>();
AudioVolume.LogChangesToValue(nameof(AudioVolume));
UseHypervisor = new ReactiveObject<bool>();
@ -867,7 +868,9 @@ namespace Ryujinx.Ava.Systems.Configuration
: System.SystemTimeOffset,
System.TimeZone,
System.MemoryManagerMode,
System.IgnoreMissingServices,
#if DEBUG
CommandLineState.IgnoreMissingServices,
#endif
Graphics.AspectRatio,
System.AudioVolume,
System.UseHypervisor,
@ -875,8 +878,8 @@ namespace Ryujinx.Ava.Systems.Configuration
Multiplayer.Mode,
Multiplayer.DisableP2p,
Multiplayer.LdnPassphrase,
Multiplayer.GetLdnServer(),
Graphics.CustomVSyncInterval,
Hacks.ShowDirtyHacks ? Hacks.EnabledHacks : null);
Instance.Multiplayer.GetLdnServer(),
Instance.Graphics.CustomVSyncInterval,
Instance.Hacks.ShowDirtyHacks ? Instance.Hacks.EnabledHacks : null);
}
}

View file

@ -80,8 +80,8 @@ namespace Ryujinx.Ava.Systems.Configuration
AudioVolume = System.AudioVolume,
MemoryManagerMode = System.MemoryManagerMode,
DramSize = System.DramSize,
IgnoreMissingServices = System.IgnoreMissingServices,
IgnoreApplet = System.IgnoreControllerApplet,
SkipUserProfiles = System.SkipUserProfilesManager,
UseHypervisor = System.UseHypervisor,
GuiColumns = new GuiColumns
{
@ -204,8 +204,8 @@ 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.SkipUserProfilesManager.Value = false;
System.UseHypervisor.Value = true;
Multiplayer.LanInterfaceId.Value = "0";
Multiplayer.Mode.Value = MultiplayerMode.Disabled;

View file

@ -3,6 +3,7 @@ using Avalonia.Controls;
using Avalonia.Input;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
@ -78,6 +79,13 @@ namespace Ryujinx.Ava.UI.Applet
public static async Task<(UserId Id, bool Result)> ShowInputDialog(ProfileSelectorDialogViewModel viewModel)
{
if (ConfigurationState.Instance.System.SkipUserProfilesManager)
{
UserId defaultId = viewModel.SelectedUserId;
return (defaultId, true);
}
ContentDialog contentDialog = new()
{
Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],

View file

@ -133,6 +133,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDiscordIntegration { get; set; }
public bool ShowConfirmExit { get; set; }
public bool IgnoreApplet { get; set; }
public bool SkipUserProfiles { get; set; }
public bool RememberWindowState { get; set; }
public bool ShowOldUI { get; set; }
public int HideCursor { get; set; }
@ -228,7 +229,6 @@ namespace Ryujinx.Ava.UI.ViewModels
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; }
@ -604,8 +604,8 @@ 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;
SkipUserProfiles = config.System.SkipUserProfilesManager;
// CPU
EnablePptc = config.System.EnablePtc;
@ -707,8 +707,8 @@ 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;
config.System.SkipUserProfilesManager.Value = SkipUserProfiles;
// CPU
config.System.EnablePtc.Value = EnablePptc;

View file

@ -313,11 +313,6 @@
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}">
@ -328,6 +323,11 @@
ToolTip.Tip="{ext:Locale SettingsTabSystemEnableCustomVSyncIntervalTooltip}">
<TextBlock Text="{ext:Locale SettingsTabSystemEnableCustomVSyncInterval}" />
</CheckBox>
<CheckBox
IsChecked="{Binding SkipUserProfiles}"
ToolTip.Tip="{ext:Locale SkipUserProfilesTooltip}">
<TextBlock Text="{ext:Locale SettingsTabSystemSkipUserProfilesManager}" />
</CheckBox>
</StackPanel>
</StackPanel>
</Border>

View file

@ -26,6 +26,9 @@ namespace Ryujinx.Ava.Utilities
public static bool StartFullscreenArg { get; private set; }
public static bool HideAvailableUpdates { get; private set; }
#if DEBUG
public static bool IgnoreMissingServices { get; private set; }
#endif
public static void ParseArguments(string[] args)
{
@ -185,6 +188,11 @@ namespace Ryujinx.Ava.Utilities
case "--hide-updates":
HideAvailableUpdates = true;
break;
#if DEBUG
case "--ignore-missing-services":
IgnoreMissingServices = true;
break;
#endif
case "--software-gui":
OverrideHardwareAcceleration = false;
break;