From 91f73a48915453dc1aa84debc4808f40eb7ca6f4 Mon Sep 17 00:00:00 2001 From: Daniel Nylander Date: Fri, 14 Feb 2025 02:28:39 +0100 Subject: [PATCH 01/13] Updated Swedish translation (#594) --- src/Ryujinx/Assets/locales.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index dda498c59..9d8569501 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -589,7 +589,7 @@ "pl_PL": "", "pt_BR": "Iniciar jogos ocultando a interface", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Starta spel med dolt användargränssnitt", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -2614,7 +2614,7 @@ "pl_PL": "", "pt_BR": "Extraia o RomFS de um arquivo DLC selecionado", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Extrahera RomFS från en vald DLC-fil", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -4621,7 +4621,7 @@ "zh_CN": "繁体中文(推荐)", "zh_TW": "正體中文 (建議)" } - }, + }, { "ID": "SettingsTabSystemSystemLanguageSwedish", "Translations": { @@ -4646,7 +4646,7 @@ "zh_CN": "瑞典语", "zh_TW": "" } - }, + }, { "ID": "SettingsTabSystemSystemLanguageNorwegian", "Translations": { @@ -6464,7 +6464,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Ok", "th_TH": "ตกลง", "tr_TR": "Tamam", "uk_UA": "", @@ -8364,7 +8364,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Inaktivera", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8389,7 +8389,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Regnbåge", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -8439,7 +8439,7 @@ "pl_PL": "", "pt_BR": "", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Färg", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -15239,7 +15239,7 @@ "pl_PL": "Seria Amiibo", "pt_BR": "Franquia Amiibo", "ru_RU": "Серия Amiibo", - "sv_SE": "", + "sv_SE": "Amiibo-serie", "th_TH": "", "tr_TR": "Amiibo Serisi", "uk_UA": "Серія Amiibo", @@ -18664,7 +18664,7 @@ "pl_PL": "", "pt_BR": "{0} - Informação", "ru_RU": "{0} - Информация", - "sv_SE": "", + "sv_SE": "{0} - Information", "th_TH": "{0} – ข้อมูล", "tr_TR": "{0} - Bilgi", "uk_UA": "{0} - Інформація", @@ -19739,7 +19739,7 @@ "pl_PL": "", "pt_BR": "Configurações de LED", "ru_RU": "", - "sv_SE": "", + "sv_SE": "LED-inställningar", "th_TH": "", "tr_TR": "", "uk_UA": "", @@ -21939,7 +21939,7 @@ "pl_PL": "Głoś", "pt_BR": "", "ru_RU": "Громкость", - "sv_SE": "", + "sv_SE": "Volym", "th_TH": "ระดับเสียง", "tr_TR": "Ses", "uk_UA": "Гуч.", @@ -24014,7 +24014,7 @@ "pl_PL": "", "pt_BR": "Selecione um DLC para extrair", "ru_RU": "", - "sv_SE": "", + "sv_SE": "Välj en DLC att extrahera", "th_TH": "", "tr_TR": "", "uk_UA": "", From 6b55d158b7cb2e3e30c238897b65b4d18dfd6982 Mon Sep 17 00:00:00 2001 From: Daenorth Date: Fri, 14 Feb 2025 05:38:55 +0100 Subject: [PATCH 02/13] Norwegian locale update & update Jackbox 5 & 6 compat (#658) --- docs/compatibility.csv | 4 +- src/Ryujinx/Assets/locales.json | 84 ++++++++++++++++----------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/docs/compatibility.csv b/docs/compatibility.csv index 6cb10e8d8..7653ced9e 100644 --- a/docs/compatibility.csv +++ b/docs/compatibility.csv @@ -2988,8 +2988,8 @@ 010015D003EE4000,"The Jackbox Party Pack 2",online-working,playable,2022-08-22 18:23:40 0100CC80013D6000,"The Jackbox Party Pack 3",slow;online-working,playable,2022-08-22 18:41:06 0100E1F003EE8000,"The Jackbox Party Pack 4",online-working,playable,2022-08-22 18:56:34 -01006fe0096ac000,"The Jackbox Party Pack 5",ldn-untested,boots,2025-02-03 22:32:00 -01005a400db52000,"The Jackbox Party Pack 6",ldn-untested,boots,2025-02-03 22:32:00 +01006fe0096ac000,"The Jackbox Party Pack 5",slow;online-working,ingame,2025-02-14 05:32:00 +01005a400db52000,"The Jackbox Party Pack 6",slow;online-working,ingame,2025-02-14 05:26:00 010052C00B184000,"The Journey Down: Chapter One",nvdec,playable,2021-02-24 13:32:41 01006BC00B188000,"The Journey Down: Chapter Three",nvdec,playable,2021-02-24 13:45:27 01009AB00B186000,"The Journey Down: Chapter Two",nvdec,playable,2021-02-24 13:32:13 diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 9d8569501..684051368 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -585,7 +585,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "UI를 숨긴 상태에서 게임 시작", - "no_NO": "", + "no_NO": "Start Spillet med UI Gjemt", "pl_PL": "", "pt_BR": "Iniciar jogos ocultando a interface", "ru_RU": "", @@ -1535,7 +1535,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Utviklet av {0}", "pl_PL": "", "pt_BR": "Desenvolvido por {0}", "ru_RU": "", @@ -1835,7 +1835,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Kompatibilitet", "pl_PL": "", "pt_BR": "Compatibilidade:", "ru_RU": "", @@ -1860,7 +1860,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Tittel ID:", "pl_PL": "", "pt_BR": "ID do título:", "ru_RU": "", @@ -1885,7 +1885,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Spill som Arrangeres: {0}", "pl_PL": "", "pt_BR": "Jogos hospedados: {0}", "ru_RU": "", @@ -1910,7 +1910,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Online-spillere: {0}", "pl_PL": "", "pt_BR": "Jogadores Online: {0}", "ru_RU": "", @@ -2260,7 +2260,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "PPTC 캐시 제거", - "no_NO": "", + "no_NO": "Tøm PPTC-bufferen", "pl_PL": "", "pt_BR": "Limpar cache PPTC", "ru_RU": "", @@ -2285,7 +2285,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "앱의 모든 PPTC 캐시 파일 삭제", - "no_NO": "", + "no_NO": "Sletter alle PPTC-cache-filer for applikasjonen", "pl_PL": "", "pt_BR": "Apagar os arquivos de cache PPTC do aplicativo", "ru_RU": "", @@ -2760,7 +2760,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "호환성 항목 표시", - "no_NO": "", + "no_NO": "Vis kompatibilitetsoppføring", "pl_PL": "", "pt_BR": "Mostrar entrada de compatibilidade", "ru_RU": "", @@ -2785,7 +2785,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "일반적으로 도움말 메뉴를 통해 접근할 수 있는 호환성 목록에 선택한 게임을 표시합니다.", - "no_NO": "", + "no_NO": "Vis det valgte spillet i kompatibilitetslisten, som du vanligvis får tilgang til via Hjelp-menyen.", "pl_PL": "", "pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.", "ru_RU": "", @@ -2810,7 +2810,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "게임 통계 표시", - "no_NO": "", + "no_NO": "Vis Spill Info", "pl_PL": "", "pt_BR": "Mostrar informações do jogo", "ru_RU": "", @@ -2835,7 +2835,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "그리드 보기 레이아웃에서 누락된 현재 선택된 게임에 대한 다양한 정보를 표시합니다.", - "no_NO": "", + "no_NO": "Vis statistikk og detaljer om det valgte spillet.", "pl_PL": "", "pt_BR": "Mostrar estatísticas e detalhes sobre o jogo selecionado no momento.", "ru_RU": "", @@ -3360,7 +3360,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Se etter Oppdateringer:", "pl_PL": "", "pt_BR": "Verificar atualizações:", "ru_RU": "", @@ -3385,7 +3385,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Av", "pl_PL": "", "pt_BR": "Desligado", "ru_RU": "", @@ -3410,7 +3410,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Spør", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -3435,7 +3435,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Bakgrunn", "pl_PL": "", "pt_BR": "Fundo", "ru_RU": "", @@ -3460,7 +3460,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "På Emulator Fokus Tapt:", "pl_PL": "", "pt_BR": "Ao perder o Foco do emulador:", "ru_RU": "", @@ -3485,7 +3485,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Gjør Ingenting", "pl_PL": "", "pt_BR": "Não fazer nada", "ru_RU": "", @@ -3510,7 +3510,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Blokkinngang", "pl_PL": "", "pt_BR": "Bloquear entrada", "ru_RU": "", @@ -3535,7 +3535,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Demp Lyd", "pl_PL": "", "pt_BR": "Ficar mudo", "ru_RU": "", @@ -3560,7 +3560,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Blokker Inputs og demp Volumet", "pl_PL": "", "pt_BR": "Bloquear entrada & Ficar mudo", "ru_RU": "", @@ -3585,7 +3585,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Pause Emulatoren", "pl_PL": "", "pt_BR": "Pausar a emulação", "ru_RU": "", @@ -4635,7 +4635,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "스웨덴어", - "no_NO": "", + "no_NO": "Svensk", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -4735,7 +4735,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "매치 시스템 시간", - "no_NO": "", + "no_NO": "Match systemtid", "pl_PL": "", "pt_BR": "Sincronizar data e hora com o sistema PC", "ru_RU": "", @@ -6010,7 +6010,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Aktivere UI-logger", "pl_PL": "", "pt_BR": "Habilitar logs da IU", "ru_RU": "", @@ -6410,7 +6410,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Tilbakestill innstillinger", "pl_PL": "", "pt_BR": "Redefinir configurações", "ru_RU": "", @@ -6435,7 +6435,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Jeg vil tilbakestille innstillingene mine.", "pl_PL": "", "pt_BR": "Quero redefinir minhas configurações.", "ru_RU": "", @@ -8360,7 +8360,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "비활성화", - "no_NO": "", + "no_NO": "Deaktiver", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -8385,7 +8385,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "레인보우", - "no_NO": "", + "no_NO": "Regnbue", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -8410,7 +8410,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "레인보우 속도", - "no_NO": "", + "no_NO": "Regnbue Hastighet", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -8435,7 +8435,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "색상", - "no_NO": "", + "no_NO": "Farge", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -13685,7 +13685,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "다음에서 모든 PPTC 데이터를 제거하려고 합니다:\n\n{0}\n\n계속하시겠습니까?", - "no_NO": "", + "no_NO": "Du er i ferd med å slette alle PPTC-data fra:\n\n{0}\n\n\nEr du sikker på at du vil fortsette?", "pl_PL": "", "pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?", "ru_RU": "", @@ -17010,7 +17010,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Skriver ut Avalonia (UI)-loggmeldinger i konsollen.", "pl_PL": "", "pt_BR": "Imprimir mensagens de log do Avalonia (IU) no console.", "ru_RU": "", @@ -17935,7 +17935,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Oppdatering tilgjengelig!", "pl_PL": "", "pt_BR": "Atualização disponível!", "ru_RU": "", @@ -19735,7 +19735,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "LED 설정", - "no_NO": "", + "no_NO": "LED-innstillinger", "pl_PL": "", "pt_BR": "Configurações de LED", "ru_RU": "", @@ -23885,7 +23885,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.", "pl_PL": "", "pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.", "ru_RU": "", @@ -23910,7 +23910,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.", "pl_PL": "", "pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.", "ru_RU": "", @@ -23935,7 +23935,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Starter opp og går forbi tittelskjermen, men kommer ikke inn i hovedspillet.", "pl_PL": "", "pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.", "ru_RU": "", @@ -23960,7 +23960,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Starter, men kommer ikke lenger enn til tittelskjermen.", "pl_PL": "", "pt_BR": "Inizializa, mas não passa da tela de título.", "ru_RU": "", @@ -23985,7 +23985,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.", "pl_PL": "", "pt_BR": "Não inicializa ou não mostra sinais de atividade.", "ru_RU": "", @@ -24035,7 +24035,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Rikt nærværsbilde", "pl_PL": "", "pt_BR": "", "ru_RU": "", @@ -24060,7 +24060,7 @@ "it_IT": "", "ja_JP": "", "ko_KR": "", - "no_NO": "", + "no_NO": "Dynamisk og rik tilstedeværelse", "pl_PL": "", "pt_BR": "", "ru_RU": "", From 855161b23b8d2d99893c5cb5f0f7c874b9978f2f Mon Sep 17 00:00:00 2001 From: FluffyOMC <45863583+FluffyOMC@users.noreply.github.com> Date: Fri, 14 Feb 2025 22:37:19 -0500 Subject: [PATCH 03/13] Prevent log from showing negative JIT cache sizes (32bit-int overflow) (#664) ![image](https://github.com/user-attachments/assets/5820ce7b-cbfe-4908-8f5e-7ee82040ee1a) --- src/ARMeilleure/Translation/Cache/JitCache.cs | 2 +- src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs | 2 +- src/Ryujinx/Assets/locales.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ARMeilleure/Translation/Cache/JitCache.cs b/src/ARMeilleure/Translation/Cache/JitCache.cs index bc75e7d3f..5871b5308 100644 --- a/src/ARMeilleure/Translation/Cache/JitCache.cs +++ b/src/ARMeilleure/Translation/Cache/JitCache.cs @@ -186,7 +186,7 @@ namespace ARMeilleure.Translation.Cache int newRegionNumber = _activeRegionIndex; - Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation)."); + Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation)."); _cacheAllocator = new CacheMemoryAllocator(CacheSize); diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs index ccf8ad964..1d79ed0b5 100644 --- a/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs +++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs @@ -166,7 +166,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache int newRegionNumber = _activeRegionIndex; - Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation)."); + Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation)."); _cacheAllocator = new CacheMemoryAllocator(CacheSize); diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 684051368..c6f474577 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -4621,7 +4621,7 @@ "zh_CN": "繁体中文(推荐)", "zh_TW": "正體中文 (建議)" } - }, + }, { "ID": "SettingsTabSystemSystemLanguageSwedish", "Translations": { @@ -4646,7 +4646,7 @@ "zh_CN": "瑞典语", "zh_TW": "" } - }, + }, { "ID": "SettingsTabSystemSystemLanguageNorwegian", "Translations": { @@ -24073,4 +24073,4 @@ } } ] -} +} \ No newline at end of file From 0965ee905d7b7d421f9334fc679fd64519c236ab Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Fri, 14 Feb 2025 22:18:04 -0600 Subject: [PATCH 04/13] misc: Fix Match System Time not persisting between emulator launches --- .../Utilities/Configuration/ConfigurationState.Migration.cs | 1 + src/Ryujinx/Utilities/Configuration/ConfigurationState.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs index 6bca36340..bf1e24ed8 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs @@ -88,6 +88,7 @@ namespace Ryujinx.Ava.Utilities.Configuration System.Region.Value = cff.SystemRegion; System.TimeZone.Value = cff.SystemTimeZone; System.SystemTimeOffset.Value = cff.SystemTimeOffset; + System.MatchSystemTime.Value = cff.MatchSystemTime; System.EnableDockedMode.Value = cff.DockedMode; System.EnablePtc.Value = cff.EnablePtc; System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc; diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index 774b9217e..d810888a1 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -53,6 +53,7 @@ namespace Ryujinx.Ava.Utilities.Configuration SystemRegion = System.Region, SystemTimeZone = System.TimeZone, SystemTimeOffset = System.SystemTimeOffset, + MatchSystemTime = System.MatchSystemTime, DockedMode = System.EnableDockedMode, EnableDiscordIntegration = EnableDiscordIntegration, CheckUpdatesOnStart = CheckUpdatesOnStart, From a4b5304935e87d9b7298cf4a3cc5e844020681bf Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 00:20:01 -0600 Subject: [PATCH 05/13] UI: Refresh game list when emulated Switch language is changed (to show different logos/names) --- .../UI/ViewModels/SettingsViewModel.cs | 23 +++++++------------ .../UI/Views/Settings/SettingsUIView.axaml.cs | 16 ++++--------- .../UI/Windows/SettingsWindow.axaml.cs | 2 +- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 1b1f8a2a5..812438932 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -49,8 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels private int _graphicsBackendMultithreadingIndex; private float _volume; [ObservableProperty] private bool _isVulkanAvailable = true; - [ObservableProperty] private bool _gameDirectoryChanged; - [ObservableProperty] private bool _autoloadDirectoryChanged; + [ObservableProperty] private bool _gameListNeedsRefresh; private readonly List _gpuIds = []; private int _graphicsBackendIndex; private int _scalingFilter; @@ -593,16 +592,8 @@ namespace Ryujinx.Ava.UI.ViewModels config.HideCursor.Value = (HideCursorMode)HideCursor; config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType; config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType; - - if (GameDirectoryChanged) - { - config.UI.GameDirs.Value = [..GameDirectories]; - } - - if (AutoloadDirectoryChanged) - { - config.UI.AutoloadDirs.Value = [..AutoloadDirectories]; - } + config.UI.GameDirs.Value = [..GameDirectories]; + config.UI.AutoloadDirs.Value = [..AutoloadDirectories]; config.UI.BaseStyle.Value = BaseStyleIndex switch { @@ -623,8 +614,11 @@ namespace Ryujinx.Ava.UI.ViewModels // System config.System.Region.Value = (Region)Region; + + if (config.System.Language.Value != (Language)Language) + GameListNeedsRefresh = true; + config.System.Language.Value = (Language)Language; - if (_validTzRegions.Contains(TimeZone)) { config.System.TimeZone.Value = TimeZone; @@ -715,8 +709,7 @@ namespace Ryujinx.Ava.UI.ViewModels SaveSettingsEvent?.Invoke(); - GameDirectoryChanged = false; - AutoloadDirectoryChanged = false; + GameListNeedsRefresh = false; } private static void RevertIfNotSaved() diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs index 22a4adf51..2b0e57cb5 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs @@ -36,11 +36,8 @@ namespace Ryujinx.Ava.UI.Views.Settings directories.Add(path); addDirBox.Clear(); - - if (isGameList) - ViewModel.GameDirectoryChanged = true; - else - ViewModel.AutoloadDirectoryChanged = true; + + ViewModel.GameListNeedsRefresh = true; } else { @@ -50,10 +47,7 @@ namespace Ryujinx.Ava.UI.Views.Settings { directories.Add(folder.Value.Path.LocalPath); - if (isGameList) - ViewModel.GameDirectoryChanged = true; - else - ViewModel.AutoloadDirectoryChanged = true; + ViewModel.GameListNeedsRefresh = true; } } } @@ -65,7 +59,7 @@ namespace Ryujinx.Ava.UI.Views.Settings foreach (string path in new List(GameDirsList.SelectedItems.Cast())) { ViewModel.GameDirectories.Remove(path); - ViewModel.GameDirectoryChanged = true; + ViewModel.GameListNeedsRefresh = true; } if (GameDirsList.ItemCount > 0) @@ -81,7 +75,7 @@ namespace Ryujinx.Ava.UI.Views.Settings foreach (string path in new List(AutoloadDirsList.SelectedItems.Cast())) { ViewModel.AutoloadDirectories.Remove(path); - ViewModel.AutoloadDirectoryChanged = true; + ViewModel.GameListNeedsRefresh = true; } if (AutoloadDirsList.ItemCount > 0) diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs index 36f451fe4..701c3ddaf 100644 --- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs @@ -45,7 +45,7 @@ namespace Ryujinx.Ava.UI.Windows { InputPage.InputView?.SaveCurrentProfile(); - if (Owner is MainWindow window && (ViewModel.GameDirectoryChanged || ViewModel.AutoloadDirectoryChanged)) + if (Owner is MainWindow window && ViewModel.GameListNeedsRefresh) { window.LoadApplications(); } From 7d59ada798ead183ffee96eb5f87cc92ebe6f4c5 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 00:25:28 -0600 Subject: [PATCH 06/13] misc: chore: rename IgnoreApplet to IgnoreControllerApplet --- src/Ryujinx/Headless/Options.cs | 2 +- src/Ryujinx/UI/Applet/AvaHostUIHandler.cs | 2 +- src/Ryujinx/UI/ViewModels/SettingsViewModel.cs | 4 ++-- .../Utilities/Configuration/ConfigurationFileFormat.cs | 2 +- .../Utilities/Configuration/ConfigurationState.Migration.cs | 2 +- .../Utilities/Configuration/ConfigurationState.Model.cs | 6 +++--- src/Ryujinx/Utilities/Configuration/ConfigurationState.cs | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Ryujinx/Headless/Options.cs b/src/Ryujinx/Headless/Options.cs index a57863d5d..6658ba3ad 100644 --- a/src/Ryujinx/Headless/Options.cs +++ b/src/Ryujinx/Headless/Options.cs @@ -148,7 +148,7 @@ namespace Ryujinx.Headless IgnoreMissingServices = configurationState.System.IgnoreMissingServices; if (NeedsOverride(nameof(IgnoreControllerApplet))) - IgnoreControllerApplet = configurationState.System.IgnoreApplet; + IgnoreControllerApplet = configurationState.System.IgnoreControllerApplet; return; diff --git a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs index c03c4c45f..c9bd08fa3 100644 --- a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs +++ b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs @@ -41,7 +41,7 @@ namespace Ryujinx.Ava.UI.Applet bool okPressed = false; - if (ConfigurationState.Instance.System.IgnoreApplet) + if (ConfigurationState.Instance.System.IgnoreControllerApplet) return false; Dispatcher.UIThread.InvokeAsync(async () => diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 812438932..fe71a7420 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -526,7 +526,7 @@ namespace Ryujinx.Ava.UI.ViewModels EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; DramSize = config.System.DramSize; IgnoreMissingServices = config.System.IgnoreMissingServices; - IgnoreApplet = config.System.IgnoreApplet; + IgnoreApplet = config.System.IgnoreControllerApplet; // CPU EnablePptc = config.System.EnablePtc; @@ -629,7 +629,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; config.System.DramSize.Value = DramSize; config.System.IgnoreMissingServices.Value = IgnoreMissingServices; - config.System.IgnoreApplet.Value = IgnoreApplet; + config.System.IgnoreControllerApplet.Value = IgnoreApplet; // CPU config.System.EnablePtc.Value = EnablePptc; diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs index 7d9a4accb..814a48e53 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs @@ -183,7 +183,7 @@ namespace Ryujinx.Ava.Utilities.Configuration public bool ShowConfirmExit { get; set; } /// - /// ignore "Applet" dialog + /// Ignore Controller Applet dialog /// public bool IgnoreApplet { get; set; } diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs index bf1e24ed8..e735c287b 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs @@ -100,7 +100,7 @@ namespace Ryujinx.Ava.Utilities.Configuration System.MemoryManagerMode.Value = cff.MemoryManagerMode; System.DramSize.Value = cff.DramSize; System.IgnoreMissingServices.Value = cff.IgnoreMissingServices; - System.IgnoreApplet.Value = cff.IgnoreApplet; + System.IgnoreControllerApplet.Value = cff.IgnoreApplet; System.UseHypervisor.Value = cff.UseHypervisor; UI.GuiColumns.FavColumn.Value = cff.GuiColumns.FavColumn; diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs index 51c40cc99..3f22c6c0f 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs @@ -383,7 +383,7 @@ namespace Ryujinx.Ava.Utilities.Configuration /// /// Ignore Controller Applet /// - public ReactiveObject IgnoreApplet { get; private set; } + public ReactiveObject IgnoreControllerApplet { get; private set; } /// /// Uses Hypervisor over JIT if available @@ -424,8 +424,8 @@ namespace Ryujinx.Ava.Utilities.Configuration DramSize.LogChangesToValue(nameof(DramSize)); IgnoreMissingServices = new ReactiveObject(); IgnoreMissingServices.LogChangesToValue(nameof(IgnoreMissingServices)); - IgnoreApplet = new ReactiveObject(); - IgnoreApplet.LogChangesToValue(nameof(IgnoreApplet)); + IgnoreControllerApplet = new ReactiveObject(); + IgnoreControllerApplet.LogChangesToValue(nameof(IgnoreControllerApplet)); AudioVolume = new ReactiveObject(); AudioVolume.LogChangesToValue(nameof(AudioVolume)); UseHypervisor = new ReactiveObject(); diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index d810888a1..02a91e51d 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -81,7 +81,7 @@ namespace Ryujinx.Ava.Utilities.Configuration MemoryManagerMode = System.MemoryManagerMode, DramSize = System.DramSize, IgnoreMissingServices = System.IgnoreMissingServices, - IgnoreApplet = System.IgnoreApplet, + IgnoreApplet = System.IgnoreControllerApplet, UseHypervisor = System.UseHypervisor, GuiColumns = new GuiColumns { @@ -205,7 +205,7 @@ namespace Ryujinx.Ava.Utilities.Configuration System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe; System.DramSize.Value = MemoryConfiguration.MemoryConfiguration4GiB; System.IgnoreMissingServices.Value = false; - System.IgnoreApplet.Value = false; + System.IgnoreControllerApplet.Value = false; System.UseHypervisor.Value = true; Multiplayer.LanInterfaceId.Value = "0"; Multiplayer.Mode.Value = MultiplayerMode.Disabled; From 744d813b87e1c8ca6ae5ea7906474ea818c048fa Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 00:40:18 -0600 Subject: [PATCH 07/13] misc: i18n: change localization of Ignore Applet to Ignore Controller Applet & redo tooltip --- src/Ryujinx/Assets/locales.json | 78 +++++++++---------- .../Views/Settings/SettingsSystemView.axaml | 4 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index c6f474577..555c6d3c3 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -5148,28 +5148,28 @@ } }, { - "ID": "SettingsTabSystemIgnoreApplet", + "ID": "SettingsTabSystemIgnoreControllerApplet", "Translations": { "ar_SA": "", - "de_DE": "Applet ignorieren", - "el_GR": "Αγνοήστε το Applet", - "en_US": "Ignore Applet", - "es_ES": "Ignorar el Applet", - "fr_FR": "Ignorer la déconnexion de la manette", + "de_DE": "", + "el_GR": "", + "en_US": "Ignore Controller Applet", + "es_ES": "", + "fr_FR": "", "he_IL": "", - "it_IT": "Ignora l'applet", - "ja_JP": "アプレットを無視する", - "ko_KR": "애플릿 무시", - "no_NO": "Ignorer appleten", - "pl_PL": "Ignoruj ​​aplet", - "pt_BR": "Ignorar applet", - "ru_RU": "Игнорировать Апплет", - "sv_SE": "Ignorera applet", - "th_TH": "เมินเฉย Applet", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", "tr_TR": "", - "uk_UA": "Ігнорувати Аплет", - "zh_CN": "忽略小程序", - "zh_TW": "忽略小程式" + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { @@ -16523,28 +16523,28 @@ } }, { - "ID": "IgnoreAppletTooltip", + "ID": "IgnoreControllerAppletTooltip", "Translations": { - "ar_SA": "لن يظهر مربع الحوار الخارجي \"تطبيق وحدة التحكم\" إذا تم فصل لوحة الألعاب أثناء اللعب. ولن تظهر مطالبة بإغلاق مربع الحوار أو إعداد وحدة تحكم جديدة. وبمجرد إعادة توصيل وحدة التحكم التي تم فصلها سابقًا، ستستأنف اللعبة تلقائيًا.", - "de_DE": "Der externe Dialog \"Controller-Applet\" wird nicht angezeigt, wenn das Gamepad während des Spiels getrennt wird. Es erfolgt keine Aufforderung, den Dialog zu schließen oder einen neuen Controller einzurichten. Sobald der zuvor getrennte Controller wieder angeschlossen wird, wird das Spiel automatisch fortgesetzt.", - "el_GR": "Το εξωτερικό παράθυρο διαλόγου \"Ελεγκτής μικροεφαρμογής\" δεν θα εμφανιστεί εάν το gamepad αποσυνδεθεί κατά τη διάρκεια του παιχνιδιού. Δεν θα σας ζητηθεί να κλείσετε το παράθυρο διαλόγου ή να ρυθμίσετε έναν νέο ελεγκτή. Μόλις επανασυνδεθεί το χειριστήριο που είχε αποσυνδεθεί προηγουμένως, το παιχνίδι θα συνεχιστεί αυτόματα.", - "en_US": "The external dialog \"Controller Applet\" will not appear if the gamepad is disconnected during gameplay. There will be no prompt to close the dialog or set up a new controller. Once the previously disconnected controller is reconnected, the game will automatically resume.", - "es_ES": "El cuadro de diálogo externo \"Applet del controlador\" no aparecerá si el gamepad se desconecta durante el juego. No aparecerá ningún mensaje para cerrar el cuadro de diálogo o configurar un nuevo controlador. Una vez que se vuelva a conectar el controlador que se había desconectado anteriormente, el juego se reanudará automáticamente.", - "fr_FR": "La boîte de dialogue externe \"Programme Manette\" n'apparaîtra pas si la manette est déconnectée en jeu. Il n'y aura aucune boîte de dialogue ouverte pour configurer une nouvelle manette. Une fois que la manette précédemment déconnectée est reconnectée, le jeu reprendra automatiquement. \n\nLaissez désactivé en cas d'incertitude.", - "he_IL": "תיבת הדו-שיח החיצונית \"Controller Applet\" לא תופיע אם ה-Gamepad מנותק במהלך המשחק. לא תהיה הנחיה לסגור את תיבת הדו-שיח או להגדיר בקר חדש. ברגע שהבקר שנותק בעבר יתחבר מחדש, המשחק יתחדש אוטומטית.", - "it_IT": "La finestra di dialogo esterna \"Controller Applet\" non apparirà se il gamepad viene disconnesso durante il gioco. Non ci sarà alcun prompt per chiudere la finestra di dialogo o impostare un nuovo controller. Una volta che il controller disconnesso in precedenza viene ricollegato, il gioco riprenderà automaticamente.", - "ja_JP": "ゲームプレイ中にゲームパッドが切断された場合、外部ダイアログ「コントローラーアプレット」は表示されません。このダイアログを閉じるか、新しいコントローラーを設定するように求めるプロンプトは表示されません。以前に切断されたコントローラーが再接続されると、ゲームは自動的に再開されます。", - "ko_KR": "게임 플레이 중에 게임패드 연결이 끊어지면 외부 대화 상자 \"컨트롤러 애플릿\"이 나타나지 않습니다. 대화 상자를 닫거나 새 컨트롤러를 설정하라는 메시지가 표시되지 않습니다. 이전에 연결이 끊어진 컨트롤러가 다시 연결되면 게임이 자동으로 다시 시작됩니다.", - "no_NO": "Den eksterne dialogboksen «Controller Applet» vises ikke hvis gamepaden kobles fra under spilling. Du blir ikke bedt om å lukke dialogboksen eller konfigurere en ny kontroller. Når den tidligere frakoblede kontrolleren er koblet til igjen, fortsetter spillet automatisk.", - "pl_PL": "Zewnętrzny dialog \"Controller Applet\" nie pojawi się, jeśli gamepad zostanie odłączony podczas rozgrywki. Nie pojawi się monit o zamknięcie dialogu lub skonfigurowanie nowego kontrolera. Po ponownym podłączeniu poprzednio odłączonego kontrolera gra zostanie automatycznie wznowiona.", - "pt_BR": "O diálogo externo \"Controller Applet\" não aparecerá se o gamepad for desconectado durante o jogo. Não haverá prompt para fechar o diálogo ou configurar um novo controle. Assim que o controle desconectado anteriormente for reconectado, o jogo será retomado automaticamente.", - "ru_RU": "Внешний диалог \"Апплет контроллера\" не появится, если геймпад будет отключен во время игры. Не будет предложено закрыть диалог или настроить новый контроллер. После повторного подключения ранее отключенного контроллера игра автоматически возобновится.", - "sv_SE": "Den externa dialogen \"Handkontroller-applet\" kommer inte att visas om din gamepad är frånkopplad under spel. Det finns ingen fråga att stänga dialogen eller konfigurera en ny handkontroller. När den tidigare frånkopplade handkontrollern återansluts så kommer spelet att automatiskt återupptas.", - "th_TH": "กล่องโต้ตอบภายนอก \"แอปเพล็ตตัวควบคุม\" จะไม่ปรากฏขึ้นหากแป้นเกมถูกตัดการเชื่อมต่อระหว่างการเล่นเกม จะไม่มีข้อความแจ้งให้ปิดกล่องโต้ตอบหรือตั้งค่าตัวควบคุมใหม่ เมื่อเชื่อมต่อคอนโทรลเลอร์ที่ตัดการเชื่อมต่อก่อนหน้านี้อีกครั้ง เกมจะดำเนินการต่อโดยอัตโนมัติ", - "tr_TR": "Oyun sırasında oyun kumandasının bağlantısı kesilirse, harici \"Controller Applet\" iletişim kutusu görünmez. İletişim kutusunu kapatma veya yeni bir kumanda ayarlama isteği olmaz. Daha önce bağlantısı kesilen kumanda tekrar bağlandığında oyun otomatik olarak devam eder.", - "uk_UA": "Зовнішнє діалогове вікно \"Аплет контролера\" не з’являтиметься, якщо геймпад буде від’єднано під час гри. Не буде запиту закрити діалогове вікно чи налаштувати новий контролер. Після повторного підключення раніше від’єднаного контролера гра автоматично відновиться.", - "zh_CN": "如果游戏手柄在游戏过程中断开连接,则不会出现外部对话框“控制器小程序”。不会提示关闭对话框或设置新控制器。一旦先前断开连接的控制器重新连接,游戏将自动恢复。", - "zh_TW": "如果遊戲手把在遊戲過程中斷開連接,則外部對話方塊「控制器小程式」將不會出現。不會提示關閉對話方塊或設定新控制器。一旦先前斷開的控制器重新連接,遊戲將自動恢復。" + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "The Controller Applet dialog will not appear if the gamepad is disconnected while an application is running.\n\nLeave OFF if unsure.", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" } }, { diff --git a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml index aa7144cf1..7a9a55848 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml @@ -316,8 +316,8 @@ - + ToolTip.Tip="{ext:Locale IgnoreControllerAppletTooltip}"> + Date: Sat, 15 Feb 2025 19:01:24 -0600 Subject: [PATCH 08/13] misc: chore: Change Analyzer AddSpec logic to log the non-hexadecimal value and ignore the added entry instead of throwing an exception --- src/Ryujinx/Utilities/PlayReport/Analyzer.cs | 49 ++++++++++++++------ 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs index 51047cc32..cd4021bc4 100644 --- a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs +++ b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs @@ -1,5 +1,6 @@ using Gommon; using Ryujinx.Ava.Utilities.AppLibrary; +using Ryujinx.Common.Logging; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -27,10 +28,12 @@ namespace Ryujinx.Ava.Utilities.PlayReport /// The current , for chaining convenience. public Analyzer AddSpec(string titleId, Func transform) { - Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); + if (ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _)) + return AddSpec(transform(GameSpec.Create(titleId))); - return AddSpec(transform(GameSpec.Create(titleId))); + Logger.Notice.PrintMsg(LogClass.Application, + $"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{titleId}'"); + return this; } /// @@ -41,10 +44,12 @@ namespace Ryujinx.Ava.Utilities.PlayReport /// The current , for chaining convenience. public Analyzer AddSpec(string titleId, Action transform) { - Guard.Ensure(ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); + if (ulong.TryParse(titleId, NumberStyles.HexNumber, null, out _)) + return AddSpec(GameSpec.Create(titleId).Apply(transform)); - return AddSpec(GameSpec.Create(titleId).Apply(transform)); + Logger.Notice.PrintMsg(LogClass.Application, + $"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{titleId}'"); + return this; } /// @@ -57,10 +62,19 @@ namespace Ryujinx.Ava.Utilities.PlayReport Func transform) { string[] tids = titleIds.ToArray(); - Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); + if (tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _) && !string.IsNullOrEmpty(x))) + return AddSpec(transform(GameSpec.Create(tids))); - return AddSpec(transform(GameSpec.Create(tids))); + Logger.Notice.PrintMsg(LogClass.Application, + $"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{ + tids.FormatCollection( + x => x, + separator: ", ", + prefix: "[", + suffix: "]" + ) + }'"); + return this; } /// @@ -72,12 +86,21 @@ namespace Ryujinx.Ava.Utilities.PlayReport public Analyzer AddSpec(IEnumerable titleIds, Action transform) { string[] tids = titleIds.ToArray(); - Guard.Ensure(tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _)), - $"Cannot use a non-hexadecimal string as the Title ID for a {nameof(GameSpec)}."); + if (tids.All(x => ulong.TryParse(x, NumberStyles.HexNumber, null, out _) && !string.IsNullOrEmpty(x))) + return AddSpec(GameSpec.Create(tids).Apply(transform)); - return AddSpec(GameSpec.Create(tids).Apply(transform)); + Logger.Notice.PrintMsg(LogClass.Application, + $"Tried to add a {nameof(GameSpec)} with a non-hexadecimal title ID value. Input: '{ + tids.FormatCollection( + x => x, + separator: ", ", + prefix: "[", + suffix: "]" + ) + }'"); + return this; } - + /// /// Add an analysis spec matching a specific game by title ID, with the provided pre-configured spec. /// From 45ee8cd0e875c94d378e3af76233e2ba94925f55 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 19:02:04 -0600 Subject: [PATCH 09/13] misc: Play Report Analyzer: Skyward Sword HD rupee count --- src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs index cabace6bb..43e830819 100644 --- a/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.Formatters.cs @@ -1,4 +1,5 @@ using Gommon; +using Humanizer; using System; using System.Buffers.Binary; using System.Collections.Generic; @@ -18,6 +19,9 @@ namespace Ryujinx.Ava.Utilities.PlayReport < -201d => "Exploring the Depths", _ => "Roaming Hyrule" }; + + private static FormattedValue SkywardSwordHD_Rupees(SingleValue value) + => "rupee".ToQuantity(value.Matched.IntValue); private static FormattedValue SuperMarioOdyssey_AssistMode(SingleValue value) => value.Matched.BoxedValue is 1 ? "Playing in Assist Mode" : "Playing in Regular Mode"; From f92d09711bc5ab03703af4422b721b7bb3cbf52f Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 19:02:37 -0600 Subject: [PATCH 10/13] misc: chore: rewrite PlayReports.Analyzer creation to use Lazy and create the value alongside DiscordIntegrationModule init --- src/Ryujinx/DiscordIntegrationModule.cs | 1 + .../Utilities/PlayReport/PlayReports.cs | 136 ++++++++++-------- 2 files changed, 76 insertions(+), 61 deletions(-) diff --git a/src/Ryujinx/DiscordIntegrationModule.cs b/src/Ryujinx/DiscordIntegrationModule.cs index 47fc8ad69..075dc65da 100644 --- a/src/Ryujinx/DiscordIntegrationModule.cs +++ b/src/Ryujinx/DiscordIntegrationModule.cs @@ -56,6 +56,7 @@ namespace Ryujinx.Ava ConfigurationState.Instance.EnableDiscordIntegration.Event += Update; TitleIDs.CurrentApplication.Event += (_, e) => Use(e.NewValue); HorizonStatic.PlayReport += HandlePlayReport; + PlayReports.Initialize(); } private static void Update(object sender, ReactiveEventArgs evnt) diff --git a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs index d5568962e..27330c808 100644 --- a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs @@ -1,67 +1,81 @@ -namespace Ryujinx.Ava.Utilities.PlayReport +using System; + +namespace Ryujinx.Ava.Utilities.PlayReport { public static partial class PlayReports { - public static Analyzer Analyzer { get; } = new Analyzer() - .AddSpec( - "01007ef00011e000", - spec => spec - .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) - // reset to normal status when switching between normal & master mode in title screen - .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) - ) - .AddSpec( - "0100f2c0115b6000", - spec => spec - .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) - .AddSpec( - "0100000000010000", - spec => - spec.AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) - ) - .AddSpec( - "010075000ecbe000", - spec => - spec.AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) - ) - .AddSpec( - "010028600ebda000", - spec => spec.AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) - ) - .AddSpec( // Global & China IDs - ["0100152000022000", "010075100e8ec000"], - spec => spec.AddValueFormatter("To", MarioKart8Deluxe_Mode) - ) - .AddSpec( - ["0100a3d008c5c000", "01008f6008c5e000"], - spec => spec - .AddValueFormatter("area_no", PokemonSVArea) - .AddValueFormatter("team_circle", PokemonSVUnionCircle) - ) - .AddSpec( - "01006a800016e000", - spec => spec - .AddSparseMultiValueFormatter( - [ - // Metadata to figure out what PlayReport we have. - "match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count", - "adv_slot", - // List of Fighters - "player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter", - "player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter", - // List of rankings/placements - "player_1_rank", "player_2_rank", "player_3_rank", "player_4_rank", "player_5_rank", - "player_6_rank", "player_7_rank", "player_8_rank" - ], - SuperSmashBrosUltimate_Mode - ) - ) - .AddSpec( - [ - "0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", - "010012f017576000", "0100c62011050000", "0100b3c014bda000"], - spec => spec.AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) - ); + public static void Initialize() + { + // init lazy value + _ = Analyzer; + } + + public static Analyzer Analyzer => _analyzerLazy.Value; + + private static readonly Lazy _analyzerLazy = new(() => + new Analyzer() + .AddSpec( + "01007ef00011e000", + spec => spec + .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) + // reset to normal status when switching between normal & master mode in title screen + .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) + ) + .AddSpec( + "0100f2c0115b6000", + spec => spec + .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) + .AddSpec( + "0100000000010000", + spec => + spec.AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) + ) + .AddSpec( + "010075000ecbe000", + spec => + spec.AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) + ) + .AddSpec( + "010028600ebda000", + spec => spec.AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) + ) + .AddSpec( // Global & China IDs + ["0100152000022000", "010075100e8ec000"], + spec => spec.AddValueFormatter("To", MarioKart8Deluxe_Mode) + ) + .AddSpec( + ["0100a3d008c5c000", "01008f6008c5e000"], + spec => spec + .AddValueFormatter("area_no", PokemonSVArea) + .AddValueFormatter("team_circle", PokemonSVUnionCircle) + ) + .AddSpec( + "01006a800016e000", + spec => spec + .AddSparseMultiValueFormatter( + [ + // Metadata to figure out what PlayReport we have. + "match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count", + "adv_slot", + // List of Fighters + "player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter", + "player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter", + // List of rankings/placements + "player_1_rank", "player_2_rank", "player_3_rank", "player_4_rank", "player_5_rank", + "player_6_rank", "player_7_rank", "player_8_rank" + ], + SuperSmashBrosUltimate_Mode + ) + ) + .AddSpec( + [ + "0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", + "010012f017576000", "0100c62011050000", "0100b3c014bda000" + ], + spec => spec.AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) + ) + .AddSpec("01002da013484000", spec => spec.AddValueFormatter("rupees", SkywardSwordHD_Rupees)) + ); private static string Playing(string game) => $"Playing {game}"; } From aa2178dbe5eee7079035e4098900b10f0e09bbe3 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 20:25:17 -0600 Subject: [PATCH 11/13] UI: Button to open screenshots folder in File menu --- src/Ryujinx/Assets/locales.json | 50 +++++++++++++++++++ .../UI/ViewModels/MainWindowViewModel.cs | 19 +++++++ .../UI/Views/Main/MainMenuBarView.axaml | 4 ++ 3 files changed, 73 insertions(+) diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json index 555c6d3c3..3623a0073 100644 --- a/src/Ryujinx/Assets/locales.json +++ b/src/Ryujinx/Assets/locales.json @@ -447,6 +447,31 @@ "zh_TW": "開啟 Ryujinx 資料夾" } }, + { + "ID": "MenuBarFileOpenScreenshotsFolder", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Open Screenshots Folder", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "MenuBarFileOpenLogsFolder", "Translations": { @@ -17197,6 +17222,31 @@ "zh_TW": "開啟 Ryujinx 檔案系統資料夾" } }, + { + "ID": "OpenScreenshotFolderTooltip", + "Translations": { + "ar_SA": "", + "de_DE": "", + "el_GR": "", + "en_US": "Open Ryujinx screenshots folder", + "es_ES": "", + "fr_FR": "", + "he_IL": "", + "it_IT": "", + "ja_JP": "", + "ko_KR": "", + "no_NO": "", + "pl_PL": "", + "pt_BR": "", + "ru_RU": "", + "sv_SE": "", + "th_TH": "", + "tr_TR": "", + "uk_UA": "", + "zh_CN": "", + "zh_TW": "" + } + }, { "ID": "OpenRyujinxLogsTooltip", "Translations": { diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index bbfe80570..7d7674c4e 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1347,6 +1347,25 @@ namespace Ryujinx.Ava.UI.ViewModels OpenHelper.OpenFolder(AppDataManager.BaseDirPath); } + public void OpenScreenshotsFolder() + { + string screenshotsDir = Path.Combine(AppDataManager.BaseDirPath, "screenshots"); + + try + { + if (!Directory.Exists(screenshotsDir)) + Directory.CreateDirectory(screenshotsDir); + } + catch (Exception ex) + { + Logger.Error?.Print(LogClass.Application, $"Failed to create directory at path {screenshotsDir}. Error : {ex.GetType().Name}", "Screenshot"); + + return; + } + + OpenHelper.OpenFolder(screenshotsDir); + } + public void OpenLogsFolder() { string logPath = AppDataManager.GetOrCreateLogsDir(); diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml index cacb4b130..1da91c388 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml @@ -66,6 +66,10 @@ Command="{Binding OpenRyujinxFolder}" Header="{ext:Locale MenuBarFileOpenEmuFolder}" ToolTip.Tip="{ext:Locale OpenRyujinxFolderTooltip}" /> + Date: Sat, 15 Feb 2025 20:45:27 -0600 Subject: [PATCH 12/13] UI: Add descriptions of what each dynamic RPC formatter actually shows when hovering whether it has support in the game info popup --- .../UI/Controls/ApplicationDataView.axaml | 14 +++++--- .../UI/ViewModels/ApplicationDataViewModel.cs | 6 ++++ .../Utilities/AppLibrary/ApplicationData.cs | 10 ++++-- src/Ryujinx/Utilities/PlayReport/Analyzer.cs | 11 +++++-- .../Utilities/PlayReport/PlayReports.cs | 32 ++++++++++++++----- src/Ryujinx/Utilities/PlayReport/Specs.cs | 16 +++++++++- 6 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml index aee8f7b36..92e4d1ac3 100644 --- a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml +++ b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml @@ -119,17 +119,23 @@ TextWrapping="Wrap" > - - + + + TextWrapping="Wrap"> - + AppData = appData; + public string DynamicRichPresenceDescription => + AppData.HasDynamicRichPresenceSupport + ? AppData.RichPresenceSpec.Value.Description + : GameSpec.DefaultDescription; + public string FormattedVersion => LocaleManager.Instance[LocaleKeys.GameListHeaderVersion].Format(AppData.Version); public string FormattedDeveloper => LocaleManager.Instance[LocaleKeys.GameListHeaderDeveloper].Format(AppData.Developer); public string FormattedFileExtension => LocaleManager.Instance[LocaleKeys.GameListHeaderFileExtension].Format(AppData.FileExtension); diff --git a/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs b/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs index 747ead8ca..2658352d7 100644 --- a/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs +++ b/src/Ryujinx/Utilities/AppLibrary/ApplicationData.cs @@ -10,6 +10,7 @@ using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.NcaUtils; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Utilities.Compat; +using Ryujinx.Ava.Utilities.PlayReport; using Ryujinx.Common.Logging; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.Loaders.Processes.Extensions; @@ -35,9 +36,14 @@ namespace Ryujinx.Ava.Utilities.AppLibrary { _id = value; - Compatibility = CompatibilityCsv.Find(Id); + Compatibility = CompatibilityCsv.Find(value); + RichPresenceSpec = PlayReports.Analyzer.TryGetSpec(IdString, out GameSpec gameSpec) + ? gameSpec + : default(Optional); } } + public Optional RichPresenceSpec { get; set; } + public string Developer { get; set; } = "Unknown"; public string Version { get; set; } = "0"; public int PlayerCount { get; set; } @@ -46,7 +52,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary public bool HasLdnGames => PlayerCount != 0 && GameCount != 0; public bool HasRichPresenceAsset => DiscordIntegrationModule.HasAssetImage(IdString); - public bool HasDynamicRichPresenceSupport => DiscordIntegrationModule.HasAnalyzer(IdString); + public bool HasDynamicRichPresenceSupport => RichPresenceSpec.HasValue; public TimeSpan TimePlayed { get; set; } public DateTime? LastPlayed { get; set; } diff --git a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs index cd4021bc4..8faf4fb31 100644 --- a/src/Ryujinx/Utilities/PlayReport/Analyzer.cs +++ b/src/Ryujinx/Utilities/PlayReport/Analyzer.cs @@ -20,6 +20,11 @@ namespace Ryujinx.Ava.Utilities.PlayReport public IReadOnlyList Specs => new ReadOnlyCollection(_specs); + public GameSpec GetSpec(string titleId) => _specs.First(x => x.TitleIds.ContainsIgnoreCase(titleId)); + + public bool TryGetSpec(string titleId, out GameSpec gameSpec) + => (gameSpec = _specs.FirstOrDefault(x => x.TitleIds.ContainsIgnoreCase(titleId))) != null; + /// /// Add an analysis spec matching a specific game by title ID, with the provided spec configuration. /// @@ -128,13 +133,13 @@ namespace Ryujinx.Ava.Utilities.PlayReport { if (!playReport.ReportData.IsDictionary) return FormattedValue.Unhandled; - - if (!_specs.TryGetFirst(s => runningGameId.EqualsAnyIgnoreCase(s.TitleIds), out GameSpec spec)) + + if (!TryGetSpec(runningGameId, out GameSpec spec)) return FormattedValue.Unhandled; foreach (FormatterSpecBase formatSpec in spec.ValueFormatters.OrderBy(x => x.Priority)) { - if (!formatSpec.Format(appMeta, playReport, out FormattedValue value)) + if (!formatSpec.TryFormat(appMeta, playReport, out FormattedValue value)) continue; return value; diff --git a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs index 27330c808..7602c1de8 100644 --- a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs @@ -17,6 +17,7 @@ namespace Ryujinx.Ava.Utilities.PlayReport .AddSpec( "01007ef00011e000", spec => spec + .WithDescription("based on being in Master Mode.") .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) // reset to normal status when switching between normal & master mode in title screen .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) @@ -24,34 +25,48 @@ namespace Ryujinx.Ava.Utilities.PlayReport .AddSpec( "0100f2c0115b6000", spec => spec + .WithDescription("based on where you are in Hyrule (Depths, Surface, Sky).") .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) + .AddSpec( + "01002da013484000", + spec => spec + .WithDescription("based on how many Rupees you have.") + .AddValueFormatter("rupees", SkywardSwordHD_Rupees)) .AddSpec( "0100000000010000", - spec => - spec.AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) + spec => spec + .WithDescription("based on if you're playing with Assist Mode.") + .AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) ) .AddSpec( "010075000ecbe000", - spec => - spec.AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) + spec => spec + .WithDescription("based on if you're playing with Assist Mode.") + .AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) ) .AddSpec( "010028600ebda000", - spec => spec.AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) + spec => spec + .WithDescription("based on being in either Super Mario 3D World or Bowser's Fury.") + .AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) ) .AddSpec( // Global & China IDs ["0100152000022000", "010075100e8ec000"], - spec => spec.AddValueFormatter("To", MarioKart8Deluxe_Mode) + spec => spec + .WithDescription("based on what modes you're selecting in the menu & whether or not you're in a race.") + .AddValueFormatter("To", MarioKart8Deluxe_Mode) ) .AddSpec( ["0100a3d008c5c000", "01008f6008c5e000"], spec => spec + .WithDescription("based on what area of Paldea you're exploring.") .AddValueFormatter("area_no", PokemonSVArea) .AddValueFormatter("team_circle", PokemonSVUnionCircle) ) .AddSpec( "01006a800016e000", spec => spec + .WithDescription("based on what mode you're playing, who won, and what characters were present.") .AddSparseMultiValueFormatter( [ // Metadata to figure out what PlayReport we have. @@ -72,9 +87,10 @@ namespace Ryujinx.Ava.Utilities.PlayReport "0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", "010012f017576000", "0100c62011050000", "0100b3c014bda000" ], - spec => spec.AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) + spec => spec + .WithDescription("based on what game you first launch.\n\nNSO emulators do not print any Play Report information past the first game launch so it's all we got.") + .AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) ) - .AddSpec("01002da013484000", spec => spec.AddValueFormatter("rupees", SkywardSwordHD_Rupees)) ); private static string Playing(string game) => $"Playing {game}"; diff --git a/src/Ryujinx/Utilities/PlayReport/Specs.cs b/src/Ryujinx/Utilities/PlayReport/Specs.cs index f1b94de68..c162d4c2c 100644 --- a/src/Ryujinx/Utilities/PlayReport/Specs.cs +++ b/src/Ryujinx/Utilities/PlayReport/Specs.cs @@ -23,6 +23,20 @@ namespace Ryujinx.Ava.Utilities.PlayReport public required string[] TitleIds { get; init; } + public const string DefaultDescription = "Formats the details on your Discord presence based on logged data from the game."; + + private string _valueDescription; + + public string Description => _valueDescription ?? DefaultDescription; + + public GameSpec WithDescription(string description) + { + _valueDescription = description != null + ? $"Formats the details on your Discord presence {description}" + : null; + return this; + } + public List ValueFormatters { get; } = []; @@ -197,7 +211,7 @@ namespace Ryujinx.Ava.Utilities.PlayReport public string[] ReportKeys { get; init; } public Delegate Formatter { get; init; } - public bool Format(ApplicationMetadata appMeta, Horizon.Prepo.Types.PlayReport playReport, + public bool TryFormat(ApplicationMetadata appMeta, Horizon.Prepo.Types.PlayReport playReport, out FormattedValue formattedValue) { formattedValue = default; From b1f61e5143cf7c29cfa5f742d96d2cd5f4ee51f7 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Sat, 15 Feb 2025 20:52:03 -0600 Subject: [PATCH 13/13] misc: chore: [ci skip] Reformat PlayReports.cs --- .../Utilities/PlayReport/PlayReports.cs | 161 +++++++++--------- 1 file changed, 81 insertions(+), 80 deletions(-) diff --git a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs index 7602c1de8..9feb888b3 100644 --- a/src/Ryujinx/Utilities/PlayReport/PlayReports.cs +++ b/src/Ryujinx/Utilities/PlayReport/PlayReports.cs @@ -9,88 +9,89 @@ namespace Ryujinx.Ava.Utilities.PlayReport // init lazy value _ = Analyzer; } - + public static Analyzer Analyzer => _analyzerLazy.Value; - private static readonly Lazy _analyzerLazy = new(() => - new Analyzer() - .AddSpec( - "01007ef00011e000", - spec => spec - .WithDescription("based on being in Master Mode.") - .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) - // reset to normal status when switching between normal & master mode in title screen - .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) - ) - .AddSpec( - "0100f2c0115b6000", - spec => spec - .WithDescription("based on where you are in Hyrule (Depths, Surface, Sky).") - .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) - .AddSpec( - "01002da013484000", - spec => spec - .WithDescription("based on how many Rupees you have.") - .AddValueFormatter("rupees", SkywardSwordHD_Rupees)) - .AddSpec( - "0100000000010000", - spec => spec - .WithDescription("based on if you're playing with Assist Mode.") - .AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) - ) - .AddSpec( - "010075000ecbe000", - spec => spec - .WithDescription("based on if you're playing with Assist Mode.") - .AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) - ) - .AddSpec( - "010028600ebda000", - spec => spec - .WithDescription("based on being in either Super Mario 3D World or Bowser's Fury.") - .AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) - ) - .AddSpec( // Global & China IDs - ["0100152000022000", "010075100e8ec000"], - spec => spec - .WithDescription("based on what modes you're selecting in the menu & whether or not you're in a race.") - .AddValueFormatter("To", MarioKart8Deluxe_Mode) - ) - .AddSpec( - ["0100a3d008c5c000", "01008f6008c5e000"], - spec => spec - .WithDescription("based on what area of Paldea you're exploring.") - .AddValueFormatter("area_no", PokemonSVArea) - .AddValueFormatter("team_circle", PokemonSVUnionCircle) - ) - .AddSpec( - "01006a800016e000", - spec => spec - .WithDescription("based on what mode you're playing, who won, and what characters were present.") - .AddSparseMultiValueFormatter( - [ - // Metadata to figure out what PlayReport we have. - "match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count", - "adv_slot", - // List of Fighters - "player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter", - "player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter", - // List of rankings/placements - "player_1_rank", "player_2_rank", "player_3_rank", "player_4_rank", "player_5_rank", - "player_6_rank", "player_7_rank", "player_8_rank" - ], - SuperSmashBrosUltimate_Mode - ) - ) - .AddSpec( - [ - "0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", - "010012f017576000", "0100c62011050000", "0100b3c014bda000" - ], - spec => spec - .WithDescription("based on what game you first launch.\n\nNSO emulators do not print any Play Report information past the first game launch so it's all we got.") - .AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) - ) + private static readonly Lazy _analyzerLazy = new(() => new Analyzer() + .AddSpec( + "01007ef00011e000", + spec => spec + .WithDescription("based on being in Master Mode.") + .AddValueFormatter("IsHardMode", BreathOfTheWild_MasterMode) + // reset to normal status when switching between normal & master mode in title screen + .AddValueFormatter("AoCVer", FormattedValue.SingleAlwaysResets) + ) + .AddSpec( + "0100f2c0115b6000", + spec => spec + .WithDescription("based on where you are in Hyrule (Depths, Surface, Sky).") + .AddValueFormatter("PlayerPosY", TearsOfTheKingdom_CurrentField)) + .AddSpec( + "01002da013484000", + spec => spec + .WithDescription("based on how many Rupees you have.") + .AddValueFormatter("rupees", SkywardSwordHD_Rupees)) + .AddSpec( + "0100000000010000", + spec => spec + .WithDescription("based on if you're playing with Assist Mode.") + .AddValueFormatter("is_kids_mode", SuperMarioOdyssey_AssistMode) + ) + .AddSpec( + "010075000ecbe000", + spec => spec + .WithDescription("based on if you're playing with Assist Mode.") + .AddValueFormatter("is_kids_mode", SuperMarioOdysseyChina_AssistMode) + ) + .AddSpec( + "010028600ebda000", + spec => spec + .WithDescription("based on being in either Super Mario 3D World or Bowser's Fury.") + .AddValueFormatter("mode", SuperMario3DWorldOrBowsersFury) + ) + .AddSpec( // Global & China IDs + ["0100152000022000", "010075100e8ec000"], + spec => spec + .WithDescription( + "based on what modes you're selecting in the menu & whether or not you're in a race.") + .AddValueFormatter("To", MarioKart8Deluxe_Mode) + ) + .AddSpec( + ["0100a3d008c5c000", "01008f6008c5e000"], + spec => spec + .WithDescription("based on what area of Paldea you're exploring.") + .AddValueFormatter("area_no", PokemonSVArea) + .AddValueFormatter("team_circle", PokemonSVUnionCircle) + ) + .AddSpec( + "01006a800016e000", + spec => spec + .WithDescription("based on what mode you're playing, who won, and what characters were present.") + .AddSparseMultiValueFormatter( + [ + // Metadata to figure out what PlayReport we have. + "match_mode", "match_submode", "anniversary", "fighter", "reason", "challenge_count", + "adv_slot", + // List of Fighters + "player_1_fighter", "player_2_fighter", "player_3_fighter", "player_4_fighter", + "player_5_fighter", "player_6_fighter", "player_7_fighter", "player_8_fighter", + // List of rankings/placements + "player_1_rank", "player_2_rank", "player_3_rank", "player_4_rank", "player_5_rank", + "player_6_rank", "player_7_rank", "player_8_rank" + ], + SuperSmashBrosUltimate_Mode + ) + ) + .AddSpec( + [ + "0100c9a00ece6000", "01008d300c50c000", "0100d870045b6000", + "010012f017576000", "0100c62011050000", "0100b3c014bda000" + ], + spec => spec + .WithDescription( + "based on what game you first launch.\n\nNSO emulators do not print any Play Report information past the first game launch so it's all we got.") + .AddValueFormatter("launch_title_id", NsoEmulator_LaunchedGame) + ) ); private static string Playing(string game) => $"Playing {game}";