From d394dd769a4f8390c41a978e8187964ca3312ef0 Mon Sep 17 00:00:00 2001
From: Nicola <61830443+nicola02nb@users.noreply.github.com>
Date: Sun, 17 Nov 2024 07:15:06 +0100
Subject: [PATCH 01/33] Updated IT translation file (#243)
---
src/Ryujinx/Assets/Locales/it_IT.json | 80 ++++++++++++++++++++-------
1 file changed, 60 insertions(+), 20 deletions(-)
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index ee2bd3a16..349b53500 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -33,8 +33,9 @@
"MenuBarFileLoadDlcFromFolder": "Carica DLC Da una Cartella",
"MenuBarFileLoadTitleUpdatesFromFolder": "Carica Aggiornamenti Da una Cartella",
"MenuBarFileOpenFromFileError": "Nessuna applicazione trovata nel file selezionato",
- "MenuBarView": "_View",
- "MenuBarViewWindow": "Window Size",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
+ "MenuBarView": "_Vista",
+ "MenuBarViewWindow": "Dimensione Finestra",
"MenuBarViewWindow720": "720p",
"MenuBarViewWindow1080": "1080p",
"MenuBarHelp": "_Aiuto",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Apre la cartella che contiene le mod dell'applicazione",
"GameListContextMenuOpenSdModsDirectory": "Apri la cartella delle mod Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Apre la cartella alternativa di Atmosphere sulla scheda SD che contiene le mod dell'applicazione. Utile per le mod create per funzionare sull'hardware reale.",
- "StatusBarGamesLoaded": "{0}/{1} giochi caricati",
+ "GameListContextMenuTrimXCI": "Controlla e Trimma i file XCI",
+ "GameListContextMenuTrimXCIToolTip": "Controlla e Trimma i file XCI da Salvare Sullo Spazio del Disco",
+ "StatusBarGamesLoaded": "{0}/{1} Giochi Caricati",
"StatusBarSystemVersion": "Versione di sistema: {0}",
+ "StatusBarXCIFileTrimming": "Trimmando i file XCI '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Rilevato limite basso per le mappature di memoria",
"LinuxVmMaxMapCountDialogTextPrimary": "Vuoi aumentare il valore di vm.max_map_count a {0}?",
"LinuxVmMaxMapCountDialogTextSecondary": "Alcuni giochi potrebbero provare a creare più mappature di memoria di quanto sia attualmente consentito. Ryujinx si bloccherà non appena questo limite viene superato.",
@@ -99,8 +103,8 @@
"SettingsTabGeneralEnableDiscordRichPresence": "Attiva Discord Rich Presence",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Controlla aggiornamenti all'avvio",
"SettingsTabGeneralShowConfirmExitDialog": "Mostra dialogo \"Conferma Uscita\"",
- "SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
- "SettingsTabGeneralShowTitleBar": "Show Title Bar (Requires restart)",
+ "SettingsTabGeneralRememberWindowState": "Ricorda Dimensione/Posizione Finestra",
+ "SettingsTabGeneralShowTitleBar": "Mostra barra del titolo (Richiede il riavvio)",
"SettingsTabGeneralHideCursor": "Nascondi il cursore:",
"SettingsTabGeneralHideCursorNever": "Mai",
"SettingsTabGeneralHideCursorOnIdle": "Quando è inattivo",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Finestra di input",
"InputDialogOk": "OK",
"InputDialogCancel": "Annulla",
+ "InputDialogCancelling": "Cancellando",
+ "InputDialogClose": "Chiudi",
"InputDialogAddNewProfileTitle": "Scegli il nome del profilo",
"InputDialogAddNewProfileHeader": "Digita un nome profilo",
"InputDialogAddNewProfileSubtext": "(Lunghezza massima: {0})",
@@ -407,7 +413,7 @@
"AvatarSetBackgroundColor": "Imposta colore di sfondo",
"AvatarClose": "Chiudi",
"ControllerSettingsLoadProfileToolTip": "Carica profilo",
- "ControllerSettingsViewProfileToolTip": "View Profile",
+ "ControllerSettingsViewProfileToolTip": "Visualizza profilo",
"ControllerSettingsAddProfileToolTip": "Aggiungi profilo",
"ControllerSettingsRemoveProfileToolTip": "Rimuovi profilo",
"ControllerSettingsSaveProfileToolTip": "Salva profilo",
@@ -417,7 +423,7 @@
"GameListContextMenuToggleFavorite": "Preferito",
"GameListContextMenuToggleFavoriteToolTip": "Segna il gioco come preferito",
"SettingsTabGeneralTheme": "Tema:",
- "SettingsTabGeneralThemeAuto": "Auto",
+ "SettingsTabGeneralThemeAuto": "Automatico",
"SettingsTabGeneralThemeDark": "Scuro",
"SettingsTabGeneralThemeLight": "Chiaro",
"ControllerSettingsConfigureGeneral": "Configura",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Tipi di file disinstallati con successo!",
"DialogUninstallFileTypesErrorMessage": "Disinstallazione dei tipi di file non riuscita.",
"DialogOpenSettingsWindowLabel": "Apri finestra delle impostazioni",
+ "DialogOpenXCITrimmerWindowLabel": "Finestra XCI Trimmer",
"DialogControllerAppletTitle": "Applet del controller",
"DialogMessageDialogErrorExceptionMessage": "Errore nella visualizzazione del Message Dialog: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Errore nella visualizzazione della tastiera software: {0}",
@@ -522,7 +529,7 @@
"DialogModManagerDeletionAllWarningMessage": "Stai per eliminare tutte le mod per questo titolo.\n\nVuoi davvero procedere?",
"SettingsTabGraphicsFeaturesOptions": "Funzionalità",
"SettingsTabGraphicsBackendMultithreading": "Multithreading del backend grafico:",
- "CommonAuto": "Auto",
+ "CommonAuto": "Automatico",
"CommonOff": "Disattivato",
"CommonOn": "Attivo",
"InputDialogYes": "Sì",
@@ -669,9 +676,15 @@
"OpenSetupGuideMessage": "Apri la guida all'installazione",
"NoUpdate": "Nessun aggiornamento",
"TitleUpdateVersionLabel": "Versione {0}",
- "TitleBundledUpdateVersionLabel": "Incluso: Version {0}",
- "TitleBundledDlcLabel": "Incluso:",
- "RyujinxInfo": "Ryujinx - Info",
+ "TitleBundledUpdateVersionLabel": "In bundle: Versione {0}",
+ "TitleBundledDlcLabel": "In bundle:",
+ "TitleXCIStatusPartialLabel": "Parziale",
+ "TitleXCIStatusTrimmableLabel": "Non Trimmato",
+ "TitleXCIStatusUntrimmableLabel": "Trimmato",
+ "TitleXCIStatusFailedLabel": "(Fallito)",
+ "TitleXCICanSaveLabel": "Salva {0:n0} Mb",
+ "TitleXCISavingLabel": "Salva {0:n0} Mb",
+ "RyujinxInfo": "Ryujinx - Informazioni",
"RyujinxConfirm": "Ryujinx - Conferma",
"FileDialogAllTypes": "Tutti i tipi",
"Never": "Mai",
@@ -723,27 +736,54 @@
"SelectDlcDialogTitle": "Seleziona file dei DLC",
"SelectUpdateDialogTitle": "Seleziona file di aggiornamento",
"SelectModDialogTitle": "Seleziona cartella delle mod",
+ "TrimXCIFileDialogTitle": "Controlla e Trimma i file XCI ",
+ "TrimXCIFileDialogPrimaryText": "Questa funzionalita controllerà prima lo spazio libero e poi trimmerà il file XCI per liberare dello spazio.",
+ "TrimXCIFileDialogSecondaryText": "Dimensioni Attuali File: {0:n} MB\nDimensioni Dati Gioco: {1:n} MB\nRisparimio Spazio Disco: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "Il file XCI non deve essere trimmato. Controlla i log per ulteriori dettagli",
+ "TrimXCIFileNoUntrimPossible": "Il file XCI non può essere untrimmato. Controlla i log per ulteriori dettagli",
+ "TrimXCIFileReadOnlyFileCannotFix": "Il file XCI è in sola lettura e non può essere reso Scrivibile. Controlla i log per ulteriori dettagli",
+ "TrimXCIFileFileSizeChanged": "Il file XCI ha cambiato dimensioni da quando è stato scansionato. Controlla che il file non stia venendo scritto da qualche altro programma e poi riprova.",
+ "TrimXCIFileFreeSpaceCheckFailed": "Il file XCI ha dati nello spazio libero, non è sicuro effettuare il trimming",
+ "TrimXCIFileInvalidXCIFile": "Il file XCI contiene dati invlidi. Controlla i log per ulteriori dettagli",
+ "TrimXCIFileFileIOWriteError": "Il file XCI non può essere aperto per essere scritto. Controlla i log per ulteriori dettagli",
+ "TrimXCIFileFailedPrimaryText": "Trimming del file XCI fallito",
+ "TrimXCIFileCancelled": "Operazione Cancellata",
+ "TrimXCIFileFileUndertermined": "Nessuna operazione è stata effettuata",
"UserProfileWindowTitle": "Gestione profili utente",
"CheatWindowTitle": "Gestione trucchi",
"DlcWindowTitle": "Gestisci DLC per {0} ({1})",
"ModWindowTitle": "Gestisci mod per {0} ({1})",
"UpdateWindowTitle": "Gestione aggiornamenti",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} di {1} Titolo(i) Selezionati",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Titolo(i) Selezionati ({2} visualizzato)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Titolo(i)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Titolo(i)...",
+ "XCITrimmerTitleStatusFailed": "Fallito",
+ "XCITrimmerPotentialSavings": "Potenziali Salvataggi",
+ "XCITrimmerActualSavings": "Effettivi Salvataggi",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Seleziona Visualizzati",
+ "XCITrimmerDeselectDisplayed": "Deselziona Visualizzati",
+ "XCITrimmerSortName": "Titolo",
+ "XCITrimmerSortSaved": "Salvataggio Spazio",
+ "UpdateWindowUpdateAddedMessage": "{0} aggiornamento/i aggiunto/i",
+ "UpdateWindowBundledContentNotice": "Gli aggiornamenti inclusi non possono essere eliminati, ma solo disattivati",
"CheatWindowHeading": "Trucchi disponibili per {0} [{1}]",
"BuildId": "ID Build",
+ "DlcWindowBundledContentNotice": "i DLC \"impacchettati\" non possono essere rimossi, ma solo disabilitati.",
"DlcWindowHeading": "DLC disponibili per {0} [{1}]",
- "ModWindowHeading": "{0} mod",
- "UserProfilesEditProfile": "Modifica selezionati",
- "Cancel": "Annulla",
- "Save": "Salva",
- "Discard": "Scarta",
- "UpdateWindowBundledContentNotice": "Gli aggiornamenti inclusi non possono essere eliminati, ma solo disattivati",
+ "DlcWindowDlcAddedMessage": "{0} nuovo/i contenuto/i scaricabile/i aggiunto/i",
"AutoloadDlcAddedMessage": "{0} contenuto/i scaricabile/i aggiunto/i",
"AutoloadDlcRemovedMessage": "{0} contenuto/i scaricabile/i mancante/i rimosso/i",
"AutoloadUpdateAddedMessage": "{0} aggiornamento/i aggiunto/i",
"AutoloadUpdateRemovedMessage": "{0} aggiornamento/i mancante/i rimosso/i",
- "DlcWindowBundledContentNotice": "i DLC \"impacchettati\" non possono essere rimossi, ma solo disabilitati.",
- "DlcWindowDlcAddedMessage": "{0} nuovo/i contenuto/i scaricabile/i aggiunto/i",
- "UpdateWindowUpdateAddedMessage": "{0} aggiornamento/i aggiunto/i",
+ "ModWindowHeading": "{0} mod",
+ "UserProfilesEditProfile": "Modifica selezionati",
+ "Continue": "Continua",
+ "Cancel": "Annulla",
+ "Save": "Salva",
+ "Discard": "Scarta",
"Paused": "In pausa",
"UserProfilesSetProfileImage": "Imposta immagine profilo",
"UserProfileEmptyNameError": "Il nome è obbligatorio",
From e5d076a1b2e5c7abac41758f3c7ac6c040502586 Mon Sep 17 00:00:00 2001
From: Nicola <61830443+nicola02nb@users.noreply.github.com>
Date: Sun, 17 Nov 2024 07:16:05 +0100
Subject: [PATCH 02/33] Fixed some broken urls (#249)
---
src/Ryujinx/Assets/Locales/ar_SA.json | 2 +-
src/Ryujinx/Assets/Locales/de_DE.json | 2 +-
src/Ryujinx/Assets/Locales/el_GR.json | 2 +-
src/Ryujinx/Assets/Locales/en_US.json | 2 +-
src/Ryujinx/Assets/Locales/es_ES.json | 2 +-
src/Ryujinx/Assets/Locales/fr_FR.json | 2 +-
src/Ryujinx/Assets/Locales/he_IL.json | 2 +-
src/Ryujinx/Assets/Locales/it_IT.json | 2 +-
src/Ryujinx/Assets/Locales/ja_JP.json | 2 +-
src/Ryujinx/Assets/Locales/ko_KR.json | 4 ++--
src/Ryujinx/Assets/Locales/pl_PL.json | 2 +-
src/Ryujinx/Assets/Locales/pt_BR.json | 2 +-
src/Ryujinx/Assets/Locales/ru_RU.json | 2 +-
src/Ryujinx/Assets/Locales/th_TH.json | 2 +-
src/Ryujinx/Assets/Locales/tr_TR.json | 2 +-
src/Ryujinx/Assets/Locales/uk_UA.json | 2 +-
src/Ryujinx/Assets/Locales/zh_CN.json | 2 +-
src/Ryujinx/Assets/Locales/zh_TW.json | 2 +-
18 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json
index 495ab4b4d..723a7f133 100644
--- a/src/Ryujinx/Assets/Locales/ar_SA.json
+++ b/src/Ryujinx/Assets/Locales/ar_SA.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "أنت غير متصل بالإنترنت.",
"DialogUpdaterNoInternetSubMessage": "يرجى التحقق من أن لديك اتصال إنترنت فعال!",
"DialogUpdaterDirtyBuildMessage": "لا يمكنك تحديث نسخة القذرة من ريوجينكس!",
- "DialogUpdaterDirtyBuildSubMessage": "الرجاء تحميل ريوجينكس من https://https://github.com/GreemDev/Ryujinx/releases إذا كنت تبحث عن إصدار مدعوم.",
+ "DialogUpdaterDirtyBuildSubMessage": "الرجاء تحميل ريوجينكس من https://ryujinx.app/download إذا كنت تبحث عن إصدار مدعوم.",
"DialogRestartRequiredMessage": "يتطلب إعادة التشغيل",
"DialogThemeRestartMessage": "تم حفظ السمة. إعادة التشغيل مطلوبة لتطبيق السمة.",
"DialogThemeRestartSubMessage": "هل تريد إعادة التشغيل",
diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index e23f3b619..856f87198 100644
--- a/src/Ryujinx/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Es besteht keine Verbindung mit dem Internet!",
"DialogUpdaterNoInternetSubMessage": "Bitte vergewissern, dass eine funktionierende Internetverbindung existiert!",
"DialogUpdaterDirtyBuildMessage": "Inoffizielle Versionen von Ryujinx können nicht aktualisiert werden",
- "DialogUpdaterDirtyBuildSubMessage": "Lade Ryujinx bitte von hier herunter, um eine unterstützte Version zu erhalten: https://https://github.com/GreemDev/Ryujinx/releases/",
+ "DialogUpdaterDirtyBuildSubMessage": "Lade Ryujinx bitte von hier herunter, um eine unterstützte Version zu erhalten: https://ryujinx.app/download",
"DialogRestartRequiredMessage": "Neustart erforderlich",
"DialogThemeRestartMessage": "Das Design wurde gespeichert. Ein Neustart ist erforderlich, um das Design anzuwenden.",
"DialogThemeRestartSubMessage": "Jetzt neu starten?",
diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index 79975b892..9bba65ae2 100644
--- a/src/Ryujinx/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Δεν είστε συνδεδεμένοι στο Διαδίκτυο!",
"DialogUpdaterNoInternetSubMessage": "Επαληθεύστε ότι έχετε σύνδεση στο Διαδίκτυο που λειτουργεί!",
"DialogUpdaterDirtyBuildMessage": "Δεν μπορείτε να ενημερώσετε μία Πρόχειρη Έκδοση του Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Κάντε λήψη του Ryujinx στη διεύθυνση https://https://github.com/GreemDev/Ryujinx/releases/ εάν αναζητάτε μία υποστηριζόμενη έκδοση.",
+ "DialogUpdaterDirtyBuildSubMessage": "Κάντε λήψη του Ryujinx στη διεύθυνση https://ryujinx.app/download εάν αναζητάτε μία υποστηριζόμενη έκδοση.",
"DialogRestartRequiredMessage": "Απαιτείται Επανεκκίνηση",
"DialogThemeRestartMessage": "Το θέμα έχει αποθηκευτεί. Απαιτείται επανεκκίνηση για την εφαρμογή του θέματος.",
"DialogThemeRestartSubMessage": "Θέλετε να κάνετε επανεκκίνηση",
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index fdd2d4df2..85691481f 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -462,7 +462,7 @@
"DialogUpdaterNoInternetMessage": "You are not connected to the Internet!",
"DialogUpdaterNoInternetSubMessage": "Please verify that you have a working Internet connection!",
"DialogUpdaterDirtyBuildMessage": "You cannot update a Dirty build of Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Please download Ryujinx at https://github.com/GreemDev/Ryujinx/releases/ if you are looking for a supported version.",
+ "DialogUpdaterDirtyBuildSubMessage": "Please download Ryujinx at https://ryujinx.app/download if you are looking for a supported version.",
"DialogRestartRequiredMessage": "Restart Required",
"DialogThemeRestartMessage": "Theme has been saved. A restart is needed to apply the theme.",
"DialogThemeRestartSubMessage": "Do you want to restart",
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index e6da1d113..161351539 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "¡No estás conectado a internet!",
"DialogUpdaterNoInternetSubMessage": "¡Por favor, verifica que tu conexión a Internet funciona!",
"DialogUpdaterDirtyBuildMessage": "¡No puedes actualizar una versión \"dirty\" de Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Por favor, descarga Ryujinx en https://https://github.com/GreemDev/Ryujinx/releases/ si buscas una versión con soporte.",
+ "DialogUpdaterDirtyBuildSubMessage": "Por favor, descarga Ryujinx en https://ryujinx.app/download si buscas una versión con soporte.",
"DialogRestartRequiredMessage": "Se necesita reiniciar",
"DialogThemeRestartMessage": "Tema guardado. Se necesita reiniciar para aplicar el tema.",
"DialogThemeRestartSubMessage": "¿Quieres reiniciar?",
diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json
index e52333cea..0073a2cf5 100644
--- a/src/Ryujinx/Assets/Locales/fr_FR.json
+++ b/src/Ryujinx/Assets/Locales/fr_FR.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Vous n'êtes pas connecté à Internet !",
"DialogUpdaterNoInternetSubMessage": "Veuillez vérifier que vous disposez d'une connexion Internet fonctionnelle !",
"DialogUpdaterDirtyBuildMessage": "Vous ne pouvez pas mettre à jour une version Dirty de Ryujinx !",
- "DialogUpdaterDirtyBuildSubMessage": "Veuillez télécharger Ryujinx sur https://github.com/GreemDev/Ryujinx/releases/ si vous recherchez une version prise en charge.",
+ "DialogUpdaterDirtyBuildSubMessage": "Veuillez télécharger Ryujinx sur https://ryujinx.app/download si vous recherchez une version prise en charge.",
"DialogRestartRequiredMessage": "Redémarrage requis",
"DialogThemeRestartMessage": "Le thème a été enregistré. Un redémarrage est requis pour appliquer le thème.",
"DialogThemeRestartSubMessage": "Voulez-vous redémarrer",
diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index d2bd21124..dd86e10f4 100644
--- a/src/Ryujinx/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "אתם לא מחוברים לאינטרנט!",
"DialogUpdaterNoInternetSubMessage": "אנא ודא שיש לך חיבור אינטרנט תקין!",
"DialogUpdaterDirtyBuildMessage": "אתם לא יכולים לעדכן מבנה מלוכלך של ריוג'ינקס!",
- "DialogUpdaterDirtyBuildSubMessage": "אם אתם מחפשים גרסא נתמכת, אנא הורידו את ריוג'ינקס בכתובת https://https://github.com/GreemDev/Ryujinx/releases",
+ "DialogUpdaterDirtyBuildSubMessage": "אם אתם מחפשים גרסא נתמכת, אנא הורידו את ריוג'ינקס בכתובת https://ryujinx.app/download",
"DialogRestartRequiredMessage": "אתחול נדרש",
"DialogThemeRestartMessage": "ערכת הנושא נשמרה. יש צורך בהפעלה מחדש כדי להחיל את ערכת הנושא.",
"DialogThemeRestartSubMessage": "האם ברצונך להפעיל מחדש?",
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index 349b53500..fff0f99e9 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -462,7 +462,7 @@
"DialogUpdaterNoInternetMessage": "Non sei connesso ad Internet!",
"DialogUpdaterNoInternetSubMessage": "Verifica di avere una connessione ad Internet funzionante!",
"DialogUpdaterDirtyBuildMessage": "Non puoi aggiornare una Dirty build di Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Scarica Ryujinx da https://https://github.com/GreemDev/Ryujinx/releases/ se stai cercando una versione supportata.",
+ "DialogUpdaterDirtyBuildSubMessage": "Scarica Ryujinx da https://ryujinx.app/download se stai cercando una versione supportata.",
"DialogRestartRequiredMessage": "Riavvio richiesto",
"DialogThemeRestartMessage": "Il tema è stato salvato. È richiesto un riavvio per applicare il tema.",
"DialogThemeRestartSubMessage": "Vuoi riavviare?",
diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index 8d15ab678..ed7809d03 100644
--- a/src/Ryujinx/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "インターネットに接続されていません!",
"DialogUpdaterNoInternetSubMessage": "インターネット接続が正常動作しているか確認してください!",
"DialogUpdaterDirtyBuildMessage": "Dirty ビルドの Ryujinx はアップデートできません!",
- "DialogUpdaterDirtyBuildSubMessage": "サポートされているバージョンをお探しなら, https://https://github.com/GreemDev/Ryujinx/releases/ で Ryujinx をダウンロードしてください.",
+ "DialogUpdaterDirtyBuildSubMessage": "サポートされているバージョンをお探しなら, https://ryujinx.app/download で Ryujinx をダウンロードしてください.",
"DialogRestartRequiredMessage": "再起動が必要",
"DialogThemeRestartMessage": "テーマがセーブされました. テーマを適用するには再起動が必要です.",
"DialogThemeRestartSubMessage": "再起動しますか",
diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index bcac40138..275fd3802 100644
--- a/src/Ryujinx/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
@@ -462,7 +462,7 @@
"DialogUpdaterNoInternetMessage": "인터넷에 연결되어 있지 않습니다!",
"DialogUpdaterNoInternetSubMessage": "인터넷이 제대로 연결되어 있는지 확인하세요!",
"DialogUpdaterDirtyBuildMessage": "Ryujinx의 더티 빌드는 업데이트할 수 없습니다!",
- "DialogUpdaterDirtyBuildSubMessage": "지원되는 버전을 찾으신다면 https://github.com/GreemDev/Ryujinx/releases/에서 Ryujinx를 내려받으세요.",
+ "DialogUpdaterDirtyBuildSubMessage": "지원되는 버전을 찾으신다면 https://ryujinx.app/download 에서 Ryujinx를 내려받으세요.",
"DialogRestartRequiredMessage": "다시 시작 필요",
"DialogThemeRestartMessage": "테마를 저장했습니다. 테마를 적용하려면 다시 시작해야 합니다.",
"DialogThemeRestartSubMessage": "다시 시작하시겠습니까?",
@@ -861,4 +861,4 @@
"ClearLdnPass": "지우기",
"ClearLdnPassTooltip": "현재 암호를 지우고 공용 네트워크로 돌아갑니다.",
"InvalidLdnPassphrase": "유효하지 않은 암호입니다! \"Ryujinx-<8 hex chars>\" 형식이어야 합니다."
- }
+}
diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index d6356dc76..37b0df9e8 100644
--- a/src/Ryujinx/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Nie masz połączenia z Internetem!",
"DialogUpdaterNoInternetSubMessage": "Sprawdź, czy masz działające połączenie internetowe!",
"DialogUpdaterDirtyBuildMessage": "Nie możesz zaktualizować Dirty wersji Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Pobierz Ryujinx ze strony https://https://github.com/GreemDev/Ryujinx/releases/, jeśli szukasz obsługiwanej wersji.",
+ "DialogUpdaterDirtyBuildSubMessage": "Pobierz Ryujinx ze strony https://ryujinx.app/download, jeśli szukasz obsługiwanej wersji.",
"DialogRestartRequiredMessage": "Wymagane Ponowne Uruchomienie",
"DialogThemeRestartMessage": "Motyw został zapisany. Aby zastosować motyw, konieczne jest ponowne uruchomienie.",
"DialogThemeRestartSubMessage": "Czy chcesz uruchomić ponownie?",
diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index 42a8e437b..e27c3d9a4 100644
--- a/src/Ryujinx/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Você não está conectado à Internet!",
"DialogUpdaterNoInternetSubMessage": "Por favor, certifique-se de que você tem uma conexão funcional à Internet!",
"DialogUpdaterDirtyBuildMessage": "Você não pode atualizar uma compilação Dirty do Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Por favor, baixe o Ryujinx em https://https://github.com/GreemDev/Ryujinx/releases/ se está procurando por uma versão suportada.",
+ "DialogUpdaterDirtyBuildSubMessage": "Por favor, baixe o Ryujinx em https://ryujinx.app/download se está procurando por uma versão suportada.",
"DialogRestartRequiredMessage": "Reinicialização necessária",
"DialogThemeRestartMessage": "O tema foi salvo. Uma reinicialização é necessária para aplicar o tema.",
"DialogThemeRestartSubMessage": "Deseja reiniciar?",
diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index 4ef6ff6d9..910e8a443 100644
--- a/src/Ryujinx/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Вы не подключены к интернету",
"DialogUpdaterNoInternetSubMessage": "Убедитесь, что у вас работает подключение к интернету",
"DialogUpdaterDirtyBuildMessage": "Вы не можете обновлять Dirty Build",
- "DialogUpdaterDirtyBuildSubMessage": "Загрузите Ryujinx по адресу https://https://github.com/GreemDev/Ryujinx/releases/ если вам нужна поддерживаемая версия.",
+ "DialogUpdaterDirtyBuildSubMessage": "Загрузите Ryujinx по адресу https://ryujinx.app/download если вам нужна поддерживаемая версия.",
"DialogRestartRequiredMessage": "Требуется перезагрузка",
"DialogThemeRestartMessage": "Тема сохранена. Для применения темы требуется перезапуск.",
"DialogThemeRestartSubMessage": "Хотите перезапустить",
diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json
index 91169d9e2..ab7a26690 100644
--- a/src/Ryujinx/Assets/Locales/th_TH.json
+++ b/src/Ryujinx/Assets/Locales/th_TH.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "คุณไม่ได้เชื่อมต่อกับอินเทอร์เน็ต!",
"DialogUpdaterNoInternetSubMessage": "โปรดตรวจสอบว่าคุณมีการเชื่อมต่ออินเทอร์เน็ตว่ามีการใช้งานได้หรือไม่!",
"DialogUpdaterDirtyBuildMessage": "คุณไม่สามารถอัปเดต Dirty build ของ Ryujinx ได้!",
- "DialogUpdaterDirtyBuildSubMessage": "โปรดดาวน์โหลด Ryujinx ได้ที่ https://https://github.com/GreemDev/Ryujinx/releases/ หากคุณกำลังมองหาเวอร์ชั่นที่รองรับ",
+ "DialogUpdaterDirtyBuildSubMessage": "โปรดดาวน์โหลด Ryujinx ได้ที่ https://ryujinx.app/download หากคุณกำลังมองหาเวอร์ชั่นที่รองรับ",
"DialogRestartRequiredMessage": "จำเป็นต้องรีสตาร์ทเพื่อให้การอัพเดตสามารถให้งานได้",
"DialogThemeRestartMessage": "บันทึกธีมแล้ว จำเป็นต้องรีสตาร์ทเพื่อใช้ธีม",
"DialogThemeRestartSubMessage": "คุณต้องการรีสตาร์ทหรือไม่?",
diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index b9ce3e884..2b08c4590 100644
--- a/src/Ryujinx/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "İnternete bağlı değilsiniz!",
"DialogUpdaterNoInternetSubMessage": "Lütfen aktif bir internet bağlantınız olduğunu kontrol edin!",
"DialogUpdaterDirtyBuildMessage": "Ryujinx'in Dirty build'lerini güncelleyemezsiniz!",
- "DialogUpdaterDirtyBuildSubMessage": "Desteklenen bir sürüm için lütfen Ryujinx'i https://https://github.com/GreemDev/Ryujinx/releases/ sitesinden indirin.",
+ "DialogUpdaterDirtyBuildSubMessage": "Desteklenen bir sürüm için lütfen Ryujinx'i https://ryujinx.app/download sitesinden indirin.",
"DialogRestartRequiredMessage": "Yeniden Başlatma Gerekli",
"DialogThemeRestartMessage": "Tema kaydedildi. Temayı uygulamak için yeniden başlatma gerekiyor.",
"DialogThemeRestartSubMessage": "Yeniden başlatmak ister misiniz",
diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index 581d1bca1..3d6c131b8 100644
--- a/src/Ryujinx/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "Ви не підключені до Інтернету!",
"DialogUpdaterNoInternetSubMessage": "Будь ласка, переконайтеся, що у вас є робоче підключення до Інтернету!",
"DialogUpdaterDirtyBuildMessage": "Ви не можете оновити брудну збірку Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "Будь ласка, завантажте Ryujinx на https://https://github.com/GreemDev/Ryujinx/releases/, якщо ви шукаєте підтримувану версію.",
+ "DialogUpdaterDirtyBuildSubMessage": "Будь ласка, завантажте Ryujinx на https://ryujinx.app/download, якщо ви шукаєте підтримувану версію.",
"DialogRestartRequiredMessage": "Потрібен перезапуск",
"DialogThemeRestartMessage": "Тему збережено. Щоб застосувати тему, потрібен перезапуск.",
"DialogThemeRestartSubMessage": "Ви хочете перезапустити",
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index 3426b8a4a..dd43dc741 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "没有连接到网络",
"DialogUpdaterNoInternetSubMessage": "请确保互联网连接正常。",
"DialogUpdaterDirtyBuildMessage": "无法更新非官方版本的 Ryujinx 模拟器!",
- "DialogUpdaterDirtyBuildSubMessage": "如果想使用受支持的版本,请您在 https://https://github.com/GreemDev/Ryujinx/releases/ 下载官方版本。",
+ "DialogUpdaterDirtyBuildSubMessage": "如果想使用受支持的版本,请您在 https://ryujinx.app/download 下载官方版本。",
"DialogRestartRequiredMessage": "需要重启模拟器",
"DialogThemeRestartMessage": "主题设置已保存,需要重启模拟器才能生效。",
"DialogThemeRestartSubMessage": "是否要重启模拟器?",
diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index fd02254e1..35a7cffdc 100644
--- a/src/Ryujinx/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
@@ -456,7 +456,7 @@
"DialogUpdaterNoInternetMessage": "您沒有連線到網際網路!",
"DialogUpdaterNoInternetSubMessage": "請確認您的網際網路連線正常!",
"DialogUpdaterDirtyBuildMessage": "您無法更新非官方版本的 Ryujinx!",
- "DialogUpdaterDirtyBuildSubMessage": "如果您正在尋找受官方支援的版本,請從 https://https://github.com/GreemDev/Ryujinx/releases/ 下載 Ryujinx。",
+ "DialogUpdaterDirtyBuildSubMessage": "如果您正在尋找受官方支援的版本,請從 https://ryujinx.app/download 下載 Ryujinx。",
"DialogRestartRequiredMessage": "需要重新啟動",
"DialogThemeRestartMessage": "佈景主題設定已儲存。需要重新啟動才能套用主題。",
"DialogThemeRestartSubMessage": "您要重新啟動嗎",
From 11416e21671f1ea5f01fb238b81466e3d7df3f92 Mon Sep 17 00:00:00 2001
From: jzumaran
Date: Sun, 17 Nov 2024 03:17:56 -0300
Subject: [PATCH 03/33] i18n: es_ES: Added missing translations and minor fixes
(#242)
Added missing translations and fixed a few spelling mistakes.
---
src/Ryujinx/Assets/Locales/es_ES.json | 90 +++++++++++++++------------
1 file changed, 51 insertions(+), 39 deletions(-)
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index 161351539..41af0c900 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -10,10 +10,10 @@
"SettingsTabSystemUseHypervisor": "Usar hipervisor",
"MenuBarFile": "_Archivo",
"MenuBarFileOpenFromFile": "_Cargar aplicación desde un archivo",
- "MenuBarFileOpenFromFileError": "No applications found in selected file.",
+ "MenuBarFileOpenFromFileError": "No se encontraron aplicaciones en el archivo seleccionado.",
"MenuBarFileOpenUnpacked": "Cargar juego _desempaquetado",
- "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder",
- "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder",
+ "MenuBarFileLoadDlcFromFolder": "Cargar DLC Desde Carpeta",
+ "MenuBarFileLoadTitleUpdatesFromFolder": "Cargar Actualizaciones de Títulos Desde Carpeta",
"MenuBarFileOpenEmuFolder": "Abrir carpeta de Ryujinx",
"MenuBarFileOpenLogsFolder": "Abrir carpeta de registros",
"MenuBarFileExit": "_Salir",
@@ -34,7 +34,7 @@
"MenuBarToolsInstallFileTypes": "Instalar tipos de archivo",
"MenuBarToolsUninstallFileTypes": "Desinstalar tipos de archivo",
"MenuBarView": "_View",
- "MenuBarViewWindow": "Window Size",
+ "MenuBarViewWindow": "Tamaño Ventana",
"MenuBarViewWindow720": "720p",
"MenuBarViewWindow1080": "1080p",
"MenuBarHelp": "_Ayuda",
@@ -99,15 +99,15 @@
"SettingsTabGeneralEnableDiscordRichPresence": "Habilitar estado en Discord",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Buscar actualizaciones al iniciar",
"SettingsTabGeneralShowConfirmExitDialog": "Mostrar diálogo de confirmación al cerrar",
- "SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
- "SettingsTabGeneralShowTitleBar": "Show Title Bar (Requires restart)",
+ "SettingsTabGeneralRememberWindowState": "Recordar Tamaño/Posición de la Ventana",
+ "SettingsTabGeneralShowTitleBar": "Mostrar Barra de Título (Requiere reinicio)",
"SettingsTabGeneralHideCursor": "Esconder el cursor:",
"SettingsTabGeneralHideCursorNever": "Nunca",
"SettingsTabGeneralHideCursorOnIdle": "Ocultar cursor cuando esté inactivo",
"SettingsTabGeneralHideCursorAlways": "Siempre",
"SettingsTabGeneralGameDirectories": "Carpetas de juegos",
- "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories",
- "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically",
+ "SettingsTabGeneralAutoloadDirectories": "Carpetas de DLC/Actualizaciones para Carga Automática",
+ "SettingsTabGeneralAutoloadNote": "DLC y Actualizaciones que hacen referencia a archivos ausentes serán desactivado automáticamente",
"SettingsTabGeneralAdd": "Agregar",
"SettingsTabGeneralRemove": "Quitar",
"SettingsTabSystem": "Sistema",
@@ -142,10 +142,10 @@
"SettingsTabSystemSystemTime": "Hora del sistema:",
"SettingsTabSystemEnableVsync": "Sincronización vertical",
"SettingsTabSystemEnablePptc": "PPTC (Cache de Traducción de Perfil Persistente)",
- "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
+ "SettingsTabSystemEnableLowPowerPptc": "Cache PPTC de bajo consumo",
"SettingsTabSystemEnableFsIntegrityChecks": "Comprobar integridad de los archivos",
"SettingsTabSystemAudioBackend": "Motor de audio:",
- "SettingsTabSystemAudioBackendDummy": "Vacio",
+ "SettingsTabSystemAudioBackendDummy": "Vacío",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
@@ -407,7 +407,7 @@
"AvatarSetBackgroundColor": "Establecer color de fondo",
"AvatarClose": "Cerrar",
"ControllerSettingsLoadProfileToolTip": "Cargar perfil",
- "ControllerSettingsViewProfileToolTip": "View Profile",
+ "ControllerSettingsViewProfileToolTip": "Ver perfil",
"ControllerSettingsAddProfileToolTip": "Agregar perfil",
"ControllerSettingsRemoveProfileToolTip": "Eliminar perfil",
"ControllerSettingsSaveProfileToolTip": "Guardar perfil",
@@ -461,7 +461,7 @@
"DialogThemeRestartMessage": "Tema guardado. Se necesita reiniciar para aplicar el tema.",
"DialogThemeRestartSubMessage": "¿Quieres reiniciar?",
"DialogFirmwareInstallEmbeddedMessage": "¿Quieres instalar el firmware incluido en este juego? (Firmware versión {0})",
- "DialogFirmwareInstallEmbeddedSuccessMessage": "No installed firmware was found but Ryujinx was able to install firmware {0} from the provided game.\nThe emulator will now start.",
+ "DialogFirmwareInstallEmbeddedSuccessMessage": "No se encontró ning{un firmware instalado pero Ryujinx pudo instalar firmware {0} del juego proporcionado.\nEl emulador iniciará.",
"DialogFirmwareNoFirmwareInstalledMessage": "No hay firmware instalado",
"DialogFirmwareInstalledMessage": "Se instaló el firmware {0}",
"DialogInstallFileTypesSuccessMessage": "¡Tipos de archivos instalados con éxito!",
@@ -568,22 +568,22 @@
"AddGameDirBoxTooltip": "Elige un directorio de juegos para mostrar en la ventana principal",
"AddGameDirTooltip": "Agrega un directorio de juegos a la lista",
"RemoveGameDirTooltip": "Quita el directorio seleccionado de la lista",
- "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list",
- "AddAutoloadDirTooltip": "Add an autoload directory to the list",
- "RemoveAutoloadDirTooltip": "Remove selected autoload directory",
+ "AddAutoloadDirBoxTooltip": "Elige un directorio de carga automática para agregar a la lista",
+ "AddAutoloadDirTooltip": "Agregar un directorio de carga automática a la lista",
+ "RemoveAutoloadDirTooltip": "Eliminar el directorio de carga automática seleccionado",
"CustomThemeCheckTooltip": "Activa o desactiva los temas personalizados para la interfaz",
"CustomThemePathTooltip": "Carpeta que contiene los temas personalizados para la interfaz",
"CustomThemeBrowseTooltip": "Busca un tema personalizado para la interfaz",
"DockModeToggleTooltip": "El modo dock o modo TV hace que la consola emulada se comporte como una Nintendo Switch en su dock. Esto mejora la calidad gráfica en la mayoría de los juegos. Del mismo modo, si lo desactivas, el sistema emulado se comportará como una Nintendo Switch en modo portátil, reduciendo la cálidad de los gráficos.\n\nConfigura los controles de \"Jugador\" 1 si planeas jugar en modo dock/TV; configura los controles de \"Portátil\" si planeas jugar en modo portátil.\n\nActívalo si no sabes qué hacer.",
- "DirectKeyboardTooltip": "Direct keyboard access (HID) support. Provides games access to your keyboard as a text entry device.\n\nOnly works with games that natively support keyboard usage on Switch hardware.\n\nLeave OFF if unsure.",
- "DirectMouseTooltip": "Direct mouse access (HID) support. Provides games access to your mouse as a pointing device.\n\nOnly works with games that natively support mouse controls on Switch hardware, which are few and far between.\n\nWhen enabled, touch screen functionality may not work.\n\nLeave OFF if unsure.",
+ "DirectKeyboardTooltip": "Soporte de acceso directo al teclado (HID). Proporciona a los juegos acceso a su teclado como dispositivo de entrada de texto.\n\nSolo funciona con juegos que permiten de forma nativa el uso del teclado en el hardware de Switch.\n\nDesactívalo si no sabes qué hacer.",
+ "DirectMouseTooltip": "Soporte de acceso directo al mouse (HID). Proporciona a los juegos acceso a su mouse como puntero.\n\nSolo funciona con juegos que permiten de forma nativa el uso de controles con mouse en el hardware de switch, lo cual son pocos.\n\nCuando esté activado, la funcionalidad de pantalla táctil puede no funcionar.\n\nDesactívalo si no sabes qué hacer.",
"RegionTooltip": "Cambia la región del sistema",
"LanguageTooltip": "Cambia el idioma del sistema",
"TimezoneTooltip": "Cambia la zona horaria del sistema",
"TimeTooltip": "Cambia la hora del sistema",
- "VSyncToggleTooltip": "Emulated console's Vertical Sync. Essentially a frame-limiter for the majority of games; disabling it may cause games to run at higher speed or make loading screens take longer or get stuck.\n\nCan be toggled in-game with a hotkey of your preference (F1 by default). We recommend doing this if you plan on disabling it.\n\nLeave ON if unsure.",
+ "VSyncToggleTooltip": "Sincronización vertical de la consola emulada. En práctica un limitador del framerate para la mayoría de los juegos; desactivando puede causar que juegos corran a mayor velocidad o que las pantallas de carga tarden más o queden atascados.\n\nSe puede alternar en juego utilizando una tecla de acceso rápido configurable (F1 by default). Recomendamos hacer esto en caso de querer desactivar sincroniziación vertical.\n\nDesactívalo si no sabes qué hacer.",
"PptcToggleTooltip": "Guarda funciones de JIT traducidas para que no sea necesario traducirlas cada vez que el juego carga.\n\nReduce los tirones y acelera significativamente el tiempo de inicio de los juegos después de haberlos ejecutado al menos una vez.\n\nActívalo si no sabes qué hacer.",
- "LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.",
+ "LowPowerPptcToggleTooltip": "Cargue el PPTC utilizando un tercio de la cantidad de núcleos.",
"FsIntegrityToggleTooltip": "Comprueba si hay archivos corruptos en los juegos que ejecutes al abrirlos, y si detecta archivos corruptos, muestra un error de Hash en los registros.\n\nEsto no tiene impacto alguno en el rendimiento y está pensado para ayudar a resolver problemas.\n\nActívalo si no sabes qué hacer.",
"AudioBackendTooltip": "Cambia el motor usado para renderizar audio.\n\nSDL2 es el preferido, mientras que OpenAL y SoundIO se usan si hay problemas con este. Dummy no produce audio.\n\nSelecciona SDL2 si no sabes qué hacer.",
"MemoryManagerTooltip": "Cambia la forma de mapear y acceder a la memoria del guest. Afecta en gran medida al rendimiento de la CPU emulada.\n\nSelecciona \"Host sin verificación\" si no sabes qué hacer.",
@@ -597,10 +597,10 @@
"GraphicsBackendThreadingTooltip": "Ejecuta los comandos del motor gráfico en un segundo hilo. Acelera la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos que no realicen su propio procesamiento con múltiples hilos. Rendimiento ligeramente superior en controladores gráficos que soporten múltiples hilos.\n\nSelecciona \"Auto\" si no sabes qué hacer.",
"GalThreadingTooltip": "Ejecuta los comandos del motor gráfico en un segundo hilo. Acelera la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos que no realicen su propio procesamiento con múltiples hilos. Rendimiento ligeramente superior en controladores gráficos que soporten múltiples hilos.\n\nSelecciona \"Auto\" si no sabes qué hacer.",
"ShaderCacheToggleTooltip": "Guarda una caché de sombreadores en disco, la cual reduce los tirones a medida que vas jugando.\n\nActívalo si no sabes qué hacer.",
- "ResolutionScaleTooltip": "Multiplies the game's rendering resolution.\n\nA few games may not work with this and look pixelated even when the resolution is increased; for those games, you may need to find mods that remove anti-aliasing or that increase their internal rendering resolution. For using the latter, you'll likely want to select Native.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nKeep in mind 4x is overkill for virtually any setup.",
+ "ResolutionScaleTooltip": "Multiplica la resolución de rendereo del juego.\n\nAlgunos juegos podrían no funcionar con esto y verse pixelado al aumentar la resolución; en esos casos, quizás sería necesario buscar mods que de anti-aliasing o que aumenten la resolución interna. Para usar este último, probablemente necesitarás seleccionar Nativa.\n\nEsta opción puede ser modificada mientras que un juego este corriendo haciendo click en \"Aplicar\" más abajo; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nTener en cuenta que 4x es excesivo para prácticamente cualquier configuración.",
"ResolutionScaleEntryTooltip": "Escalado de resolución de coma flotante, como por ejemplo 1,5. Los valores no íntegros pueden causar errores gráficos o crashes.",
- "AnisotropyTooltip": "Level of Anisotropic Filtering. Set to Auto to use the value requested by the game.",
- "AspectRatioTooltip": "Aspect Ratio applied to the renderer window.\n\nOnly change this if you're using an aspect ratio mod for your game, otherwise the graphics will be stretched.\n\nLeave on 16:9 if unsure.",
+ "AnisotropyTooltip": "Nivel de filtrado anisotrópico. Setear en Auto para utilizar el valor solicitado por el juego.",
+ "AspectRatioTooltip": "Relación de aspecto aplicada a la ventana del renderizador.\n\nSolamente modificar esto si estás utilizando un mod de relación de aspecto para su juego, en cualquier otro caso los gráficos se estirarán.\n\nDejar en 16:9 si no sabe que hacer.",
"ShaderDumpPathTooltip": "Directorio en el cual se volcarán los sombreadores de los gráficos",
"FileLogTooltip": "Guarda los registros de la consola en archivos en disco. No afectan al rendimiento.",
"StubLogTooltip": "Escribe mensajes de Stub en la consola. No afectan al rendimiento.",
@@ -616,8 +616,8 @@
"DebugLogTooltip": "Escribe mensajes de debug en la consola\n\nActiva esto solo si un miembro del equipo te lo pide expresamente, pues hará que el registro sea difícil de leer y empeorará el rendimiento del emulador.",
"LoadApplicationFileTooltip": "Abre el explorador de archivos para elegir un archivo compatible con Switch para cargar",
"LoadApplicationFolderTooltip": "Abre el explorador de archivos para elegir un archivo desempaquetado y compatible con Switch para cargar",
- "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from",
- "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from",
+ "LoadDlcFromFolderTooltip": "Abrir un explorador de archivos para seleccionar una o más carpetas para cargar DLC de forma masiva",
+ "LoadTitleUpdatesFromFolderTooltip": "Abrir un explorador de archivos para seleccionar una o más carpetas para cargar actualizaciones de título de forma masiva",
"OpenRyujinxFolderTooltip": "Abre la carpeta de sistema de Ryujinx",
"OpenRyujinxLogsTooltip": "Abre la carpeta en la que se guardan los registros",
"ExitTooltip": "Cierra Ryujinx",
@@ -726,18 +726,18 @@
"UserProfileWindowTitle": "Administrar perfiles de usuario",
"CheatWindowTitle": "Administrar cheats",
"DlcWindowTitle": "Administrar contenido descargable",
- "ModWindowTitle": "Manage Mods for {0} ({1})",
+ "ModWindowTitle": "Administrar Mods para {0} ({1})",
"UpdateWindowTitle": "Administrar actualizaciones",
- "UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
- "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
+ "UpdateWindowUpdateAddedMessage": "{0} nueva(s) actualización(es) agregada(s)",
+ "UpdateWindowBundledContentNotice": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.",
"CheatWindowHeading": "Cheats disponibles para {0} [{1}]",
"BuildId": "Id de compilación:",
"DlcWindowHeading": "Contenido descargable disponible para {0} [{1}]",
- "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
- "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
- "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
- "AutoloadUpdateAddedMessage": "{0} new update(s) added",
- "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
+ "DlcWindowDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)",
+ "AutoloadDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)",
+ "AutoloadDlcRemovedMessage": "Se eliminaron {0} contenido(s) descargable(s) faltantes",
+ "AutoloadUpdateAddedMessage": "Se agregaron {0} nueva(s) actualización(es)",
+ "AutoloadUpdateRemovedMessage": "Se eliminaron {0} actualización(es) faltantes",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Editar selección",
"Cancel": "Cancelar",
@@ -753,9 +753,9 @@
"UserProfilesName": "Nombre:",
"UserProfilesUserId": "Id de Usuario:",
"SettingsTabGraphicsBackend": "Fondo de gráficos",
- "SettingsTabGraphicsBackendTooltip": "Select the graphics backend that will be used in the emulator.\n\nVulkan is overall better for all modern graphics cards, as long as their drivers are up to date. Vulkan also features faster shader compilation (less stuttering) on all GPU vendors.\n\nOpenGL may achieve better results on old Nvidia GPUs, on old AMD GPUs on Linux, or on GPUs with lower VRAM, though shader compilation stutters will be greater.\n\nSet to Vulkan if unsure. Set to OpenGL if your GPU does not support Vulkan even with the latest graphics drivers.",
+ "SettingsTabGraphicsBackendTooltip": "Seleccione el backend gráfico que utilizará el emulador.\n\nVulkan, en general, es mejor para todas las tarjetas gráficas modernas, mientras que sus controladores estén actualizados. Vulkan también cuenta con complicación más rápida de sombreadores (menos tirones) en todos los proveredores de GPU.\n\nOpenGL puede lograr mejores resultados en GPU Nvidia antiguas, GPU AMD antiguas en Linux o en GPUs con menor VRAM, aunque tirones de compilación de sombreadores serán mayores.\n\nSetear en Vulkan si no sabe que hacer. Setear en OpenGL si su GPU no tiene soporte para Vulkan aún con los últimos controladores gráficos.",
"SettingsEnableTextureRecompression": "Activar recompresión de texturas",
- "SettingsEnableTextureRecompressionTooltip": "Compresses ASTC textures in order to reduce VRAM usage.\n\nGames using this texture format include Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder and The Legend of Zelda: Tears of the Kingdom.\n\nGraphics cards with 4GiB VRAM or less will likely crash at some point while running these games.\n\nEnable only if you're running out of VRAM on the aforementioned games. Leave OFF if unsure.",
+ "SettingsEnableTextureRecompressionTooltip": "Comprimir texturas ASTC para reducir uso de VRAM.\n\nJuegos que utilizan este formato de textura incluyen Astral Chain, Bayonetta 3, Fire Emblem Engage, Metroid Prime Remastered, Super Mario Bros. Wonder y The Legend of Zelda: Tears of the Kingdom.\n\nTarjetas gráficas con 4GiB de VRAM o menos probalemente se caeran en algún momento mientras que estén corriendo estos juegos.\n\nActivar solo si está quedan sin VRAM en los juegos antes mencionados. Desactívalo si no sabes qué hacer.",
"SettingsTabGraphicsPreferredGpu": "GPU preferida",
"SettingsTabGraphicsPreferredGpuTooltip": "Selecciona la tarjeta gráfica que se utilizará con los back-end de gráficos Vulkan.\n\nNo afecta la GPU que utilizará OpenGL.\n\nFije a la GPU marcada como \"dGUP\" ante dudas. Si no hay una, no haga modificaciones.",
"SettingsAppRequiredRestartMessage": "Reinicio de Ryujinx requerido.",
@@ -772,7 +772,7 @@
"UserProfilesManageSaves": "Administrar mis partidas guardadas",
"DeleteUserSave": "¿Quieres borrar los datos de usuario de este juego?",
"IrreversibleActionNote": "Esta acción no es reversible.",
- "SaveManagerHeading": "Manage Saves for {0}",
+ "SaveManagerHeading": "Administrar partidas guardadas para {0}",
"SaveManagerTitle": "Administrador de datos de guardado.",
"Name": "Nombre",
"Size": "Tamaño",
@@ -781,11 +781,11 @@
"Recover": "Recuperar",
"UserProfilesRecoverHeading": "Datos de guardado fueron encontrados para las siguientes cuentas",
"UserProfilesRecoverEmptyList": "No hay perfiles a recuperar",
- "GraphicsAATooltip": "Applies anti-aliasing to the game render.\n\nFXAA will blur most of the image, while SMAA will attempt to find jagged edges and smooth them out.\n\nNot recommended to use in conjunction with the FSR scaling filter.\n\nThis option can be changed while a game is running by clicking \"Apply\" below; you can simply move the settings window aside and experiment until you find your preferred look for a game.\n\nLeave on NONE if unsure.",
+ "GraphicsAATooltip": "Aplica antia-aliasing al rendereo del juego.\n\nFXAA desenfocará la mayor parte del la iamgen, mientras que SMAA intentará encontrar bordes irregulares y suavizarlos.\n\nNo se recomienda usar en conjunto con filtro de escala FSR.\n\nEsta opción puede ser modificada mientras que esté corriendo el juego haciendo click en \"Aplicar\" más abajo; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nDejar en NADA si no está seguro.",
"GraphicsAALabel": "Suavizado de bordes:",
"GraphicsScalingFilterLabel": "Filtro de escalado:",
"GraphicsScalingFilterTooltip": "Elija el filtro de escala que se aplicará al utilizar la escala de resolución.\n\nBilinear funciona bien para juegos 3D y es una opción predeterminada segura.\n\nSe recomienda el bilinear para juegos de pixel art.\n\nFSR 1.0 es simplemente un filtro de afilado, no se recomienda su uso con FXAA o SMAA.\n\nEsta opción se puede cambiar mientras se ejecuta un juego haciendo clic en \"Aplicar\" a continuación; simplemente puedes mover la ventana de configuración a un lado y experimentar hasta que encuentres tu estilo preferido para un juego.\n\nDéjelo en BILINEAR si no está seguro.",
- "GraphicsScalingFilterBilinear": "Bilinear\n",
+ "GraphicsScalingFilterBilinear": "Bilinear",
"GraphicsScalingFilterNearest": "Cercano",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
@@ -806,6 +806,18 @@
"SettingsTabNetworkMultiplayer": "Multijugador",
"MultiplayerMode": "Modo:",
"MultiplayerModeTooltip": "Cambiar modo LDN multijugador.\n\nLdnMitm modificará la funcionalidad local de juego inalámbrico para funcionar como si fuera LAN, permitiendo locales conexiones de la misma red con otras instancias de Ryujinx y consolas hackeadas de Nintendo Switch que tienen instalado el módulo ldn_mitm.\n\nMultijugador requiere que todos los jugadores estén en la misma versión del juego (por ejemplo, Super Smash Bros. Ultimate v13.0.1 no se puede conectar a v13.0.0).\n\nDejar DESACTIVADO si no está seguro.",
- "MultiplayerModeDisabled": "Deshabilitar",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeDisabled": "Deshabilitado",
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Desactivar El Hosteo De Red P2P (puede aumentar latencia)",
+ "MultiplayerDisableP2PTooltip": "Desactivar el hosteo de red P2P, pares se conectarán a través del servidor maestro en lugar de conectarse directamente contigo.",
+ "LdnPassphrase": "Frase de contraseña de la Red:",
+ "LdnPassphraseTooltip": "Solo podrás ver los juegos hosteados con la misma frase de contraseña que tú.",
+ "LdnPassphraseInputTooltip": "Ingresar una frase de contraseña en formato Ryujinx-<8 caracteres hexadecimales>. Solamente podrás ver juegos hosteados con la misma frase de contraseña que tú.",
+ "LdnPassphraseInputPublic": "(público)",
+ "GenLdnPass": "Generar aleatorio",
+ "GenLdnPassTooltip": "Genera una nueva frase de contraseña, que puede ser compartida con otros jugadores.",
+ "ClearLdnPass": "Borrar",
+ "ClearLdnPassTooltip": "Borra la frase de contraseña actual, regresando a la red pública.",
+ "InvalidLdnPassphrase": "Frase de Contraseña Inválida! Debe ser en formato \"Ryujinx-<8 caracteres hexadecimales>\""
}
From 52f42d450fb5fb7d2b2dd1d72aef70a07d4e44d5 Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Sun, 17 Nov 2024 00:57:56 -0600
Subject: [PATCH 04/33] try 1: Fix IndexOutOfBounds in SDL2GamepadDriver.cs
---
src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs
index 0acbaaa19..fd34fe219 100644
--- a/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs
+++ b/src/Ryujinx.Input.SDL2/SDL2GamepadDriver.cs
@@ -115,7 +115,10 @@ namespace Ryujinx.Input.SDL2
{
lock (_lock)
{
- _gamepadsIds.Insert(joystickDeviceId, id);
+ if (joystickDeviceId <= _gamepadsIds.FindLastIndex(_ => true))
+ _gamepadsIds.Insert(joystickDeviceId, id);
+ else
+ _gamepadsIds.Add(id);
}
OnGamepadConnected?.Invoke(id);
From 25d69079cbe40c79ad959879a62679e35728ab8f Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Sun, 17 Nov 2024 11:35:37 +0100
Subject: [PATCH 05/33] Fix a couple dead links and spotty wording in docs
(#260)
Made it clearer that building is for contributors only in `COMPILING.md`
Fixed 2 dead links in `CONTRIBUTING.md`, that were caused by separating
`COMPILING.md` and file structure changed to `pr-guide.md`
---
COMPILING.md | 4 ++--
CONTRIBUTING.md | 4 ++--
docs/workflow/pr-guide.md | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/COMPILING.md b/COMPILING.md
index 06cebab44..20a2eb7ff 100644
--- a/COMPILING.md
+++ b/COMPILING.md
@@ -1,6 +1,6 @@
## Compilation
-Building the project is for advanced users.
+Building the project is for users that want to contribute code only.
If you wish to build the emulator yourself, follow these steps:
### Step 1
@@ -20,4 +20,4 @@ Then type the following command: `dotnet build -c Release -o build`
the built files will be found in the newly created build directory.
Ryujinx system files are stored in the `Ryujinx` folder.
-This folder is located in the user folder, which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
\ No newline at end of file
+This folder is located in the user folder, which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index af47fc9d9..686ea3994 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -74,7 +74,7 @@ We use and recommend the following workflow:
3. In your fork, create a branch off of main (`git checkout -b mybranch`).
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
4. Make and commit your changes to your branch.
- - [Build Instructions](https://github.com/GreemDev/Ryujinx#building) explains how to build and test.
+ - [Build Instructions](https://github.com/GreemDev/Ryujinx/blob/master/COMPILING.md) explains how to build and test.
- Commit messages should be clear statements of action and intent.
6. Build the repository with your changes.
- Make sure that the builds are clean.
@@ -83,7 +83,7 @@ We use and recommend the following workflow:
- State in the description what issue or improvement your change is addressing.
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/GreemDev/Ryujinx/actions) to check for outstanding errors.
8. Wait for feedback or approval of your changes from the core development team
- - Details about the pull request [review procedure](docs/workflow/ci/pr-guide.md).
+ - Details about the pull request [review procedure](docs/workflow/pr-guide.md).
9. When the team members have signed off, and all checks are green, your PR will be merged.
- The next official build will automatically include your change.
- You can delete the branch you used for making the change.
diff --git a/docs/workflow/pr-guide.md b/docs/workflow/pr-guide.md
index c03db210b..50f44d87f 100644
--- a/docs/workflow/pr-guide.md
+++ b/docs/workflow/pr-guide.md
@@ -9,7 +9,7 @@ To merge pull requests, you must have write permissions in the repository.
## Quick Code Review Rules
* Do not mix unrelated changes in one pull request. For example, a code style change should never be mixed with a bug fix.
-* All changes should follow the existing code style. You can read more about our code style at [docs/coding-guidelines](../coding-guidelines/coding-style.md).
+* All changes should follow the existing code style. You can read more about our code style at [docs/coding-style](../coding-guidelines/coding-style.md).
* Adding external dependencies is to be avoided unless not doing so would introduce _significant_ complexity. Any dependency addition should be justified and discussed before merge.
* Use Draft pull requests for changes you are still working on but want early CI loop feedback. When you think your changes are ready for review, [change the status](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request) of your pull request.
* Rebase your changes when required or directly requested. Changes should always be commited on top of the upstream branch, not the other way around.
From f4b757c584aabdb43e2f564cf02a1e1ca540f38a Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Mon, 18 Nov 2024 22:05:00 +0100
Subject: [PATCH 06/33] Add `XCITrimmerTrim` and `XCITrimmerUntrim` Locales
(#273)
---
src/Ryujinx/Assets/Locales/ar_SA.json | 2 ++
src/Ryujinx/Assets/Locales/de_DE.json | 2 ++
src/Ryujinx/Assets/Locales/el_GR.json | 2 ++
src/Ryujinx/Assets/Locales/en_US.json | 2 ++
src/Ryujinx/Assets/Locales/es_ES.json | 2 ++
src/Ryujinx/Assets/Locales/he_IL.json | 2 ++
src/Ryujinx/Assets/Locales/it_IT.json | 2 ++
src/Ryujinx/Assets/Locales/ja_JP.json | 2 ++
src/Ryujinx/Assets/Locales/ko_KR.json | 2 ++
src/Ryujinx/Assets/Locales/pl_PL.json | 2 ++
src/Ryujinx/Assets/Locales/pt_BR.json | 2 ++
src/Ryujinx/Assets/Locales/ru_RU.json | 2 ++
src/Ryujinx/Assets/Locales/th_TH.json | 2 ++
src/Ryujinx/Assets/Locales/tr_TR.json | 2 ++
src/Ryujinx/Assets/Locales/uk_UA.json | 2 ++
src/Ryujinx/Assets/Locales/zh_CN.json | 2 ++
src/Ryujinx/Assets/Locales/zh_TW.json | 2 ++
src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml | 4 ++--
18 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json
index 723a7f133..781568fee 100644
--- a/src/Ryujinx/Assets/Locales/ar_SA.json
+++ b/src/Ryujinx/Assets/Locales/ar_SA.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "إدارة المحتوى القابل للتنزيل لـ {0} ({1})",
"ModWindowTitle": "إدارة التعديلات لـ {0} ({1})",
"UpdateWindowTitle": "مدير تحديث العنوان",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "الغش متوفر لـ {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index 856f87198..c6f9768c6 100644
--- a/src/Ryujinx/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Spiel-DLC verwalten",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "Spiel-Updates verwalten",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "Cheats verfügbar für {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index 9bba65ae2..76049fc3f 100644
--- a/src/Ryujinx/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Downloadable Content Manager",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "Διαχειριστής Ενημερώσεων Τίτλου",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "Διαθέσιμα Cheats για {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 85691481f..9354c8a41 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -767,6 +767,8 @@
"XCITrimmerDeselectDisplayed": "Deselect Shown",
"XCITrimmerSortName": "Title",
"XCITrimmerSortSaved": "Space Savings",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "Cheats Available for {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index 41af0c900..cf5c586d0 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Administrar contenido descargable",
"ModWindowTitle": "Administrar Mods para {0} ({1})",
"UpdateWindowTitle": "Administrar actualizaciones",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} nueva(s) actualización(es) agregada(s)",
"UpdateWindowBundledContentNotice": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.",
"CheatWindowHeading": "Cheats disponibles para {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index dd86e10f4..91e3e24e4 100644
--- a/src/Ryujinx/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "נהל הרחבות משחק עבור {0} ({1})",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "נהל עדכוני משחקים",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "צ'יטים זמינים עבור {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index fff0f99e9..2a92e70dc 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -767,6 +767,8 @@
"XCITrimmerDeselectDisplayed": "Deselziona Visualizzati",
"XCITrimmerSortName": "Titolo",
"XCITrimmerSortSaved": "Salvataggio Spazio",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} aggiornamento/i aggiunto/i",
"UpdateWindowBundledContentNotice": "Gli aggiornamenti inclusi non possono essere eliminati, ma solo disattivati",
"CheatWindowHeading": "Trucchi disponibili per {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index ed7809d03..b8e5870a6 100644
--- a/src/Ryujinx/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "DLC 管理",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "アップデート管理",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "利用可能なチート {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index 275fd3802..5bda1565b 100644
--- a/src/Ryujinx/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
@@ -767,6 +767,8 @@
"XCITrimmerDeselectDisplayed": "표시됨 선택 취소",
"XCITrimmerSortName": "타이틀",
"XCITrimmerSortSaved": "공간 절약s",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0}개의 새 업데이트가 추가됨",
"UpdateWindowBundledContentNotice": "번들 업데이트는 제거할 수 없으며, 비활성화만 가능합니다.",
"CheatWindowHeading": "{0} [{1}]에 사용 가능한 치트",
diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index 37b0df9e8..fa88bab5e 100644
--- a/src/Ryujinx/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Menedżer Zawartości do Pobrania",
"ModWindowTitle": "Zarządzaj modami dla {0} ({1})",
"UpdateWindowTitle": "Menedżer Aktualizacji Tytułu",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "Kody Dostępne dla {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index e27c3d9a4..5b7a21494 100644
--- a/src/Ryujinx/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Gerenciador de DLC",
"ModWindowTitle": "Gerenciar Mods para {0} ({1})",
"UpdateWindowTitle": "Gerenciador de atualizações",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} nova(s) atualização(ões) adicionada(s)",
"UpdateWindowBundledContentNotice": "Atualizações incorporadas não podem ser removidas, apenas desativadas.",
"CheatWindowHeading": "Cheats disponíveis para {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index 910e8a443..cd17eb301 100644
--- a/src/Ryujinx/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Управление DLC для {0} ({1})",
"ModWindowTitle": "Управление модами для {0} ({1})",
"UpdateWindowTitle": "Менеджер обновлений игр",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "Доступные читы для {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json
index ab7a26690..d32cfb737 100644
--- a/src/Ryujinx/Assets/Locales/th_TH.json
+++ b/src/Ryujinx/Assets/Locales/th_TH.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "จัดการ DLC ที่ดาวน์โหลดได้สำหรับ {0} ({1})",
"ModWindowTitle": "จัดการม็อดที่ดาวน์โหลดได้สำหรับ {0} ({1})",
"UpdateWindowTitle": "จัดการอัปเดตหัวข้อ",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} อัพเดตที่เพิ่มมาใหม่",
"UpdateWindowBundledContentNotice": "แพ็คที่อัพเดตมาไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น",
"CheatWindowHeading": "สูตรโกงมีให้สำหรับ {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index 2b08c4590..1ac9a0b6e 100644
--- a/src/Ryujinx/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Oyun DLC'lerini Yönet",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "Oyun Güncellemelerini Yönet",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "{0} için Hile mevcut [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index 3d6c131b8..0e22263b6 100644
--- a/src/Ryujinx/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "Менеджер вмісту для завантаження",
"ModWindowTitle": "Керувати модами для {0} ({1})",
"UpdateWindowTitle": "Менеджер оновлення назв",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "Коди доступні для {0} [{1}]",
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index dd43dc741..67b2cc9d1 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "管理 {0} ({1}) 的 DLC",
"ModWindowTitle": "管理 {0} ({1}) 的 MOD",
"UpdateWindowTitle": "游戏更新管理器",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} 个更新被添加",
"UpdateWindowBundledContentNotice": "捆绑的更新无法被移除,只可被禁用。",
"CheatWindowHeading": "适用于 {0} [{1}] 的金手指",
diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index 35a7cffdc..9bfc243ae 100644
--- a/src/Ryujinx/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
@@ -728,6 +728,8 @@
"DlcWindowTitle": "管理 {0} 的可下載內容 ({1})",
"ModWindowTitle": "管理 {0} 的模組 ({1})",
"UpdateWindowTitle": "遊戲更新管理員",
+ "XCITrimmerTrim": "Trim",
+ "XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "已加入 {0} 個遊戲更新",
"UpdateWindowBundledContentNotice": "附帶的遊戲更新只能被停用而無法被刪除。",
"CheatWindowHeading": "可用於 {0} [{1}] 的密技",
diff --git a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml b/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml
index e3640cd7e..d726f8099 100644
--- a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml
+++ b/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml
@@ -296,7 +296,7 @@
Margin="5"
Click="Trim"
IsEnabled="{Binding CanTrim}">
-
+
Date: Tue, 19 Nov 2024 08:52:51 +0100
Subject: [PATCH 07/33] Created bool to store if the "Avilable Update" should
be hidden on startup (--hide-updates) (#272)
fixes #263
---
src/Ryujinx.UI.Common/Helper/CommandLineState.cs | 4 ++++
src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/Ryujinx.UI.Common/Helper/CommandLineState.cs b/src/Ryujinx.UI.Common/Helper/CommandLineState.cs
index ae0e4d904..3a96a55c8 100644
--- a/src/Ryujinx.UI.Common/Helper/CommandLineState.cs
+++ b/src/Ryujinx.UI.Common/Helper/CommandLineState.cs
@@ -16,6 +16,7 @@ namespace Ryujinx.UI.Common.Helper
public static string LaunchPathArg { get; private set; }
public static string LaunchApplicationId { get; private set; }
public static bool StartFullscreenArg { get; private set; }
+ public static bool HideAvailableUpdates { get; private set; }
public static void ParseArguments(string[] args)
{
@@ -93,6 +94,9 @@ namespace Ryujinx.UI.Common.Helper
OverrideHideCursor = args[++i];
break;
+ case "--hide-updates":
+ HideAvailableUpdates = true;
+ break;
case "--software-gui":
OverrideHardwareAcceleration = false;
break;
diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
index 4ddcee07f..829db4bc9 100644
--- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
@@ -383,7 +383,7 @@ namespace Ryujinx.Ava.UI.Windows
await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys));
}
- if (ConfigurationState.Instance.CheckUpdatesOnStart && Updater.CanUpdate())
+ if (ConfigurationState.Instance.CheckUpdatesOnStart && !CommandLineState.HideAvailableUpdates && Updater.CanUpdate())
{
await this.BeginUpdateAsync()
.ContinueWith(
From 722953211d88aa160469f1677f52b6f10f22582b Mon Sep 17 00:00:00 2001
From: Pitchoune
Date: Tue, 19 Nov 2024 08:59:00 +0100
Subject: [PATCH 08/33] Add Zelda Echoes of Wisdom Amiibos informations (#262)
This adds missing informations about Zelda Echoes of Wisdom Amiibos.
---
assets/amiibo/Amiibo.json | 452 +++++++++++++++++++++++++++++++++++++-
1 file changed, 450 insertions(+), 2 deletions(-)
diff --git a/assets/amiibo/Amiibo.json b/assets/amiibo/Amiibo.json
index b877ea142..03c2c020e 100644
--- a/assets/amiibo/Amiibo.json
+++ b/assets/amiibo/Amiibo.json
@@ -707,6 +707,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Blue Attire",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01010300",
@@ -3526,6 +3542,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01400000",
@@ -4160,6 +4192,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -5848,6 +5896,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -6126,6 +6190,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -8341,6 +8421,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -9020,6 +9116,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000100",
@@ -9496,6 +9608,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Blue Attire",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01010000",
@@ -9833,6 +9961,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -14667,6 +14811,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01030000",
@@ -16119,6 +16279,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01050000",
@@ -16717,6 +16893,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01070000",
@@ -19745,6 +19937,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01080000",
@@ -20503,6 +20711,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Blue Attire",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01010000",
@@ -21805,6 +22029,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -22340,6 +22580,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01020100",
@@ -22990,6 +23246,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -23440,6 +23712,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -24660,6 +24948,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01410000",
@@ -24954,6 +25258,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01060000",
@@ -25286,6 +25606,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -29114,6 +29450,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Blue Attire",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01010000",
@@ -32512,6 +32864,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -32928,6 +33296,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000100",
@@ -34800,6 +35184,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Red Tunic",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01000000",
@@ -37569,6 +37969,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Blue Attire",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01010100",
@@ -41293,6 +41709,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Black Cat Clothes",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01020100",
@@ -45153,6 +45585,22 @@
"0100F2C0115B6000"
],
"gameName": "The Legend of Zelda: Tears of the Kingdom"
+ },
+ {
+ "amiiboUsage": [
+ {
+ "Usage": "Receive the Blue Attire",
+ "write": false
+ },
+ {
+ "Usage": "Receive random materials",
+ "write": false
+ }
+ ],
+ "gameID": [
+ "01008CF01BAAC000"
+ ],
+ "gameName": "The Legend of Zelda: Echoes of Wisdom"
}
],
"head": "01010000",
@@ -47896,5 +48344,5 @@
"type": "Figure"
}
],
- "lastUpdated": "2024-10-01T00:00:25.035619"
-}
\ No newline at end of file
+ "lastUpdated": "2024-11-17T15:28:47.035619"
+}
From 008d908c5a2a4bdbdd42a75e2ede70242aef7fb7 Mon Sep 17 00:00:00 2001
From: Narugakuruga <31060534+Narugakuruga@users.noreply.github.com>
Date: Tue, 19 Nov 2024 15:59:56 +0800
Subject: [PATCH 09/33] Update Chinese locale missing line (#259)
---
src/Ryujinx/Assets/Locales/zh_CN.json | 30 +++++++++++++--------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index 67b2cc9d1..004d5007b 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -6,7 +6,7 @@
"SettingsTabSystemMemoryManagerMode": "内存管理模式:",
"SettingsTabSystemMemoryManagerModeSoftware": "软件管理",
"SettingsTabSystemMemoryManagerModeHost": "本机映射 (较快)",
- "SettingsTabSystemMemoryManagerModeHostUnchecked": "跳过检查的本机映射 (最快,但不安全)",
+ "SettingsTabSystemMemoryManagerModeHostUnchecked": "跳过检查的本机映射 (最快,不安全)",
"SettingsTabSystemUseHypervisor": "使用 Hypervisor 虚拟化",
"MenuBarFile": "文件(_F)",
"MenuBarFileOpenFromFile": "加载游戏文件(_L)",
@@ -100,14 +100,14 @@
"SettingsTabGeneralCheckUpdatesOnLaunch": "启动时检查更新",
"SettingsTabGeneralShowConfirmExitDialog": "退出游戏时需要确认",
"SettingsTabGeneralRememberWindowState": "记住窗口大小和位置",
- "SettingsTabGeneralShowTitleBar": "Show Title Bar (Requires restart)",
+ "SettingsTabGeneralShowTitleBar": "显示标题栏 (需要重启)",
"SettingsTabGeneralHideCursor": "隐藏鼠标指针:",
"SettingsTabGeneralHideCursorNever": "从不隐藏",
"SettingsTabGeneralHideCursorOnIdle": "自动隐藏",
"SettingsTabGeneralHideCursorAlways": "始终隐藏",
"SettingsTabGeneralGameDirectories": "游戏目录",
"SettingsTabGeneralAutoloadDirectories": "自动加载DLC/游戏更新目录",
- "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically",
+ "SettingsTabGeneralAutoloadNote": "DLC/游戏更新可自动加载和卸载",
"SettingsTabGeneralAdd": "添加",
"SettingsTabGeneralRemove": "删除",
"SettingsTabSystem": "系统",
@@ -142,7 +142,7 @@
"SettingsTabSystemSystemTime": "系统时钟:",
"SettingsTabSystemEnableVsync": "启用垂直同步",
"SettingsTabSystemEnablePptc": "开启 PPTC 缓存",
- "SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
+ "SettingsTabSystemEnableLowPowerPptc": "低功耗 PPTC 加载",
"SettingsTabSystemEnableFsIntegrityChecks": "启用文件系统完整性检查",
"SettingsTabSystemAudioBackend": "音频处理引擎:",
"SettingsTabSystemAudioBackendDummy": "无",
@@ -407,7 +407,7 @@
"AvatarSetBackgroundColor": "设置背景色",
"AvatarClose": "关闭",
"ControllerSettingsLoadProfileToolTip": "加载配置文件",
- "ControllerSettingsViewProfileToolTip": "View Profile",
+ "ControllerSettingsViewProfileToolTip": "预览配置文件",
"ControllerSettingsAddProfileToolTip": "新增配置文件",
"ControllerSettingsRemoveProfileToolTip": "删除配置文件",
"ControllerSettingsSaveProfileToolTip": "保存配置文件",
@@ -667,7 +667,7 @@
"UserErrorUnknownDescription": "出现未知错误!",
"UserErrorUndefinedDescription": "出现未定义错误!此类错误不应出现,请联系开发者!",
"OpenSetupGuideMessage": "打开安装指南",
- "NoUpdate": "无更新(或不加载游戏更新)",
+ "NoUpdate": "无更新(默认版本)",
"TitleUpdateVersionLabel": "游戏更新的版本 {0}",
"TitleBundledUpdateVersionLabel": "捆绑:版本 {0}",
"TitleBundledDlcLabel": "捆绑:",
@@ -731,17 +731,17 @@
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} 个更新被添加",
- "UpdateWindowBundledContentNotice": "捆绑的更新无法被移除,只可被禁用。",
+ "UpdateWindowBundledContentNotice": "游戏整合的更新无法移除,可尝试禁用。",
"CheatWindowHeading": "适用于 {0} [{1}] 的金手指",
"BuildId": "游戏版本 ID:",
- "DlcWindowBundledContentNotice": "捆绑的DLC无法被移除,只可被禁用。",
+ "DlcWindowBundledContentNotice": "游戏整合的DLC无法移除,可尝试禁用。",
"DlcWindowHeading": "{0} 个 DLC",
"DlcWindowDlcAddedMessage": "{0} 个DLC被添加",
"AutoloadDlcAddedMessage": "{0} 个DLC被添加",
- "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
+ "AutoloadDlcRemovedMessage": "{0} 个失效的DLC已移除",
"AutoloadUpdateAddedMessage": "{0} 个游戏更新被添加",
- "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
- "ModWindowHeading": "{0} Mod(s)",
+ "AutoloadUpdateRemovedMessage": "{0} 个失效的游戏更新已移除",
+ "ModWindowHeading": "{0} Mod",
"UserProfilesEditProfile": "编辑所选",
"Cancel": "取消",
"Save": "保存",
@@ -770,7 +770,7 @@
"SettingsEnableMacroHLE": "启用 HLE 宏加速",
"SettingsEnableMacroHLETooltip": "GPU 宏指令的高级模拟。\n\n提高性能表现,但一些游戏可能会出现图形错误。\n\n如果不确定,请保持开启状态。",
"SettingsEnableColorSpacePassthrough": "色彩空间直通",
- "SettingsEnableColorSpacePassthroughTooltip": "使 Vulkan 图形引擎直接传输原始色彩信息。对于宽色域 (例如 DCI-P3) 显示器的用户来说,可以产生更鲜艳的颜色,代价是会损失部分色彩准确度。",
+ "SettingsEnableColorSpacePassthroughTooltip": "使 Vulkan 图形引擎直接传输原始色彩信息。对于广色域 (例如 DCI-P3) 显示器的用户来说,可以产生更鲜艳的颜色,代价是损失部分色彩准确度。",
"VolumeShort": "音量",
"UserProfilesManageSaves": "管理存档",
"DeleteUserSave": "确定删除此游戏的用户存档吗?",
@@ -789,9 +789,9 @@
"GraphicsScalingFilterLabel": "缩放过滤:",
"GraphicsScalingFilterTooltip": "选择在分辨率缩放时将使用的缩放过滤器。\n\nBilinear(双线性过滤)对于3D游戏效果较好,是一个安全的默认选项。\n\nNearest(最近邻过滤)推荐用于像素艺术游戏。\n\nFSR(超级分辨率锐画)只是一个锐化过滤器,不推荐与 FXAA 或 SMAA 抗锯齿一起使用。\n\nArea(局部过滤),当渲染分辨率大于窗口实际分辨率,推荐该选项。该选项在渲染比例大于2.0的情况下,可以实现超采样的效果。\n\n在游戏运行时,通过点击下面的“应用”按钮可以使设置生效;你可以将设置窗口移开,并试验找到您喜欢的游戏画面效果。\n\n如果不确定,请保持为“Bilinear(双线性过滤)”。",
"GraphicsScalingFilterBilinear": "Bilinear(双线性过滤)",
- "GraphicsScalingFilterNearest": "Nearest(最近邻过滤)",
+ "GraphicsScalingFilterNearest": "Nearest(邻近过滤)",
"GraphicsScalingFilterFsr": "FSR(超级分辨率锐画技术)",
- "GraphicsScalingFilterArea": "Area(局部过滤)",
+ "GraphicsScalingFilterArea": "Area(区域过滤)",
"GraphicsScalingFilterLevelLabel": "等级",
"GraphicsScalingFilterLevelTooltip": "设置 FSR 1.0 的锐化等级,数值越高,图像越锐利。",
"SmaaLow": "SMAA 低质量",
@@ -808,7 +808,7 @@
"AboutChangelogButtonTooltipMessage": "点击这里在浏览器中打开此版本的更新日志。",
"SettingsTabNetworkMultiplayer": "多人联机游玩",
"MultiplayerMode": "联机模式:",
- "MultiplayerModeTooltip": "修改 LDN 多人联机游玩模式。\n\nldn_mitm 联机插件将修改游戏中的本地无线和本地游玩功能,使其表现得像局域网一样,允许和其他安装了 ldn_mitm 插件的 Ryujinx 模拟器和破解的任天堂 Switch 主机在同一网络下进行本地连接,实现多人联机游玩。\n\n多人联机游玩要求所有玩家必须运行相同的游戏版本(例如,任天堂明星大乱斗特别版 v13.0.1 无法与 v13.0.0 版本联机)。\n\n如果不确定,请保持为“禁用”。",
+ "MultiplayerModeTooltip": "修改 LDN 多人联机游玩模式。\n\nldn_mitm 联机插件将修改游戏中的本地无线和本地游玩功能,使其表现得像局域网一样,允许和其他安装了 ldn_mitm 插件的 Ryujinx 模拟器和破解的任天堂 Switch 主机在同一网络下进行本地连接,实现多人联机游玩。\n\n多人联机游玩要求所有玩家必须运行相同的游戏版本(例如,游戏版本 v13.0.1 无法与 v13.0.0 联机)。\n\n如果不确定,请保持为“禁用”。",
"MultiplayerModeDisabled": "禁用",
"MultiplayerModeLdnMitm": "ldn_mitm"
}
From 8444e4dca01a4d3831655c909ef1647c8a6e68b0 Mon Sep 17 00:00:00 2001
From: Nicola <61830443+nicola02nb@users.noreply.github.com>
Date: Tue, 19 Nov 2024 09:16:15 +0100
Subject: [PATCH 10/33] Fixed mime types button not updating after
install/uninstall (#241)
---
src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs | 10 ++++++++--
src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs | 6 ++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index 53263847b..f1587a0ff 100644
--- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
@@ -102,6 +102,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private float _volumeBeforeMute;
private string _backendText;
+ private bool _areMimeTypesRegistered = FileAssociationHelper.AreMimeTypesRegistered;
private bool _canUpdate = true;
private Cursor _cursor;
private string _title;
@@ -804,10 +805,15 @@ namespace Ryujinx.Ava.UI.ViewModels
{
get => FileAssociationHelper.IsTypeAssociationSupported;
}
-
+
public bool AreMimeTypesRegistered
{
- get => FileAssociationHelper.AreMimeTypesRegistered;
+ get => _areMimeTypesRegistered;
+ set {
+ _areMimeTypesRegistered = value;
+
+ OnPropertyChanged();
+ }
}
public ObservableCollectionExtended Applications
diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
index 144ab408f..41b27e9c1 100644
--- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -165,7 +165,8 @@ namespace Ryujinx.Ava.UI.Views.Main
private async void InstallFileTypes_Click(object sender, RoutedEventArgs e)
{
- if (FileAssociationHelper.Install())
+ ViewModel.AreMimeTypesRegistered = FileAssociationHelper.Install();
+ if (ViewModel.AreMimeTypesRegistered)
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
else
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogInstallFileTypesErrorMessage]);
@@ -173,7 +174,8 @@ namespace Ryujinx.Ava.UI.Views.Main
private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e)
{
- if (FileAssociationHelper.Uninstall())
+ ViewModel.AreMimeTypesRegistered = !FileAssociationHelper.Uninstall();
+ if (!ViewModel.AreMimeTypesRegistered)
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesSuccessMessage], string.Empty, LocaleManager.Instance[LocaleKeys.InputDialogOk], string.Empty, string.Empty);
else
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUninstallFileTypesErrorMessage]);
From fda79efed4bfd00582fb749fc575c8a43752087b Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Tue, 19 Nov 2024 09:30:41 -0600
Subject: [PATCH 11/33] Fix Windows builds not being uploaded
---
.github/workflows/release.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 183d4c618..d1ea8e449 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -174,7 +174,7 @@ jobs:
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
- artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
+ artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
omitBodyDuringUpdate: true
From c3831428e08e9299ab7104a4e4c5354533c2efbf Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Tue, 19 Nov 2024 10:22:11 -0600
Subject: [PATCH 12/33] Try and fix weird nullref
---
src/Ryujinx.UI.Common/Helper/FileAssociationHelper.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Ryujinx.UI.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.UI.Common/Helper/FileAssociationHelper.cs
index be10deca0..9333a1b76 100644
--- a/src/Ryujinx.UI.Common/Helper/FileAssociationHelper.cs
+++ b/src/Ryujinx.UI.Common/Helper/FileAssociationHelper.cs
@@ -101,13 +101,13 @@ namespace Ryujinx.UI.Common.Helper
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
- if (key is null)
+ var openCmd = key?.OpenSubKey(@"shell\open\command");
+
+ if (openCmd is null)
{
return false;
}
-
- var openCmd = key.OpenSubKey(@"shell\open\command");
-
+
string keyValue = (string)openCmd.GetValue(string.Empty);
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
From c0a4d95c5d984df4a862a62d21f5090fb88a32de Mon Sep 17 00:00:00 2001
From: Luke Warner <65521430+LukeWarnut@users.noreply.github.com>
Date: Tue, 19 Nov 2024 14:02:24 -0500
Subject: [PATCH 13/33] ARMeilleure: Implement TPIDR2_EL0 (#280)
This is an implementation of the TPIDR2_EL0 register. There may be more
potential use-cases for this register not included in this PR, but this
implements the use-case seen in SuperTuxKart.
---
src/ARMeilleure/Instructions/InstEmitSystem.cs | 17 +++++++++++++++++
src/ARMeilleure/State/NativeContext.cs | 9 +++++++++
2 files changed, 26 insertions(+)
diff --git a/src/ARMeilleure/Instructions/InstEmitSystem.cs b/src/ARMeilleure/Instructions/InstEmitSystem.cs
index 8c430fc23..fbf3b4a70 100644
--- a/src/ARMeilleure/Instructions/InstEmitSystem.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSystem.cs
@@ -49,6 +49,9 @@ namespace ARMeilleure.Instructions
case 0b11_011_1101_0000_011:
EmitGetTpidrroEl0(context);
return;
+ case 0b11_011_1101_0000_101:
+ EmitGetTpidr2El0(context);
+ return;
case 0b11_011_1110_0000_000:
info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0));
break;
@@ -84,6 +87,9 @@ namespace ARMeilleure.Instructions
case 0b11_011_1101_0000_010:
EmitSetTpidrEl0(context);
return;
+ case 0b11_011_1101_0000_101:
+ EmitGetTpidr2El0(context);
+ return;
default:
throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
@@ -213,6 +219,17 @@ namespace ARMeilleure.Instructions
SetIntOrZR(context, op.Rt, result);
}
+ private static void EmitGetTpidr2El0(ArmEmitterContext context)
+ {
+ OpCodeSystem op = (OpCodeSystem)context.CurrOp;
+
+ Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
+
+ Operand result = context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetTpidr2El0Offset())));
+
+ SetIntOrZR(context, op.Rt, result);
+ }
+
private static void EmitSetNzcv(ArmEmitterContext context)
{
OpCodeSystem op = (OpCodeSystem)context.CurrOp;
diff --git a/src/ARMeilleure/State/NativeContext.cs b/src/ARMeilleure/State/NativeContext.cs
index 628efde41..140b6f7a7 100644
--- a/src/ARMeilleure/State/NativeContext.cs
+++ b/src/ARMeilleure/State/NativeContext.cs
@@ -21,6 +21,7 @@ namespace ARMeilleure.State
public ulong ExclusiveValueLow;
public ulong ExclusiveValueHigh;
public int Running;
+ public long Tpidr2El0;
}
private static NativeCtxStorage _dummyStorage = new();
@@ -176,6 +177,9 @@ namespace ARMeilleure.State
public long GetTpidrroEl0() => GetStorage().TpidrroEl0;
public void SetTpidrroEl0(long value) => GetStorage().TpidrroEl0 = value;
+ public long GetTpidr2El0() => GetStorage().Tpidr2El0;
+ public void SetTpidr2El0(long value) => GetStorage().Tpidr2El0 = value;
+
public int GetCounter() => GetStorage().Counter;
public void SetCounter(int value) => GetStorage().Counter = value;
@@ -232,6 +236,11 @@ namespace ARMeilleure.State
return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0);
}
+ public static int GetTpidr2El0Offset()
+ {
+ return StorageOffset(ref _dummyStorage, ref _dummyStorage.Tpidr2El0);
+ }
+
public static int GetCounterOffset()
{
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter);
From 150e06e0de20305b521b838fbe5b63379878cc85 Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Wed, 20 Nov 2024 18:52:16 +0100
Subject: [PATCH 14/33] Add `documentation` and `ldn` labels to `labeler.yml`
(#282)
This should make it so that any changes made to ldn and documentation
related files should be auto-labeled
---
.github/labeler.yml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 54f2757b0..871f9945f 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -33,3 +33,11 @@ kernel:
infra:
- changed-files:
- any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props']
+
+documentation:
+- changed-files:
+ - any-glob-to-any-file: 'docs/**'
+
+ldn:
+- changed-files:
+ - any-glob-to-any-file: 'src/Ryujinx.HLE/HOS/Services/Ldn/**'
From aaaf60b7a4e7793c137019459ab7ef7c8f20c91e Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Wed, 20 Nov 2024 19:20:38 +0100
Subject: [PATCH 15/33] Change headless to nogui in the release artifacts
(#285)
This makes it so that instead of the files you download being
`sdl2-ryujinx-headless` they are now `nogui-ryujinx`in the release (and
canary) artifacts
---
.github/workflows/build.yml | 4 ++--
.github/workflows/canary.yml | 4 ++--
.github/workflows/nightly_pr_comment.yml | 4 ++--
.github/workflows/release.yml | 4 ++--
distribution/macos/create_macos_build_headless.sh | 4 ++--
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b678e5f8e..21dc3eb0b 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -122,7 +122,7 @@ jobs:
- name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v4
with:
- name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
+ name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
path: publish_sdl2_headless
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
@@ -185,6 +185,6 @@ jobs:
- name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v4
with:
- name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
+ name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
path: "publish_headless/*.tar.gz"
if: github.event_name == 'pull_request'
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
index d102beaa3..72e1b9515 100644
--- a/.github/workflows/canary.yml
+++ b/.github/workflows/canary.yml
@@ -116,7 +116,7 @@ jobs:
pushd publish_sdl2_headless
rm publish/libarmeilleure-jitsupport.dylib
- 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
+ 7z a ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
shell: bash
@@ -132,7 +132,7 @@ jobs:
pushd publish_sdl2_headless
rm publish/libarmeilleure-jitsupport.dylib
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
- tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
+ tar -czvf ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
shell: bash
diff --git a/.github/workflows/nightly_pr_comment.yml b/.github/workflows/nightly_pr_comment.yml
index 64705b6ee..85a6e2de4 100644
--- a/.github/workflows/nightly_pr_comment.yml
+++ b/.github/workflows/nightly_pr_comment.yml
@@ -38,12 +38,12 @@ jobs:
return core.error(`No artifacts found`);
}
let body = `Download the artifacts for this pull request:\n`;
- let hidden_headless_artifacts = `\n\n GUI-less (SDL2)\n`;
+ let hidden_headless_artifacts = `\n\n GUI-less\n`;
let hidden_debug_artifacts = `\n\n Only for Developers\n`;
for (const art of artifacts) {
if(art.name.includes('Debug')) {
hidden_debug_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
- } else if(art.name.includes('sdl2-ryujinx-headless')) {
+ } else if(art.name.includes('nogui-ryujinx')) {
hidden_headless_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
} else {
body += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d1ea8e449..44b1de09b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -115,7 +115,7 @@ jobs:
pushd publish_sdl2_headless
rm libarmeilleure-jitsupport.dylib
- 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
+ 7z a ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd
shell: bash
@@ -166,7 +166,7 @@ jobs:
pushd publish_sdl2_headless
chmod +x Ryujinx.sh Ryujinx.Headless.SDL2
- tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
+ tar -czvf ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd
shell: bash
diff --git a/distribution/macos/create_macos_build_headless.sh b/distribution/macos/create_macos_build_headless.sh
index 2715699d0..24836418d 100755
--- a/distribution/macos/create_macos_build_headless.sh
+++ b/distribution/macos/create_macos_build_headless.sh
@@ -22,9 +22,9 @@ EXTRA_ARGS=$8
if [ "$VERSION" == "1.1.0" ];
then
- RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
+ RELEASE_TAR_FILE_NAME=nogui-ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
else
- RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$VERSION-macos_universal.tar
+ RELEASE_TAR_FILE_NAME=nogui-ryujinx-$VERSION-macos_universal.tar
fi
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
From c2de5cc700e1ae6beefe3d8866b7cdadb0c7c5ba Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Thu, 21 Nov 2024 10:16:13 -0600
Subject: [PATCH 16/33] Fix really obvious typo, lol
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 3bc223f3a..f6783b412 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@
Guides and documentation can be found on the Wiki tab.
- If you would like a version more preservative fork of Ryujinx, check out ryujinx-mirror.
+ If you would like a more preservative fork of Ryujinx, check out ryujinx-mirror.
From 1d42c29335a87bd5ac2c53a5aa1edf948f211f4b Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Thu, 21 Nov 2024 19:34:53 +0100
Subject: [PATCH 17/33] Add more mentions of canary (#258)
This should hopefully make it clearer whether or not you're using
canary.
Changelog:
- Changed github workflows to have "canary" in the zip files
- Added `App.FullAppName` in the about section, so that it's clear in
there too
- Changed log name for canary builds to
`Ryujinx_Canary_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log`
(normal builds should still be
"Ryujinx_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log)
---
.github/workflows/canary.yml | 12 ++++++------
.github/workflows/release.yml | 4 ++--
distribution/macos/create_macos_build_ava.sh | 13 +++++++------
distribution/macos/create_macos_build_headless.sh | 13 +++++++------
src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs | 3 ++-
src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs | 2 +-
6 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
index 72e1b9515..a24436de3 100644
--- a/.github/workflows/canary.yml
+++ b/.github/workflows/canary.yml
@@ -111,12 +111,12 @@ jobs:
run: |
pushd publish_ava
rm publish/libarmeilleure-jitsupport.dylib
- 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
+ 7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
pushd publish_sdl2_headless
rm publish/libarmeilleure-jitsupport.dylib
- 7z a ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
+ 7z a ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
shell: bash
@@ -126,13 +126,13 @@ jobs:
pushd publish_ava
rm publish/libarmeilleure-jitsupport.dylib
chmod +x publish/Ryujinx.sh publish/Ryujinx
- tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
+ tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
pushd publish_sdl2_headless
rm publish/libarmeilleure-jitsupport.dylib
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
- tar -czvf ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
+ tar -czvf ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
shell: bash
@@ -236,11 +236,11 @@ jobs:
- name: Publish macOS Ryujinx
run: |
- ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
+ ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
- ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
+ ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
- name: Pushing new release
uses: ncipollo/release-action@v1
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 44b1de09b..ec02976a1 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -231,11 +231,11 @@ jobs:
- name: Publish macOS Ryujinx
run: |
- ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
+ ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
- ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
+ ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
- name: Pushing new release
uses: ncipollo/release-action@v1
diff --git a/distribution/macos/create_macos_build_ava.sh b/distribution/macos/create_macos_build_ava.sh
index 80bd6662c..b19fa4863 100755
--- a/distribution/macos/create_macos_build_ava.sh
+++ b/distribution/macos/create_macos_build_ava.sh
@@ -2,8 +2,8 @@
set -e
-if [ "$#" -lt 7 ]; then
- echo "usage "
+if [ "$#" -lt 8 ]; then
+ echo "usage "
exit 1
fi
@@ -18,10 +18,11 @@ ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
VERSION=$5
SOURCE_REVISION_ID=$6
CONFIGURATION=$7
-EXTRA_ARGS=$8
+CANARY=$8
-if [ "$VERSION" == "1.1.0" ];
-then
+if [ "$CANARY" == "1" ]; then
+ RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar
+elif [ "$VERSION" == "1.1.0" ]; then
RELEASE_TAR_FILE_NAME=ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.app.tar
else
RELEASE_TAR_FILE_NAME=ryujinx-$VERSION-macos_universal.app.tar
@@ -61,7 +62,7 @@ mkdir -p "$OUTPUT_DIRECTORY"
cp -R "$ARM64_APP_BUNDLE" "$UNIVERSAL_APP_BUNDLE"
rm "$UNIVERSAL_APP_BUNDLE/$EXECUTABLE_SUB_PATH"
-# Make it libraries universal
+# Make its libraries universal
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_APP_BUNDLE" "$X64_APP_BUNDLE" "$UNIVERSAL_APP_BUNDLE" "**/*.dylib"
if ! [ -x "$(command -v lipo)" ];
diff --git a/distribution/macos/create_macos_build_headless.sh b/distribution/macos/create_macos_build_headless.sh
index 24836418d..01951d878 100755
--- a/distribution/macos/create_macos_build_headless.sh
+++ b/distribution/macos/create_macos_build_headless.sh
@@ -2,8 +2,8 @@
set -e
-if [ "$#" -lt 7 ]; then
- echo "usage "
+if [ "$#" -lt 8 ]; then
+ echo "usage "
exit 1
fi
@@ -18,10 +18,11 @@ ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
VERSION=$5
SOURCE_REVISION_ID=$6
CONFIGURATION=$7
-EXTRA_ARGS=$8
+CANARY=$8
-if [ "$VERSION" == "1.1.0" ];
-then
+if [ "$CANARY" == "1" ]; then
+ RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar
+elif [ "$VERSION" == "1.1.0" ]; then
RELEASE_TAR_FILE_NAME=nogui-ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
else
RELEASE_TAR_FILE_NAME=nogui-ryujinx-$VERSION-macos_universal.tar
@@ -56,7 +57,7 @@ mkdir -p "$OUTPUT_DIRECTORY"
cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
-# Make it libraries universal
+# Make its libraries universal
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
if ! [ -x "$(command -v lipo)" ];
diff --git a/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs b/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
index 631df3056..94e9359c8 100644
--- a/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
+++ b/src/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
@@ -69,9 +69,10 @@ namespace Ryujinx.Common.Logging.Targets
}
string version = ReleaseInformation.Version;
+ string appName = ReleaseInformation.IsCanaryBuild ? "Ryujinx_Canary" : "Ryujinx";
// Get path for the current time
- path = Path.Combine(logDir.FullName, $"Ryujinx_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log");
+ path = Path.Combine(logDir.FullName, $"{appName}_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log");
try
{
diff --git a/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
index 236711c31..c48ad378f 100644
--- a/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
@@ -49,7 +49,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public AboutWindowViewModel()
{
- Version = Program.Version;
+ Version = App.FullAppName + "\n" + Program.Version;
UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value);
ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
From e2b7738465cc3b753ff255d0e10ed63fb6895058 Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Fri, 22 Nov 2024 18:07:47 +0100
Subject: [PATCH 18/33] Add all the missing locales from XCI Trimmer and LDN
merge (#281)
Hello any fellow developers that may be reading this. Whenever you add
any new locales to `en_US.json`, please make sure to add them to the
rest of the locale files. I will not always be there to add them myself.
---
src/Ryujinx/Assets/Locales/ar_SA.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/de_DE.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/el_GR.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/es_ES.json | 40 +++++++++++++++++++
src/Ryujinx/Assets/Locales/fr_FR.json | 56 ++++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/he_IL.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/it_IT.json | 14 ++++++-
src/Ryujinx/Assets/Locales/ja_JP.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/pl_PL.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/pt_BR.json | 55 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/ru_RU.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/th_TH.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/tr_TR.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/uk_UA.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/zh_CN.json | 54 +++++++++++++++++++++++++-
src/Ryujinx/Assets/Locales/zh_TW.json | 54 +++++++++++++++++++++++++-
16 files changed, 797 insertions(+), 16 deletions(-)
diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json
index 781568fee..6dbc96135 100644
--- a/src/Ryujinx/Assets/Locales/ar_SA.json
+++ b/src/Ryujinx/Assets/Locales/ar_SA.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "إدارة أنواع الملفات",
"MenuBarToolsInstallFileTypes": "تثبيت أنواع الملفات",
"MenuBarToolsUninstallFileTypes": "إزالة أنواع الملفات",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_عرض",
"MenuBarViewWindow": "حجم النافذة",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "يفتح المجلد الذي يحتوي على تعديلات(mods) التطبيق",
"GameListContextMenuOpenSdModsDirectory": "فتح مجلد تعديلات(mods) أتموسفير",
"GameListContextMenuOpenSdModsDirectoryToolTip": "يفتح مجلد أتموسفير لبطاقة SD البديلة الذي يحتوي على تعديلات التطبيق. مفيد للتعديلات التي تم تعبئتها للأجهزة الحقيقية.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} لعبة تم تحميلها",
"StatusBarSystemVersion": "إصدار النظام: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "الحد الأدنى لتعيينات الذاكرة المكتشفة",
"LinuxVmMaxMapCountDialogTextPrimary": "هل ترغب في زيادة قيمة vm.max_map_count إلى {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "قد تحاول بعض الألعاب إنشاء المزيد من تعيينات الذاكرة أكثر مما هو مسموح به حاليا. سيغلق ريوجينكس بمجرد تجاوز هذا الحد.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "حوار الإدخال",
"InputDialogOk": "موافق",
"InputDialogCancel": "إلغاء",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "اختر اسم الملف الشخصي",
"InputDialogAddNewProfileHeader": "الرجاء إدخال اسم الملف الشخصي",
"InputDialogAddNewProfileSubtext": "(الطول الأقصى: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "تم إلغاء تثبيت أنواع الملفات بنجاح!",
"DialogUninstallFileTypesErrorMessage": "فشل إلغاء تثبيت أنواع الملفات.",
"DialogOpenSettingsWindowLabel": "فتح نافذة الإعدادات",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "تطبيق وحدة التحكم المصغر",
"DialogMessageDialogErrorExceptionMessage": "خطأ في عرض مربع حوار الرسالة: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "خطأ في عرض لوحة مفاتيح البرامج: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "الإصدار: {0}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "ريوجينكس - معلومات",
"RyujinxConfirm": "ريوجينكس - تأكيد",
"FileDialogAllTypes": "كل الأنواع",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "حدد ملفات المحتوي الإضافي",
"SelectUpdateDialogTitle": "حدد ملفات التحديث",
"SelectModDialogTitle": "حدد مجلد التعديل",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "مدير الملفات الشخصية للمستخدمين",
"CheatWindowTitle": "مدير الغش",
"DlcWindowTitle": "إدارة المحتوى القابل للتنزيل لـ {0} ({1})",
"ModWindowTitle": "إدارة التعديلات لـ {0} ({1})",
"UpdateWindowTitle": "مدير تحديث العنوان",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} تعديل",
"UserProfilesEditProfile": "تعديل المحدد",
+ "Continue": "Continue",
"Cancel": "إلغاء",
"Save": "حفظ",
"Discard": "تجاهل",
@@ -810,5 +850,17 @@
"MultiplayerMode": "الوضع:",
"MultiplayerModeTooltip": "تغيير وضع LDN متعدد اللاعبين.\n\nسوف يقوم LdnMitm بتعديل وظيفة اللعب المحلية/اللاسلكية المحلية في الألعاب لتعمل كما لو كانت شبكة LAN، مما يسمح باتصالات الشبكة المحلية نفسها مع محاكيات ريوجينكس الأخرى وأجهزة نينتندو سويتش المخترقة التي تم تثبيت وحدة ldn_mitm عليها.\n\nيتطلب وضع اللاعبين المتعددين أن يكون جميع اللاعبين على نفس إصدار اللعبة (على سبيل المثال، يتعذر على الإصدار 13.0.1 من سوبر سماش برذرز ألتميت الاتصال بالإصدار 13.0.0).\n\nاتركه معطلا إذا لم تكن متأكدا.",
"MultiplayerModeDisabled": "معطل",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index c6f9768c6..be95f3bc0 100644
--- a/src/Ryujinx/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Dateitypen verwalten",
"MenuBarToolsInstallFileTypes": "Dateitypen installieren",
"MenuBarToolsUninstallFileTypes": "Dateitypen deinstallieren",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_Ansicht",
"MenuBarViewWindow": "Fenstergröße",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Öffnet das Verzeichnis, welches Mods für die Spiele beinhaltet",
"GameListContextMenuOpenSdModsDirectory": "Atmosphere-Mod-Verzeichnis öffnen",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Öffnet das alternative SD-Karten-Atmosphere-Verzeichnis, das die Mods der Anwendung enthält. Dieser Ordner ist nützlich für Mods, die für echte Hardware erstellt worden sind.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} Spiele geladen",
"StatusBarSystemVersion": "Systemversion: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Niedriges Limit für Speicherzuordnungen erkannt",
"LinuxVmMaxMapCountDialogTextPrimary": "Möchtest Du den Wert von vm.max_map_count auf {0} erhöhen",
"LinuxVmMaxMapCountDialogTextSecondary": "Einige Spiele könnten versuchen, mehr Speicherzuordnungen zu erstellen, als derzeit erlaubt. Ryujinx wird abstürzen, sobald dieses Limit überschritten wird.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Eingabe-Dialog",
"InputDialogOk": "OK",
"InputDialogCancel": "Abbrechen",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Wähle den Profilnamen",
"InputDialogAddNewProfileHeader": "Bitte gebe einen Profilnamen ein",
"InputDialogAddNewProfileSubtext": "(Maximale Länge: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Dateitypen erfolgreich deinstalliert!",
"DialogUninstallFileTypesErrorMessage": "Deinstallation der Dateitypen fehlgeschlagen.",
"DialogOpenSettingsWindowLabel": "Fenster-Einstellungen öffnen",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Controller-Applet",
"DialogMessageDialogErrorExceptionMessage": "Fehler bei der Anzeige des Meldungs-Dialogs: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Fehler bei der Anzeige der Software-Tastatur: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Version {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Bestätigung",
"FileDialogAllTypes": "Alle Typen",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "DLC-Dateien auswählen",
"SelectUpdateDialogTitle": "Update-Datei auswählen",
"SelectModDialogTitle": "Mod-Ordner auswählen",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Benutzerprofile verwalten",
"CheatWindowTitle": "Spiel-Cheats verwalten",
"DlcWindowTitle": "Spiel-DLC verwalten",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "Spiel-Updates verwalten",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Profil bearbeiten",
+ "Continue": "Continue",
"Cancel": "Abbrechen",
"Save": "Speichern",
"Discard": "Verwerfen",
@@ -810,5 +850,17 @@
"MultiplayerMode": "Modus:",
"MultiplayerModeTooltip": "Ändert den LDN-Mehrspielermodus.\n\nLdnMitm ändert die lokale drahtlose/lokale Spielfunktionalität in Spielen so, dass sie wie ein LAN funktioniert und lokale, netzwerkgleiche Verbindungen mit anderen Ryujinx-Instanzen und gehackten Nintendo Switch-Konsolen ermöglicht, auf denen das ldn_mitm-Modul installiert ist.\n\nMultiplayer erfordert, dass alle Spieler die gleiche Spielversion verwenden (d.h. Super Smash Bros. Ultimate v13.0.1 kann sich nicht mit v13.0.0 verbinden).\n\nIm Zweifelsfall auf DISABLED lassen.",
"MultiplayerModeDisabled": "Deaktiviert",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index 76049fc3f..c6cfb9d62 100644
--- a/src/Ryujinx/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Διαχείριση τύπων αρχείων",
"MenuBarToolsInstallFileTypes": "Εγκαταστήσετε τύπους αρχείων.",
"MenuBarToolsUninstallFileTypes": "Απεγκαταστήσετε τύπους αρχείων",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Window Size",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
"GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} Φορτωμένα Παιχνίδια",
"StatusBarSystemVersion": "Έκδοση Συστήματος: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Εντοπίστηκε χαμηλό όριο για αντιστοιχίσεις μνήμης",
"LinuxVmMaxMapCountDialogTextPrimary": "Θα θέλατε να αυξήσετε την τιμή του vm.max_map_count σε {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "Μερικά παιχνίδια μπορεί να προσπαθήσουν να δημιουργήσουν περισσότερες αντιστοιχίσεις μνήμης από αυτές που επιτρέπονται τώρα. Ο Ryujinx θα καταρρεύσει μόλις ξεπεραστεί αυτό το όριο.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Διάλογος Εισαγωγής",
"InputDialogOk": "ΟΚ",
"InputDialogCancel": "Ακύρωση",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Επιλογή Ονόματος Προφίλ",
"InputDialogAddNewProfileHeader": "Εισαγωγή Ονόματος Προφίλ",
"InputDialogAddNewProfileSubtext": "(Σύνολο Χαρακτήρων: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Επιτυχής απεγκατάσταση τύπων αρχείων!",
"DialogUninstallFileTypesErrorMessage": "Αποτυχία απεγκατάστασης τύπων αρχείων.",
"DialogOpenSettingsWindowLabel": "Άνοιγμα Παραθύρου Ρυθμίσεων",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Applet Χειρισμού",
"DialogMessageDialogErrorExceptionMessage": "Σφάλμα εμφάνισης του διαλόγου Μηνυμάτων: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Σφάλμα εμφάνισης Λογισμικού Πληκτρολογίου: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Version {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Πληροφορίες",
"RyujinxConfirm": "Ryujinx - Επιβεβαίωση",
"FileDialogAllTypes": "Όλοι οι τύποι",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "Επιλογή αρχείων DLC",
"SelectUpdateDialogTitle": "Επιλογή αρχείων ενημέρωσης",
"SelectModDialogTitle": "Select mod directory",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Διαχειριστής Προφίλ Χρήστη",
"CheatWindowTitle": "Διαχειριστής των Cheats",
"DlcWindowTitle": "Downloadable Content Manager",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "Διαχειριστής Ενημερώσεων Τίτλου",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Επεξεργασία Επιλεγμένων",
+ "Continue": "Continue",
"Cancel": "Ακύρωση",
"Save": "Αποθήκευση",
"Discard": "Απόρριψη",
@@ -810,5 +850,17 @@
"MultiplayerMode": "Λειτουργία:",
"MultiplayerModeTooltip": "Change LDN multiplayer mode.\n\nLdnMitm will modify local wireless/local play functionality in games to function as if it were LAN, allowing for local, same-network connections with other Ryujinx instances and hacked Nintendo Switch consoles that have the ldn_mitm module installed.\n\nMultiplayer requires all players to be on the same game version (i.e. Super Smash Bros. Ultimate v13.0.1 can't connect to v13.0.0).\n\nLeave DISABLED if unsure.",
"MultiplayerModeDisabled": "Disabled",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index cf5c586d0..6a194960b 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Administrar tipos de archivo",
"MenuBarToolsInstallFileTypes": "Instalar tipos de archivo",
"MenuBarToolsUninstallFileTypes": "Desinstalar tipos de archivo",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Tamaño Ventana",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Abre el directorio que contiene los Mods de la Aplicación.",
"GameListContextMenuOpenSdModsDirectory": "Abrir Directorio de Mods de Atmosphere\n\n\n\n\n\n",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Abre el directorio alternativo de la tarjeta SD de Atmosphere que contiene los Mods de la Aplicación. Útil para los mods que están empaquetados para el hardware real.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} juegos cargados",
"StatusBarSystemVersion": "Versión del sistema: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Límite inferior para mapeos de memoria detectado",
"LinuxVmMaxMapCountDialogTextPrimary": "¿Quieres aumentar el valor de vm.max_map_count a {0}?",
"LinuxVmMaxMapCountDialogTextSecondary": "Algunos juegos podrían intentar crear más mapeos de memoria de los permitidos. Ryujinx se bloqueará tan pronto como se supere este límite.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Cuadro de diálogo de entrada",
"InputDialogOk": "Aceptar",
"InputDialogCancel": "Cancelar",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Introducir nombre de perfil",
"InputDialogAddNewProfileHeader": "Por favor elige un nombre de usuario",
"InputDialogAddNewProfileSubtext": "(Máximo de caracteres: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "¡Tipos de archivos desinstalados con éxito!",
"DialogUninstallFileTypesErrorMessage": "No se pudo desinstalar los tipos de archivo.",
"DialogOpenSettingsWindowLabel": "Abrir ventana de opciones",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Applet de mandos",
"DialogMessageDialogErrorExceptionMessage": "Error al mostrar cuadro de diálogo: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Error al mostrar teclado de software: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Versión {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Confirmación",
"FileDialogAllTypes": "Todos los tipos",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "Selecciona archivo(s) de DLC",
"SelectUpdateDialogTitle": "Selecciona archivo(s) de actualización",
"SelectModDialogTitle": "Seleccionar un directorio de Mods",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Administrar perfiles de usuario",
"CheatWindowTitle": "Administrar cheats",
"DlcWindowTitle": "Administrar contenido descargable",
"ModWindowTitle": "Administrar Mods para {0} ({1})",
"UpdateWindowTitle": "Administrar actualizaciones",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} nueva(s) actualización(es) agregada(s)",
@@ -742,6 +781,7 @@
"AutoloadUpdateRemovedMessage": "Se eliminaron {0} actualización(es) faltantes",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Editar selección",
+ "Continue": "Continue",
"Cancel": "Cancelar",
"Save": "Guardar",
"Discard": "Descartar",
diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json
index 0073a2cf5..dd23bef76 100644
--- a/src/Ryujinx/Assets/Locales/fr_FR.json
+++ b/src/Ryujinx/Assets/Locales/fr_FR.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Gérer les types de fichiers",
"MenuBarToolsInstallFileTypes": "Installer les types de fichiers",
"MenuBarToolsUninstallFileTypes": "Désinstaller les types de fichiers",
+ "MenuBarToolsXCITrimmer": "Réduire les fichiers XCI",
"MenuBarView": "_Fenêtre",
"MenuBarViewWindow": "Taille de la fenêtre",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Ouvre le dossier contenant les mods du jeu",
"GameListContextMenuOpenSdModsDirectory": "Ouvrir le dossier des mods Atmosphère",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Ouvre le dossier alternatif de la carte SD Atmosphère qui contient les mods de l'application. Utile pour les mods conçus pour console.",
+ "GameListContextMenuTrimXCI": "Vérifier et réduire les fichiers XCI",
+ "GameListContextMenuTrimXCIToolTip": "Vérifier et réduire les fichiers XCI pour économiser de l'espace",
"StatusBarGamesLoaded": "{0}/{1} Jeux chargés",
"StatusBarSystemVersion": "Version du Firmware: {0}",
+ "StatusBarXCIFileTrimming": "Réduction du fichier XCI '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Limite basse pour les mappings mémoire détectée",
"LinuxVmMaxMapCountDialogTextPrimary": "Voulez-vous augmenter la valeur de vm.max_map_count à {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "Certains jeux peuvent essayer de créer plus de mappings mémoire que ce qui est actuellement autorisé. Ryujinx plantera dès que cette limite sera dépassée.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Fenêtre d'entrée de texte",
"InputDialogOk": "OK",
"InputDialogCancel": "Annuler",
+ "InputDialogCancelling": "Annulation en cours",
+ "InputDialogClose": "Fermer",
"InputDialogAddNewProfileTitle": "Choisir un nom de profil",
"InputDialogAddNewProfileHeader": "Merci d'entrer un nom de profil",
"InputDialogAddNewProfileSubtext": "(Longueur max.: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Types de fichiers désinstallés avec succès!",
"DialogUninstallFileTypesErrorMessage": "Échec de la désinstallation des types de fichiers.",
"DialogOpenSettingsWindowLabel": "Ouvrir la fenêtre de configuration",
+ "DialogOpenXCITrimmerWindowLabel": "Fenêtre de réduction de fichiers XCI",
"DialogControllerAppletTitle": "Programme Manette",
"DialogMessageDialogErrorExceptionMessage": "Erreur lors de l'affichage de la boîte de dialogue : {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Erreur lors de l'affichage du clavier logiciel: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Version {0}",
"TitleBundledUpdateVersionLabel": "Inclus avec le jeu: Version {0}",
"TitleBundledDlcLabel": "Inclus avec le jeu :",
+ "TitleXCIStatusPartialLabel": "Partiel",
+ "TitleXCIStatusTrimmableLabel": "Non réduit",
+ "TitleXCIStatusUntrimmableLabel": "Réduit",
+ "TitleXCIStatusFailedLabel": "(Échoué)",
+ "TitleXCICanSaveLabel": "Sauvegarde de {0:n0} Mo",
+ "TitleXCISavingLabel": "Sauvegardé {0:n0} Mo",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Confirmation",
"FileDialogAllTypes": "Tous les types",
@@ -723,11 +736,39 @@
"SelectDlcDialogTitle": "Sélectionner les fichiers DLC",
"SelectUpdateDialogTitle": "Sélectionner les fichiers de mise à jour",
"SelectModDialogTitle": "Sélectionner le répertoire du mod",
+ "TrimXCIFileDialogTitle": "Vérifier et Réduire le fichier XCI",
+ "TrimXCIFileDialogPrimaryText": "Cette fonction va vérifier l'espace vide, puis réduire le fichier XCI pour économiser de l'espace de disque dur.",
+ "TrimXCIFileDialogSecondaryText": "Taille actuelle du fichier: {0:n} MB\nTaille des données de jeux: {1:n} MB\nÉconomie d'espaces sur le disque: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "Fichier XCI n'a pas besoin d'être réduit. Regarder les journaux pour plus de détails",
+ "TrimXCIFileNoUntrimPossible": "Fichier XCI ne peut pas être dé-réduit. Regarder les journaux pour plus de détails",
+ "TrimXCIFileReadOnlyFileCannotFix": "Fichier XCI est en Lecture Seule et n'a pas pu être rendu accessible en écriture. Regarder les journaux pour plus de détails",
+ "TrimXCIFileFileSizeChanged": "Fichier XCI a changé en taille depuis qu'il a été scanné. Vérifier que le fichier n'est pas en cours d'écriture et réessayer.",
+ "TrimXCIFileFreeSpaceCheckFailed": "Fichier XCI a des données dans la zone d'espace libre, ce n'est pas sûr de réduire",
+ "TrimXCIFileInvalidXCIFile": "Fichier XCI contient des données invalides. Regarder les journaux pour plus de détails",
+ "TrimXCIFileFileIOWriteError": "Fichier XCI n'a pas pu été ouvert pour écriture. Regarder les journaux pour plus de détails",
+ "TrimXCIFileFailedPrimaryText": "Réduction du fichier XCI a échoué",
+ "TrimXCIFileCancelled": "L'opération a été annulée",
+ "TrimXCIFileFileUndertermined": "Aucune opération a été faite",
"UserProfileWindowTitle": "Gestionnaire de profils utilisateur",
"CheatWindowTitle": "Gestionnaire de cheats",
"DlcWindowTitle": "Gérer le contenu téléchargeable pour {0} ({1})",
"ModWindowTitle": "Gérer les mods pour {0} ({1})",
"UpdateWindowTitle": "Gestionnaire de mises à jour",
+ "XCITrimmerWindowTitle": "Rogneur de fichier XCI",
+ "XCITrimmerTitleStatusCount": "{0} sur {1} Fichier(s) Sélectionnés",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} sur {1} Fichier(s) Sélectionnés ({2} affiché(s)",
+ "XCITrimmerTitleStatusTrimming": "Réduction de {0} Fichier(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Dé-Réduction de {0} Fichier(s)...",
+ "XCITrimmerTitleStatusFailed": "Échoué",
+ "XCITrimmerPotentialSavings": "Économies potentielles d'espace de disque dur",
+ "XCITrimmerActualSavings": "Économies actualles d'espace de disque dur",
+ "XCITrimmerSavingsMb": "{0:n0} Mo",
+ "XCITrimmerSelectDisplayed": "Sélectionner Affiché",
+ "XCITrimmerDeselectDisplayed": "Désélectionner Affiché",
+ "XCITrimmerSortName": "Titre",
+ "XCITrimmerSortSaved": "Économies de disque dur",
+ "XCITrimmerTrim": "Réduire",
+ "XCITrimmerUntrim": "Dé-Réduire",
"UpdateWindowUpdateAddedMessage": "{0} nouvelle(s) mise(s) à jour ajoutée(s)",
"UpdateWindowBundledContentNotice": "Les mises à jour incluses avec le jeu ne peuvent pas être supprimées mais peuvent être désactivées.",
"CheatWindowHeading": "Cheats disponibles pour {0} [{1}]",
@@ -741,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} mises à jour manquantes supprimées",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Éditer la sélection",
+ "Continue": "Continuer",
"Cancel": "Annuler",
"Save": "Enregistrer",
"Discard": "Abandonner",
@@ -808,5 +850,17 @@
"MultiplayerMode": "Mode :",
"MultiplayerModeTooltip": "Changer le mode multijoueur LDN.\n\nLdnMitm modifiera la fonctionnalité de jeu sans fil local/jeu local dans les jeux pour fonctionner comme s'il s'agissait d'un LAN, permettant des connexions locales sur le même réseau avec d'autres instances de Ryujinx et des consoles Nintendo Switch piratées ayant le module ldn_mitm installé.\n\nLe multijoueur nécessite que tous les joueurs soient sur la même version du jeu (par exemple, Super Smash Bros. Ultimate v13.0.1 ne peut pas se connecter à v13.0.0).\n\nLaissez DÉSACTIVÉ si vous n'êtes pas sûr.",
"MultiplayerModeDisabled": "Désactivé",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Désactiver PàP Hébergement de Réseau (pourrait augmenter la latence)",
+ "MultiplayerDisableP2PTooltip": "Désactiver PàP hébergement de réseau, les postes vont proxy avec le serveur principal au lieu de se connecter directement à vous.",
+ "LdnPassphrase": "Mot de passe Réseau :",
+ "LdnPassphraseTooltip": "Vous pourez seulement voir les jeux hébergé avec le même mot de passe que vous.",
+ "LdnPassphraseInputTooltip": "Entrer un mot de passe dans le format Ryujinx-<8 hex chars>. Vous pourez seulement voir les jeux hébergé avec le même mot de passe que vous.",
+ "LdnPassphraseInputPublic": "(publique)",
+ "GenLdnPass": "Générer Aléatoire",
+ "GenLdnPassTooltip": "Génére un nouveau mot de passe, qui peut être partagé avec les autres.",
+ "ClearLdnPass": "Supprimer",
+ "ClearLdnPassTooltip": "Supprime le mot de passe actuel, ce qui vous remet sur le réseau public.",
+ "InvalidLdnPassphrase": "Mot de passe invalide! Il doit être dans le format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index 91e3e24e4..b9f89eb37 100644
--- a/src/Ryujinx/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "ניהול סוגי קבצים",
"MenuBarToolsInstallFileTypes": "סוגי קבצי התקנה",
"MenuBarToolsUninstallFileTypes": "סוגי קבצי הסרה",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Window Size",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "פותח את התיקייה שמכילה מודים של האפליקציה",
"GameListContextMenuOpenSdModsDirectory": "פתח תיקיית מודים של Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "פותח את תיקיית כרטיס ה-SD החלופית של Atmosphere המכילה את המודים של האפליקציה. שימושי עבור מודים שארוזים עבור חומרה אמיתית.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{1}/{0} משחקים נטענו",
"StatusBarSystemVersion": "גרסת מערכת: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "זוהתה מגבלה נמוכה עבור מיפויי זיכרון",
"LinuxVmMaxMapCountDialogTextPrimary": "האם תרצה להגביר את הערך של vm.max_map_count ל{0}",
"LinuxVmMaxMapCountDialogTextSecondary": "משחקים מסוימים עלולים לייצר עוד מיפויי זיכרון ממה שמתאפשר. Ryujinx יקרוס ברגע שהמגבלה תחרוג.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "דיאלוג קלט",
"InputDialogOk": "בסדר",
"InputDialogCancel": "ביטול",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "בחרו את שם הפרופיל",
"InputDialogAddNewProfileHeader": "אנא הזינו שם לפרופיל",
"InputDialogAddNewProfileSubtext": "(אורך מרבי: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "סוגי קבצים הוסרו בהצלחה!",
"DialogUninstallFileTypesErrorMessage": "נכשל בהסרת סוגי קבצים.",
"DialogOpenSettingsWindowLabel": "פתח את חלון ההגדרות",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "יישומון בקר",
"DialogMessageDialogErrorExceptionMessage": "שגיאה בהצגת דיאלוג ההודעה: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "שגיאה בהצגת תוכנת המקלדת: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "גרסה {0}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "ריוג'ינקס - מידע",
"RyujinxConfirm": "ריוג'ינקס - אישור",
"FileDialogAllTypes": "כל הסוגים",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "בחרו קבצי הרחבות משחק",
"SelectUpdateDialogTitle": "בחרו קבצי עדכון",
"SelectModDialogTitle": "בחר תיקיית מודים",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "ניהול פרופילי משתמש",
"CheatWindowTitle": "נהל צ'יטים למשחק",
"DlcWindowTitle": "נהל הרחבות משחק עבור {0} ({1})",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "נהל עדכוני משחקים",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} מוד(ים)",
"UserProfilesEditProfile": "ערוך נבחר/ים",
+ "Continue": "Continue",
"Cancel": "בטל",
"Save": "שמור",
"Discard": "השלך",
@@ -810,5 +850,17 @@
"MultiplayerMode": "מצב:",
"MultiplayerModeTooltip": "Change LDN multiplayer mode.\n\nLdnMitm will modify local wireless/local play functionality in games to function as if it were LAN, allowing for local, same-network connections with other Ryujinx instances and hacked Nintendo Switch consoles that have the ldn_mitm module installed.\n\nMultiplayer requires all players to be on the same game version (i.e. Super Smash Bros. Ultimate v13.0.1 can't connect to v13.0.0).\n\nLeave DISABLED if unsure.",
"MultiplayerModeDisabled": "Disabled",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index 2a92e70dc..f10dd9d35 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -850,5 +850,17 @@
"MultiplayerMode": "Modalità:",
"MultiplayerModeTooltip": "Cambia la modalità multigiocatore LDN.\n\nLdnMitm modificherà la funzionalità locale wireless/local play nei giochi per funzionare come se fosse in modalità LAN, consentendo connessioni locali sulla stessa rete con altre istanze di Ryujinx e console Nintendo Switch modificate che hanno il modulo ldn_mitm installato.\n\nLa modalità multigiocatore richiede che tutti i giocatori usino la stessa versione del gioco (es. Super Smash Bros. Ultimate v13.0.1 non può connettersi con la v13.0.0).\n\nNel dubbio, lascia l'opzione su Disabilitato.",
"MultiplayerModeDisabled": "Disabilitato",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index b8e5870a6..34253acbf 100644
--- a/src/Ryujinx/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "ファイル形式を管理",
"MenuBarToolsInstallFileTypes": "ファイル形式をインストール",
"MenuBarToolsUninstallFileTypes": "ファイル形式をアンインストール",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Window Size",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "アプリケーションの Mod データを格納するディレクトリを開きます",
"GameListContextMenuOpenSdModsDirectory": "Atmosphere Mods ディレクトリを開く",
"GameListContextMenuOpenSdModsDirectoryToolTip": "アプリケーションの Mod データを格納する SD カードの Atmosphere ディレクトリを開きます. 実際のハードウェア用に作成された Mod データに有用です.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} ゲーム",
"StatusBarSystemVersion": "システムバージョン: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "メモリマッピング上限値が小さすぎます",
"LinuxVmMaxMapCountDialogTextPrimary": "vm.max_map_count の値を {0}に増やしますか?",
"LinuxVmMaxMapCountDialogTextSecondary": "ゲームによっては, 現在許可されているサイズより大きなメモリマッピングを作成しようとすることがあります. この制限を超えると, Ryjinx はすぐにクラッシュします.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "入力ダイアログ",
"InputDialogOk": "OK",
"InputDialogCancel": "キャンセル",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "プロファイル名を選択",
"InputDialogAddNewProfileHeader": "プロファイル名を入力してください",
"InputDialogAddNewProfileSubtext": "(最大長: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "ファイル形式のアンインストールに成功しました!",
"DialogUninstallFileTypesErrorMessage": "ファイル形式のアンインストールに失敗しました.",
"DialogOpenSettingsWindowLabel": "設定ウインドウを開く",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "コントローラアプレット",
"DialogMessageDialogErrorExceptionMessage": "メッセージダイアログ表示エラー: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "ソフトウェアキーボード表示エラー: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "バージョン {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - 情報",
"RyujinxConfirm": "Ryujinx - 確認",
"FileDialogAllTypes": "すべての種別",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "DLC ファイルを選択",
"SelectUpdateDialogTitle": "アップデートファイルを選択",
"SelectModDialogTitle": "modディレクトリを選択",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "ユーザプロファイルを管理",
"CheatWindowTitle": "チート管理",
"DlcWindowTitle": "DLC 管理",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "アップデート管理",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -742,6 +781,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "編集",
+ "Continue": "Continue",
"Cancel": "キャンセル",
"Save": "セーブ",
"Discard": "破棄",
@@ -809,5 +849,17 @@
"MultiplayerMode": "モード:",
"MultiplayerModeTooltip": "LDNマルチプレイヤーモードを変更します.\n\nldn_mitmモジュールがインストールされた, 他のRyujinxインスタンスや,ハックされたNintendo Switchコンソールとのローカル/同一ネットワーク接続を可能にします.\n\nマルチプレイでは, すべてのプレイヤーが同じゲームバージョンである必要があります(例:Super Smash Bros. Ultimate v13.0.1はv13.0.0に接続できません).\n\n不明な場合は「無効」のままにしてください.",
"MultiplayerModeDisabled": "無効",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index fa88bab5e..015530833 100644
--- a/src/Ryujinx/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Zarządzaj rodzajami plików",
"MenuBarToolsInstallFileTypes": "Typy plików instalacyjnych",
"MenuBarToolsUninstallFileTypes": "Typy plików dezinstalacyjnych",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Window Size",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Otwiera katalog zawierający mody dla danej aplikacji",
"GameListContextMenuOpenSdModsDirectory": "Otwórz katalog modów Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Otwiera alternatywny katalog Atmosphere na karcie SD, który zawiera mody danej aplikacji. Przydatne dla modów przygotowanych pod prawdziwy sprzęt.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} Załadowane gry",
"StatusBarSystemVersion": "Wersja systemu: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Wykryto niski limit dla przypisań pamięci",
"LinuxVmMaxMapCountDialogTextPrimary": "Czy chcesz zwiększyć wartość vm.max_map_count do {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "Niektóre gry mogą próbować przypisać sobie więcej pamięci niż obecnie, jest to dozwolone. Ryujinx ulegnie awarii, gdy limit zostanie przekroczony.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Okno Dialogowe Wprowadzania",
"InputDialogOk": "OK",
"InputDialogCancel": "Anuluj",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Wybierz nazwę profilu",
"InputDialogAddNewProfileHeader": "Wprowadź nazwę profilu",
"InputDialogAddNewProfileSubtext": "(Maksymalna długość: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Pomyślnie odinstalowano typy plików!",
"DialogUninstallFileTypesErrorMessage": "Nie udało się odinstalować typów plików.",
"DialogOpenSettingsWindowLabel": "Otwórz Okno Ustawień",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Aplet Kontrolera",
"DialogMessageDialogErrorExceptionMessage": "Błąd wyświetlania okna Dialogowego Wiadomości: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Błąd wyświetlania Klawiatury Oprogramowania: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Wersja {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Potwierdzenie",
"FileDialogAllTypes": "Wszystkie typy",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "Wybierz pliki DLC",
"SelectUpdateDialogTitle": "Wybierz pliki aktualizacji",
"SelectModDialogTitle": "Wybierz katalog modów",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Menedżer Profili Użytkowników",
"CheatWindowTitle": "Menedżer Kodów",
"DlcWindowTitle": "Menedżer Zawartości do Pobrania",
"ModWindowTitle": "Zarządzaj modami dla {0} ({1})",
"UpdateWindowTitle": "Menedżer Aktualizacji Tytułu",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} Mod(y/ów)",
"UserProfilesEditProfile": "Edytuj Zaznaczone",
+ "Continue": "Continue",
"Cancel": "Anuluj",
"Save": "Zapisz",
"Discard": "Odrzuć",
@@ -810,5 +850,17 @@
"MultiplayerMode": "Tryb:",
"MultiplayerModeTooltip": "Change LDN multiplayer mode.\n\nLdnMitm will modify local wireless/local play functionality in games to function as if it were LAN, allowing for local, same-network connections with other Ryujinx instances and hacked Nintendo Switch consoles that have the ldn_mitm module installed.\n\nMultiplayer requires all players to be on the same game version (i.e. Super Smash Bros. Ultimate v13.0.1 can't connect to v13.0.0).\n\nLeave DISABLED if unsure.",
"MultiplayerModeDisabled": "Wyłączone",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index 5b7a21494..512581c0e 100644
--- a/src/Ryujinx/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Gerenciar tipos de arquivo",
"MenuBarToolsInstallFileTypes": "Instalar tipos de arquivo",
"MenuBarToolsUninstallFileTypes": "Desinstalar tipos de arquivos",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Window Size",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Abre a pasta que contém os mods da aplicação ",
"GameListContextMenuOpenSdModsDirectory": "Abrir diretório de mods Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} jogos carregados",
"StatusBarSystemVersion": "Versão do firmware: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Limite baixo para mapeamentos de memória detectado",
"LinuxVmMaxMapCountDialogTextPrimary": "Você gostaria de aumentar o valor de vm.max_map_count para {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "Alguns jogos podem tentar criar mais mapeamentos de memória do que o atualmente permitido. Ryujinx irá falhar assim que este limite for excedido.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Diálogo de texto",
"InputDialogOk": "OK",
"InputDialogCancel": "Cancelar",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Escolha o nome de perfil",
"InputDialogAddNewProfileHeader": "Escreva o nome do perfil",
"InputDialogAddNewProfileSubtext": "(Máximo de caracteres: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Tipos de arquivo desinstalados com sucesso!",
"DialogUninstallFileTypesErrorMessage": "Falha ao desinstalar tipos de arquivo.",
"DialogOpenSettingsWindowLabel": "Abrir janela de configurações",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Applet de controle",
"DialogMessageDialogErrorExceptionMessage": "Erro ao exibir diálogo de mensagem: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Erro ao exibir teclado virtual: {0}",
@@ -618,7 +625,6 @@
"LoadApplicationFolderTooltip": "Abre o navegador de pastas para seleção de pasta extraída do Switch compatível a ser carregada",
"OpenRyujinxFolderTooltip": "Abre o diretório do sistema de arquivos do Ryujinx",
"LoadTitleUpdatesFromFolderTooltip": "Abra o explorador de arquivos para selecionar uma ou mais pastas e carregar atualizações de jogo em massa.",
- "OpenRyujinxFolderTooltip": "Abrir diretório do sistema de arquivos do Ryujinx",
"OpenRyujinxLogsTooltip": "Abre o diretório onde os logs são salvos",
"ExitTooltip": "Sair do Ryujinx",
"OpenSettingsTooltip": "Abrir janela de configurações",
@@ -671,6 +677,12 @@
"TitleUpdateVersionLabel": "Versão {0}",
"TitleBundledUpdateVersionLabel": "Empacotado: Versão {0}",
"TitleBundledDlcLabel": "Empacotado:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Informação",
"RyujinxConfirm": "Ryujinx - Confirmação",
"FileDialogAllTypes": "Todos os tipos",
@@ -724,10 +736,36 @@
"SelectUpdateDialogTitle": "Selecionar arquivos de atualização",
"SelectModDialogTitle": "Select mod directory",
"UserProfileWindowTitle": "Gerenciador de perfis de usuário",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"CheatWindowTitle": "Gerenciador de Cheats",
"DlcWindowTitle": "Gerenciador de DLC",
"ModWindowTitle": "Gerenciar Mods para {0} ({1})",
"UpdateWindowTitle": "Gerenciador de atualizações",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} nova(s) atualização(ões) adicionada(s)",
@@ -743,6 +781,7 @@
"AutoloadUpdateRemovedMessage": "{0} atualização(ões) ausente(s) removida(s)",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Editar selecionado",
+ "Continue": "Continue",
"Cancel": "Cancelar",
"Save": "Salvar",
"Discard": "Descartar",
@@ -810,5 +849,17 @@
"MultiplayerMode": "Modo:",
"MultiplayerModeTooltip": "Alterar o modo multiplayer LDN.\n\nLdnMitm modificará a funcionalidade de jogo sem fio/local nos jogos para funcionar como se fosse LAN, permitindo conexões locais, na mesma rede, com outras instâncias do Ryujinx e consoles Nintendo Switch hackeados que possuem o módulo ldn_mitm instalado.\n\nO multiplayer exige que todos os jogadores estejam na mesma versão do jogo (ex.: Super Smash Bros. Ultimate v13.0.1 não consegue se conectar à v13.0.0).\n\nDeixe DESATIVADO se estiver em dúvida.",
"MultiplayerModeDisabled": "Desativado",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index cd17eb301..9d81116ef 100644
--- a/src/Ryujinx/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Управление типами файлов",
"MenuBarToolsInstallFileTypes": "Установить типы файлов",
"MenuBarToolsUninstallFileTypes": "Удалить типы файлов",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_Вид",
"MenuBarViewWindow": "Размер окна",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Открывает папку, содержащую моды для приложений и игр",
"GameListContextMenuOpenSdModsDirectory": "Открыть папку с модами Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Открывает папку Atmosphere на альтернативной SD-карте, которая содержит моды для приложений и игр. Полезно для модов, сделанных для реальной консоли.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} игр загружено",
"StatusBarSystemVersion": "Версия прошивки: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Обнаружен низкий лимит разметки памяти",
"LinuxVmMaxMapCountDialogTextPrimary": "Хотите увеличить значение vm.max_map_count до {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "Некоторые игры могут создавать большую разметку памяти, чем разрешено на данный момент по умолчанию. Ryujinx вылетит при превышении этого лимита.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Диалоговое окно ввода",
"InputDialogOk": "ОК",
"InputDialogCancel": "Отмена",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Выберите никнейм",
"InputDialogAddNewProfileHeader": "Пожалуйста, введите никнейм",
"InputDialogAddNewProfileSubtext": "(Максимальная длина: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Типы файлов успешно удалены",
"DialogUninstallFileTypesErrorMessage": "Не удалось удалить типы файлов.",
"DialogOpenSettingsWindowLabel": "Открывает окно параметров",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Апплет контроллера",
"DialogMessageDialogErrorExceptionMessage": "Ошибка отображения сообщения: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Ошибка отображения программной клавиатуры: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Version {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Информация",
"RyujinxConfirm": "Ryujinx - Подтверждение",
"FileDialogAllTypes": "Все типы",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "Выберите файлы DLC",
"SelectUpdateDialogTitle": "Выберите файлы обновлений",
"SelectModDialogTitle": "Выбрать папку с модами",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Менеджер учетных записей",
"CheatWindowTitle": "Менеджер читов",
"DlcWindowTitle": "Управление DLC для {0} ({1})",
"ModWindowTitle": "Управление модами для {0} ({1})",
"UpdateWindowTitle": "Менеджер обновлений игр",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "Моды для {0} ",
"UserProfilesEditProfile": "Изменить выбранные",
+ "Continue": "Continue",
"Cancel": "Отмена",
"Save": "Сохранить",
"Discard": "Отменить",
@@ -810,5 +850,17 @@
"MultiplayerMode": "Режим:",
"MultiplayerModeTooltip": "Меняет многопользовательский режим LDN.\n\nLdnMitm модифицирует функциональность локальной беспроводной/игры на одном устройстве в играх, позволяя играть с другими пользователями Ryujinx или взломанными консолями Nintendo Switch с установленным модулем ldn_mitm, находящимися в одной локальной сети друг с другом.\n\nМногопользовательская игра требует наличия у всех игроков одной и той же версии игры (т.е. Super Smash Bros. Ultimate v13.0.1 не может подключиться к v13.0.0).\n\nРекомендуется оставить отключенным.",
"MultiplayerModeDisabled": "Отключено",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json
index d32cfb737..fa59ba682 100644
--- a/src/Ryujinx/Assets/Locales/th_TH.json
+++ b/src/Ryujinx/Assets/Locales/th_TH.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "จัดการประเภทไฟล์",
"MenuBarToolsInstallFileTypes": "ติดตั้งประเภทไฟล์",
"MenuBarToolsUninstallFileTypes": "ถอนการติดตั้งประเภทไฟล์",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_มุมมอง",
"MenuBarViewWindow": "ขนาดหน้าต่าง",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "เปิดไดเร็กทอรี่ Mods ของแอปพลิเคชัน",
"GameListContextMenuOpenSdModsDirectory": "เปิดไดเร็กทอรี่ Mods Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "เปิดไดเร็กทอรี่ Atmosphere ของการ์ด SD สำรองซึ่งมี Mods ของแอปพลิเคชัน ซึ่งมีประโยชน์สำหรับ Mods ที่บรรจุมากับฮาร์ดแวร์จริง",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "เกมส์โหลดแล้ว {0}/{1}",
"StatusBarSystemVersion": "เวอร์ชั่นของระบบ: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "การตั้งค่าหน่วยความถึงขีดจำกัดต่ำสุดแล้ว",
"LinuxVmMaxMapCountDialogTextPrimary": "คุณต้องเพิ่มค่า vm.max_map_count ไปยัง {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "บางเกมอาจพยายามใช้งานหน่วยความจำมากกว่าที่ได้รับอนุญาตในปัจจุบัน Ryujinx จะปิดตัวลงเมื่อเกินขีดจำกัดนี้",
@@ -400,6 +404,8 @@
"InputDialogTitle": "กล่องโต้ตอบการป้อนข้อมูล",
"InputDialogOk": "ตกลง",
"InputDialogCancel": "ยกเลิก",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "เลือก ชื่อโปรไฟล์",
"InputDialogAddNewProfileHeader": "กรุณาใส่ชื่อโปรไฟล์",
"InputDialogAddNewProfileSubtext": "(ความยาวสูงสุด: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "ถอนการติดตั้งตามประเภทของไฟล์สำเร็จแล้ว!",
"DialogUninstallFileTypesErrorMessage": "ไม่สามารถถอนการติดตั้งตามประเภทของไฟล์ได้",
"DialogOpenSettingsWindowLabel": "เปิดหน้าต่างการตั้งค่า",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "คอนโทรลเลอร์ Applet",
"DialogMessageDialogErrorExceptionMessage": "เกิดข้อผิดพลาดในการแสดงกล่องโต้ตอบข้อความ: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "เกิดข้อผิดพลาดในการแสดงซอฟต์แวร์แป้นพิมพ์: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "เวอร์ชั่น {0}",
"TitleBundledUpdateVersionLabel": "Bundled: เวอร์ชั่น {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx – ข้อมูล",
"RyujinxConfirm": "Ryujinx - ยืนยัน",
"FileDialogAllTypes": "ทุกประเภท",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "เลือกไฟล์ DLC",
"SelectUpdateDialogTitle": "เลือกไฟล์อัพเดต",
"SelectModDialogTitle": "เลือกไดเรกทอรี Mods",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "จัดการโปรไฟล์ผู้ใช้",
"CheatWindowTitle": "จัดการสูตรโกง",
"DlcWindowTitle": "จัดการ DLC ที่ดาวน์โหลดได้สำหรับ {0} ({1})",
"ModWindowTitle": "จัดการม็อดที่ดาวน์โหลดได้สำหรับ {0} ({1})",
"UpdateWindowTitle": "จัดการอัปเดตหัวข้อ",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} อัพเดตที่เพิ่มมาใหม่",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} ม็อด",
"UserProfilesEditProfile": "แก้ไขที่เลือกแล้ว",
+ "Continue": "Continue",
"Cancel": "ยกเลิก",
"Save": "บันทึก",
"Discard": "ละทิ้ง",
@@ -810,5 +850,17 @@
"MultiplayerMode": "โหมด:",
"MultiplayerModeTooltip": "เปลี่ยนโหมดผู้เล่นหลายคนของ LDN\n\nLdnMitm จะปรับเปลี่ยนฟังก์ชันการเล่นแบบไร้สาย/ภายใน จะให้เกมทำงานเหมือนกับว่าเป็น LAN ช่วยให้สามารถเชื่อมต่อภายในเครือข่ายเดียวกันกับอินสแตนซ์ Ryujinx อื่น ๆ และคอนโซล Nintendo Switch ที่ถูกแฮ็กซึ่งมีโมดูล ldn_mitm ติดตั้งอยู่\n\nผู้เล่นหลายคนต้องการให้ผู้เล่นทุกคนอยู่ในเกมเวอร์ชันเดียวกัน (เช่น Super Smash Bros. Ultimate v13.0.1 ไม่สามารถเชื่อมต่อกับ v13.0.0)\n\nปล่อยให้ปิดการใช้งานหากไม่แน่ใจ",
"MultiplayerModeDisabled": "ปิดใช้งาน",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index 1ac9a0b6e..9b321c423 100644
--- a/src/Ryujinx/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Dosya uzantılarını yönet",
"MenuBarToolsInstallFileTypes": "Dosya uzantılarını yükle",
"MenuBarToolsUninstallFileTypes": "Dosya uzantılarını kaldır",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_Görüntüle",
"MenuBarViewWindow": "Pencere Boyutu",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
"GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} Oyun Yüklendi",
"StatusBarSystemVersion": "Sistem Sürümü: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Bellek Haritaları İçin Düşük Limit Tespit Edildi ",
"LinuxVmMaxMapCountDialogTextPrimary": "vm.max_map_count değerini {0} sayısına yükseltmek ister misiniz",
"LinuxVmMaxMapCountDialogTextSecondary": "Bazı oyunlar şu an izin verilen bellek haritası limitinden daha fazlasını yaratmaya çalışabilir. Ryujinx bu limitin geçildiği takdirde kendini kapatıcaktır.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Giriş Yöntemi Diyaloğu",
"InputDialogOk": "Tamam",
"InputDialogCancel": "İptal",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Profil İsmini Seç",
"InputDialogAddNewProfileHeader": "Lütfen Bir Profil İsmi Girin",
"InputDialogAddNewProfileSubtext": "(Maksimum Uzunluk: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Dosya uzantıları başarıyla kaldırıldı!",
"DialogUninstallFileTypesErrorMessage": "Dosya uzantıları kaldırma işlemi başarısız oldu.",
"DialogOpenSettingsWindowLabel": "Seçenekler Penceresini Aç",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Kumanda Applet'i",
"DialogMessageDialogErrorExceptionMessage": "Mesaj diyaloğu gösterilirken hata: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Mesaj diyaloğu gösterilirken hata: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Sürüm {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - Bilgi",
"RyujinxConfirm": "Ryujinx - Doğrulama",
"FileDialogAllTypes": "Tüm türler",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "DLC dosyalarını seç",
"SelectUpdateDialogTitle": "Güncelleme dosyalarını seç",
"SelectModDialogTitle": "Mod Dizinini Seç",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Kullanıcı Profillerini Yönet",
"CheatWindowTitle": "Oyun Hilelerini Yönet",
"DlcWindowTitle": "Oyun DLC'lerini Yönet",
"ModWindowTitle": "Manage Mods for {0} ({1})",
"UpdateWindowTitle": "Oyun Güncellemelerini Yönet",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} Mod(lar)",
"UserProfilesEditProfile": "Seçiliyi Düzenle",
+ "Continue": "Continue",
"Cancel": "İptal",
"Save": "Kaydet",
"Discard": "Iskarta",
@@ -810,5 +850,17 @@
"MultiplayerMode": "Mod:",
"MultiplayerModeTooltip": "Change LDN multiplayer mode.\n\nLdnMitm will modify local wireless/local play functionality in games to function as if it were LAN, allowing for local, same-network connections with other Ryujinx instances and hacked Nintendo Switch consoles that have the ldn_mitm module installed.\n\nMultiplayer requires all players to be on the same game version (i.e. Super Smash Bros. Ultimate v13.0.1 can't connect to v13.0.0).\n\nLeave DISABLED if unsure.",
"MultiplayerModeDisabled": "Devre Dışı",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index 0e22263b6..09a7e8cb4 100644
--- a/src/Ryujinx/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "Керувати типами файлів",
"MenuBarToolsInstallFileTypes": "Установити типи файлів",
"MenuBarToolsUninstallFileTypes": "Видалити типи файлів",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "_View",
"MenuBarViewWindow": "Window Size",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Відкриває каталог, який містить модифікації Додатків",
"GameListContextMenuOpenSdModsDirectory": "Відкрити каталог модифікацій Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Відкриває альтернативний каталог SD-карти Atmosphere, що містить модифікації Додатків. Корисно для модифікацій, зроблених для реального обладнання.",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} ігор завантажено",
"StatusBarSystemVersion": "Версія системи: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Виявлено низьку межу для відображення памʼяті",
"LinuxVmMaxMapCountDialogTextPrimary": "Бажаєте збільшити значення vm.max_map_count на {0}",
"LinuxVmMaxMapCountDialogTextSecondary": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.",
@@ -400,6 +404,8 @@
"InputDialogTitle": "Діалог введення",
"InputDialogOk": "Гаразд",
"InputDialogCancel": "Скасувати",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "Виберіть ім'я профілю",
"InputDialogAddNewProfileHeader": "Будь ласка, введіть ім'я профілю",
"InputDialogAddNewProfileSubtext": "(Макс. довжина: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "Успішно видалено типи файлів!",
"DialogUninstallFileTypesErrorMessage": "Не вдалося видалити типи файлів.",
"DialogOpenSettingsWindowLabel": "Відкрити вікно налаштувань",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "Аплет контролера",
"DialogMessageDialogErrorExceptionMessage": "Помилка показу діалогового вікна повідомлення: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Помилка показу програмної клавіатури: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "Версія {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujin x - Інформація",
"RyujinxConfirm": "Ryujinx - Підтвердження",
"FileDialogAllTypes": "Всі типи",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "Виберіть файли DLC",
"SelectUpdateDialogTitle": "Виберіть файли оновлення",
"SelectModDialogTitle": "Виберіть теку з модами",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "Менеджер профілів користувачів",
"CheatWindowTitle": "Менеджер читів",
"DlcWindowTitle": "Менеджер вмісту для завантаження",
"ModWindowTitle": "Керувати модами для {0} ({1})",
"UpdateWindowTitle": "Менеджер оновлення назв",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} мод(ів)",
"UserProfilesEditProfile": "Редагувати вибране",
+ "Continue": "Continue",
"Cancel": "Скасувати",
"Save": "Зберегти",
"Discard": "Скасувати",
@@ -810,5 +850,17 @@
"MultiplayerMode": "Режим:",
"MultiplayerModeTooltip": "Змінити LDN мультиплеєру.\n\nLdnMitm змінить функціонал бездротової/локальної гри в іграх, щоб вони працювали так, ніби це LAN, що дозволяє локальні підключення в тій самій мережі з іншими екземплярами Ryujinx та хакнутими консолями Nintendo Switch, які мають встановлений модуль ldn_mitm.\n\nМультиплеєр вимагає, щоб усі гравці були на одній і тій же версії гри (наприклад Super Smash Bros. Ultimate v13.0.1 не зможе під'єднатися до v13.0.0).\n\nЗалиште на \"Вимкнено\", якщо не впевнені, ",
"MultiplayerModeDisabled": "Вимкнено",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index 004d5007b..11840e864 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "管理文件扩展名",
"MenuBarToolsInstallFileTypes": "关联文件扩展名",
"MenuBarToolsUninstallFileTypes": "取消关联扩展名",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "视图(_V)",
"MenuBarViewWindow": "窗口大小",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "打开存放游戏 MOD 的目录",
"GameListContextMenuOpenSdModsDirectory": "打开大气层系统 MOD 目录",
"GameListContextMenuOpenSdModsDirectoryToolTip": "打开存放适用于大气层系统的游戏 MOD 的目录,对于为真实硬件打包的 MOD 非常有用",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} 游戏加载完成",
"StatusBarSystemVersion": "系统固件版本:{0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "检测到操作系统内存映射最大数量被设置的过低",
"LinuxVmMaxMapCountDialogTextPrimary": "你想要将操作系统 vm.max_map_count 的值增加到 {0} 吗",
"LinuxVmMaxMapCountDialogTextSecondary": "有些游戏可能会尝试创建超过当前系统允许的内存映射最大数量,若超过当前最大数量,Ryujinx 模拟器将会闪退。",
@@ -400,6 +404,8 @@
"InputDialogTitle": "输入对话框",
"InputDialogOk": "完成",
"InputDialogCancel": "取消",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "选择用户名称",
"InputDialogAddNewProfileHeader": "请输入账户名称",
"InputDialogAddNewProfileSubtext": "(最大长度:{0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "成功解除文件类型关联!",
"DialogUninstallFileTypesErrorMessage": "解除文件类型关联失败!",
"DialogOpenSettingsWindowLabel": "打开设置窗口",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "控制器小窗口",
"DialogMessageDialogErrorExceptionMessage": "显示消息对话框时出错:{0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "显示软件键盘时出错:{0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "游戏更新的版本 {0}",
"TitleBundledUpdateVersionLabel": "捆绑:版本 {0}",
"TitleBundledDlcLabel": "捆绑:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - 信息",
"RyujinxConfirm": "Ryujinx - 确认",
"FileDialogAllTypes": "全部类型",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "选择 DLC 文件",
"SelectUpdateDialogTitle": "选择更新文件",
"SelectModDialogTitle": "选择 MOD 目录",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "管理用户账户",
"CheatWindowTitle": "金手指管理器",
"DlcWindowTitle": "管理 {0} ({1}) 的 DLC",
"ModWindowTitle": "管理 {0} ({1}) 的 MOD",
"UpdateWindowTitle": "游戏更新管理器",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "{0} 个更新被添加",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "{0} 个失效的游戏更新已移除",
"ModWindowHeading": "{0} Mod",
"UserProfilesEditProfile": "编辑所选",
+ "Continue": "Continue",
"Cancel": "取消",
"Save": "保存",
"Discard": "放弃",
@@ -810,5 +850,17 @@
"MultiplayerMode": "联机模式:",
"MultiplayerModeTooltip": "修改 LDN 多人联机游玩模式。\n\nldn_mitm 联机插件将修改游戏中的本地无线和本地游玩功能,使其表现得像局域网一样,允许和其他安装了 ldn_mitm 插件的 Ryujinx 模拟器和破解的任天堂 Switch 主机在同一网络下进行本地连接,实现多人联机游玩。\n\n多人联机游玩要求所有玩家必须运行相同的游戏版本(例如,游戏版本 v13.0.1 无法与 v13.0.0 联机)。\n\n如果不确定,请保持为“禁用”。",
"MultiplayerModeDisabled": "禁用",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index 9bfc243ae..d59df0e5b 100644
--- a/src/Ryujinx/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
@@ -33,6 +33,7 @@
"MenuBarToolsManageFileTypes": "管理檔案類型",
"MenuBarToolsInstallFileTypes": "安裝檔案類型",
"MenuBarToolsUninstallFileTypes": "移除檔案類型",
+ "MenuBarToolsXCITrimmer": "Trim XCI Files",
"MenuBarView": "檢視(_V)",
"MenuBarViewWindow": "視窗大小",
"MenuBarViewWindow720": "720p",
@@ -84,8 +85,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "開啟此應用程式模組的資料夾",
"GameListContextMenuOpenSdModsDirectory": "開啟 Atmosphere 模組資料夾",
"GameListContextMenuOpenSdModsDirectoryToolTip": "開啟此應用程式模組的另一個 SD 卡 Atmosphere 資料夾。適用於為真實硬體封裝的模組。",
+ "GameListContextMenuTrimXCI": "Check and Trim XCI File",
+ "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
"StatusBarGamesLoaded": "{0}/{1} 遊戲已載入",
"StatusBarSystemVersion": "系統版本: {0}",
+ "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
"LinuxVmMaxMapCountDialogTitle": "檢測到記憶體映射的低限值",
"LinuxVmMaxMapCountDialogTextPrimary": "您是否要將 vm.max_map_count 的數值增至 {0}?",
"LinuxVmMaxMapCountDialogTextSecondary": "某些遊戲可能會嘗試建立超過目前允許的記憶體映射。一旦超過此限制,Ryujinx 就會崩潰。",
@@ -400,6 +404,8 @@
"InputDialogTitle": "輸入對話方塊",
"InputDialogOk": "確定",
"InputDialogCancel": "取消",
+ "InputDialogCancelling": "Cancelling",
+ "InputDialogClose": "Close",
"InputDialogAddNewProfileTitle": "選擇設定檔名稱",
"InputDialogAddNewProfileHeader": "請輸入設定檔名稱",
"InputDialogAddNewProfileSubtext": "(最大長度: {0})",
@@ -469,6 +475,7 @@
"DialogUninstallFileTypesSuccessMessage": "成功移除檔案類型!",
"DialogUninstallFileTypesErrorMessage": "無法移除檔案類型。",
"DialogOpenSettingsWindowLabel": "開啟設定視窗",
+ "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
"DialogControllerAppletTitle": "控制器小程式",
"DialogMessageDialogErrorExceptionMessage": "顯示訊息對話方塊時出現錯誤: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "顯示軟體鍵盤時出現錯誤: {0}",
@@ -671,6 +678,12 @@
"TitleUpdateVersionLabel": "版本 {0}",
"TitleBundledUpdateVersionLabel": "附帶: 版本 {0}",
"TitleBundledDlcLabel": "附帶:",
+ "TitleXCIStatusPartialLabel": "Partial",
+ "TitleXCIStatusTrimmableLabel": "Untrimmed",
+ "TitleXCIStatusUntrimmableLabel": "Trimmed",
+ "TitleXCIStatusFailedLabel": "(Failed)",
+ "TitleXCICanSaveLabel": "Save {0:n0} Mb",
+ "TitleXCISavingLabel": "Saved {0:n0} Mb",
"RyujinxInfo": "Ryujinx - 資訊",
"RyujinxConfirm": "Ryujinx - 確認",
"FileDialogAllTypes": "全部類型",
@@ -723,11 +736,37 @@
"SelectDlcDialogTitle": "選取 DLC 檔案",
"SelectUpdateDialogTitle": "選取更新檔",
"SelectModDialogTitle": "選取模組資料夾",
+ "TrimXCIFileDialogTitle": "Check and Trim XCI File",
+ "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
+ "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
+ "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
+ "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
+ "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
+ "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
+ "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
+ "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
+ "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
+ "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
+ "TrimXCIFileCancelled": "The operation was cancelled",
+ "TrimXCIFileFileUndertermined": "No operation was performed",
"UserProfileWindowTitle": "使用者設定檔管理員",
"CheatWindowTitle": "密技管理員",
"DlcWindowTitle": "管理 {0} 的可下載內容 ({1})",
"ModWindowTitle": "管理 {0} 的模組 ({1})",
"UpdateWindowTitle": "遊戲更新管理員",
+ "XCITrimmerWindowTitle": "XCI File Trimmer",
+ "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
+ "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
+ "XCITrimmerTitleStatusFailed": "Failed",
+ "XCITrimmerPotentialSavings": "Potential Savings",
+ "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerSavingsMb": "{0:n0} Mb",
+ "XCITrimmerSelectDisplayed": "Select Shown",
+ "XCITrimmerDeselectDisplayed": "Deselect Shown",
+ "XCITrimmerSortName": "Title",
+ "XCITrimmerSortSaved": "Space Savings",
"XCITrimmerTrim": "Trim",
"XCITrimmerUntrim": "Untrim",
"UpdateWindowUpdateAddedMessage": "已加入 {0} 個遊戲更新",
@@ -743,6 +782,7 @@
"AutoloadUpdateRemovedMessage": "已刪除 {0} 個遺失的遊戲更新",
"ModWindowHeading": "{0} 模組",
"UserProfilesEditProfile": "編輯所選",
+ "Continue": "Continue",
"Cancel": "取消",
"Save": "儲存",
"Discard": "放棄變更",
@@ -810,5 +850,17 @@
"MultiplayerMode": "模式:",
"MultiplayerModeTooltip": "變更 LDN 多人遊戲模式。\n\nLdnMitm 將修改遊戲中的本機無線/本機遊戲功能,使其如同區域網路一樣執行,允許與其他安裝了 ldn_mitm 模組的 Ryujinx 實例和已破解的 Nintendo Switch 遊戲機進行本機同網路連線。\n\n多人遊戲要求所有玩家使用相同的遊戲版本 (例如,Super Smash Bros. Ultimate v13.0.1 無法連接 v13.0.0)。\n\n如果不確定,請保持 Disabled (停用) 狀態。",
"MultiplayerModeDisabled": "已停用",
- "MultiplayerModeLdnMitm": "ldn_mitm"
+ "MultiplayerModeLdnMitm": "ldn_mitm",
+ "MultiplayerModeLdnRyu": "RyuLDN",
+ "MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
+ "MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
+ "LdnPassphrase": "Network Passphrase:",
+ "LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
+ "LdnPassphraseInputPublic": "(public)",
+ "GenLdnPass": "Generate Random",
+ "GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
+ "ClearLdnPass": "Clear",
+ "ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
+ "InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
}
From f8d63f9a2fe6a094f147b414201c882e34f27e29 Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Fri, 22 Nov 2024 14:38:58 -0600
Subject: [PATCH 19/33] UI: Add a show changelog button in the Updater, for new
updates & when you're on the latest version.
---
Directory.Packages.props | 4 +--
src/Ryujinx.Common/ReleaseInformation.cs | 9 +++++
src/Ryujinx/Assets/Locales/ar_SA.json | 1 +
src/Ryujinx/Assets/Locales/de_DE.json | 1 +
src/Ryujinx/Assets/Locales/el_GR.json | 1 +
src/Ryujinx/Assets/Locales/en_US.json | 1 +
src/Ryujinx/Assets/Locales/es_ES.json | 1 +
src/Ryujinx/Assets/Locales/fr_FR.json | 1 +
src/Ryujinx/Assets/Locales/he_IL.json | 1 +
src/Ryujinx/Assets/Locales/it_IT.json | 1 +
src/Ryujinx/Assets/Locales/ja_JP.json | 1 +
src/Ryujinx/Assets/Locales/ko_KR.json | 1 +
src/Ryujinx/Assets/Locales/pl_PL.json | 1 +
src/Ryujinx/Assets/Locales/pt_BR.json | 1 +
src/Ryujinx/Assets/Locales/ru_RU.json | 1 +
src/Ryujinx/Assets/Locales/th_TH.json | 1 +
src/Ryujinx/Assets/Locales/tr_TR.json | 1 +
src/Ryujinx/Assets/Locales/uk_UA.json | 1 +
src/Ryujinx/Assets/Locales/zh_CN.json | 1 +
src/Ryujinx/Assets/Locales/zh_TW.json | 1 +
src/Ryujinx/UI/Helpers/ContentDialogHelper.cs | 34 +++++++++++++++++++
src/Ryujinx/Updater.cs | 33 +++++++++++++-----
22 files changed, 87 insertions(+), 11 deletions(-)
diff --git a/Directory.Packages.props b/Directory.Packages.props
index c0ace079d..ffb5f2ead 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -38,7 +38,7 @@
-
+
@@ -52,4 +52,4 @@
-
\ No newline at end of file
+
diff --git a/src/Ryujinx.Common/ReleaseInformation.cs b/src/Ryujinx.Common/ReleaseInformation.cs
index f4c62155a..011d9848a 100644
--- a/src/Ryujinx.Common/ReleaseInformation.cs
+++ b/src/Ryujinx.Common/ReleaseInformation.cs
@@ -1,3 +1,4 @@
+using System;
using System.Reflection;
namespace Ryujinx.Common
@@ -35,5 +36,13 @@ namespace Ryujinx.Common
public static bool IsReleaseBuild => IsValid && ReleaseChannelName.Equals(ReleaseChannel);
public static string Version => IsValid ? BuildVersion : Assembly.GetEntryAssembly()!.GetCustomAttribute()?.InformationalVersion;
+
+ public static string GetChangelogUrl(Version currentVersion, Version newVersion) =>
+ IsCanaryBuild
+ ? $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/compare/Canary-{currentVersion}...Canary-{newVersion}"
+ : $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/releases/tag/{newVersion}";
+
+ public static string GetChangelogForVersion(Version version) =>
+ $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/tag/{version}";
}
}
diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json
index 6dbc96135..c937a2eed 100644
--- a/src/Ryujinx/Assets/Locales/ar_SA.json
+++ b/src/Ryujinx/Assets/Locales/ar_SA.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "جاري استخراج التحديث...",
"DialogUpdaterRenamingMessage": "إعادة تسمية التحديث...",
"DialogUpdaterAddingFilesMessage": "إضافة تحديث جديد...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "اكتمل التحديث",
"DialogUpdaterRestartMessage": "هل تريد إعادة تشغيل ريوجينكس الآن؟",
"DialogUpdaterNoInternetMessage": "أنت غير متصل بالإنترنت.",
diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index be95f3bc0..c27de5608 100644
--- a/src/Ryujinx/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Update wird entpackt...",
"DialogUpdaterRenamingMessage": "Update wird umbenannt...",
"DialogUpdaterAddingFilesMessage": "Update wird hinzugefügt...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Update abgeschlossen!",
"DialogUpdaterRestartMessage": "Ryujinx jetzt neu starten?",
"DialogUpdaterNoInternetMessage": "Es besteht keine Verbindung mit dem Internet!",
diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index c6cfb9d62..d47c8b9fe 100644
--- a/src/Ryujinx/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Εξαγωγή Ενημέρωσης...",
"DialogUpdaterRenamingMessage": "Μετονομασία Ενημέρωσης...",
"DialogUpdaterAddingFilesMessage": "Προσθήκη Νέας Ενημέρωσης...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Η Ενημέρωση Ολοκληρώθηκε!",
"DialogUpdaterRestartMessage": "Θέλετε να επανεκκινήσετε το Ryujinx τώρα;",
"DialogUpdaterNoInternetMessage": "Δεν είστε συνδεδεμένοι στο Διαδίκτυο!",
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 9354c8a41..23135866d 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Extracting Update...",
"DialogUpdaterRenamingMessage": "Renaming Update...",
"DialogUpdaterAddingFilesMessage": "Adding New Update...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Update Complete!",
"DialogUpdaterRestartMessage": "Do you want to restart Ryujinx now?",
"DialogUpdaterNoInternetMessage": "You are not connected to the Internet!",
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index 6a194960b..8456040ce 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Extrayendo actualización...",
"DialogUpdaterRenamingMessage": "Renombrando actualización...",
"DialogUpdaterAddingFilesMessage": "Aplicando actualización...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "¡Actualización completa!",
"DialogUpdaterRestartMessage": "¿Quieres reiniciar Ryujinx?",
"DialogUpdaterNoInternetMessage": "¡No estás conectado a internet!",
diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json
index dd23bef76..f17a7ba95 100644
--- a/src/Ryujinx/Assets/Locales/fr_FR.json
+++ b/src/Ryujinx/Assets/Locales/fr_FR.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Extraction de la mise à jour…",
"DialogUpdaterRenamingMessage": "Renommage de la mise à jour...",
"DialogUpdaterAddingFilesMessage": "Ajout d'une nouvelle mise à jour...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Mise à jour terminée !",
"DialogUpdaterRestartMessage": "Voulez-vous redémarrer Ryujinx maintenant ?",
"DialogUpdaterNoInternetMessage": "Vous n'êtes pas connecté à Internet !",
diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index b9f89eb37..f0cf4eb68 100644
--- a/src/Ryujinx/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "מחלץ עדכון...",
"DialogUpdaterRenamingMessage": "משנה את שם העדכון...",
"DialogUpdaterAddingFilesMessage": "מוסיף עדכון חדש...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "העדכון הושלם!",
"DialogUpdaterRestartMessage": "האם אתם רוצים להפעיל מחדש את ריוג'ינקס עכשיו?",
"DialogUpdaterNoInternetMessage": "אתם לא מחוברים לאינטרנט!",
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index f10dd9d35..dd408bf5b 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Estrazione dell'aggiornamento...",
"DialogUpdaterRenamingMessage": "Rinominazione dell'aggiornamento...",
"DialogUpdaterAddingFilesMessage": "Aggiunta del nuovo aggiornamento...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Aggiornamento completato!",
"DialogUpdaterRestartMessage": "Vuoi riavviare Ryujinx adesso?",
"DialogUpdaterNoInternetMessage": "Non sei connesso ad Internet!",
diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index 34253acbf..244730494 100644
--- a/src/Ryujinx/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "アップデートを展開中...",
"DialogUpdaterRenamingMessage": "アップデートをリネーム中...",
"DialogUpdaterAddingFilesMessage": "新規アップデートを追加中...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "アップデート完了!",
"DialogUpdaterRestartMessage": "すぐに Ryujinx を再起動しますか?",
"DialogUpdaterNoInternetMessage": "インターネットに接続されていません!",
diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index 5bda1565b..47a619054 100644
--- a/src/Ryujinx/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "업데이트 추출 중...",
"DialogUpdaterRenamingMessage": "이름 변경 업데이트...",
"DialogUpdaterAddingFilesMessage": "새 업데이트 추가 중...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "업데이트가 완료되었습니다!",
"DialogUpdaterRestartMessage": "지금 Ryujinx를 다시 시작하시겠습니까?",
"DialogUpdaterNoInternetMessage": "인터넷에 연결되어 있지 않습니다!",
diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index 015530833..cfa9d7a76 100644
--- a/src/Ryujinx/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Wypakowywanie Aktualizacji...",
"DialogUpdaterRenamingMessage": "Zmiana Nazwy Aktualizacji...",
"DialogUpdaterAddingFilesMessage": "Dodawanie Nowej Aktualizacji...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Aktualizacja Zakończona!",
"DialogUpdaterRestartMessage": "Czy chcesz teraz zrestartować Ryujinx?",
"DialogUpdaterNoInternetMessage": "Nie masz połączenia z Internetem!",
diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index 512581c0e..352fae46b 100644
--- a/src/Ryujinx/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Extraindo atualização...",
"DialogUpdaterRenamingMessage": "Renomeando atualização...",
"DialogUpdaterAddingFilesMessage": "Adicionando nova atualização...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Atualização concluída!",
"DialogUpdaterRestartMessage": "Deseja reiniciar o Ryujinx agora?",
"DialogUpdaterNoInternetMessage": "Você não está conectado à Internet!",
diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index 9d81116ef..112735e2d 100644
--- a/src/Ryujinx/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Извлечение обновления...",
"DialogUpdaterRenamingMessage": "Переименование обновления...",
"DialogUpdaterAddingFilesMessage": "Добавление нового обновления...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Обновление завершено",
"DialogUpdaterRestartMessage": "Перезапустить Ryujinx?",
"DialogUpdaterNoInternetMessage": "Вы не подключены к интернету",
diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json
index fa59ba682..35959ddbd 100644
--- a/src/Ryujinx/Assets/Locales/th_TH.json
+++ b/src/Ryujinx/Assets/Locales/th_TH.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "กำลังแตกไฟล์อัปเดต...",
"DialogUpdaterRenamingMessage": "กำลังลบไฟล์เก่า...",
"DialogUpdaterAddingFilesMessage": "กำลังเพิ่มไฟล์อัปเดตใหม่...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "อัปเดตเสร็จสมบูรณ์แล้ว!",
"DialogUpdaterRestartMessage": "คุณต้องการรีสตาร์ท Ryujinx ตอนนี้หรือไม่?",
"DialogUpdaterNoInternetMessage": "คุณไม่ได้เชื่อมต่อกับอินเทอร์เน็ต!",
diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index 9b321c423..5d50b67db 100644
--- a/src/Ryujinx/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Güncelleme Ayıklanıyor...",
"DialogUpdaterRenamingMessage": "Güncelleme Yeniden Adlandırılıyor...",
"DialogUpdaterAddingFilesMessage": "Yeni Güncelleme Ekleniyor...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Güncelleme Tamamlandı!",
"DialogUpdaterRestartMessage": "Ryujinx'i şimdi yeniden başlatmak istiyor musunuz?",
"DialogUpdaterNoInternetMessage": "İnternete bağlı değilsiniz!",
diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index 09a7e8cb4..a45208486 100644
--- a/src/Ryujinx/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "Видобування оновлення...",
"DialogUpdaterRenamingMessage": "Перейменування оновлення...",
"DialogUpdaterAddingFilesMessage": "Додавання нового оновлення...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "Оновлення завершено!",
"DialogUpdaterRestartMessage": "Перезапустити Ryujinx зараз?",
"DialogUpdaterNoInternetMessage": "Ви не підключені до Інтернету!",
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index 11840e864..8a4995ea7 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "正在提取更新...",
"DialogUpdaterRenamingMessage": "正在重命名更新...",
"DialogUpdaterAddingFilesMessage": "安装更新中...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "更新成功!",
"DialogUpdaterRestartMessage": "是否立即重启 Ryujinx 模拟器?",
"DialogUpdaterNoInternetMessage": "没有连接到网络",
diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index d59df0e5b..5649ba00a 100644
--- a/src/Ryujinx/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
@@ -457,6 +457,7 @@
"DialogUpdaterExtractionMessage": "正在提取更新...",
"DialogUpdaterRenamingMessage": "重新命名更新...",
"DialogUpdaterAddingFilesMessage": "加入新更新...",
+ "DialogUpdaterShowChangelogMessage": "Show Changelog",
"DialogUpdaterCompleteMessage": "更新成功!",
"DialogUpdaterRestartMessage": "您現在要重新啟動 Ryujinx 嗎?",
"DialogUpdaterNoInternetMessage": "您沒有連線到網際網路!",
diff --git a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs
index a7fe3f0ce..3f0f0f033 100644
--- a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs
+++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs
@@ -261,6 +261,16 @@ namespace Ryujinx.Ava.UI.Helpers
string.Empty,
LocaleManager.Instance[LocaleKeys.InputDialogOk],
(int)Symbol.Important);
+
+ internal static async Task CreateUpdaterUpToDateInfoDialog(string primary, string secondaryText)
+ => await ShowTextDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterTitle],
+ primary,
+ secondaryText,
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
+ string.Empty,
+ LocaleManager.Instance[LocaleKeys.InputDialogOk],
+ (int)Symbol.Important);
internal static async Task CreateWarningDialog(string primary, string secondaryText)
=> await ShowTextDialog(
@@ -309,6 +319,30 @@ namespace Ryujinx.Ava.UI.Helpers
return response == UserResult.Yes;
}
+
+ internal static async Task CreateUpdaterChoiceDialog(string title, string primary, string secondaryText)
+ {
+ if (_isChoiceDialogOpen)
+ {
+ return UserResult.Cancel;
+ }
+
+ _isChoiceDialogOpen = true;
+
+ UserResult response = await ShowTextDialog(
+ title,
+ primary,
+ secondaryText,
+ LocaleManager.Instance[LocaleKeys.InputDialogYes],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterShowChangelogMessage],
+ LocaleManager.Instance[LocaleKeys.InputDialogNo],
+ (int)Symbol.Help,
+ UserResult.Yes);
+
+ _isChoiceDialogOpen = false;
+
+ return response;
+ }
internal static async Task CreateExitDialog()
{
diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs
index 9deff5e86..5f3ddb119 100644
--- a/src/Ryujinx/Updater.cs
+++ b/src/Ryujinx/Updater.cs
@@ -176,9 +176,14 @@ namespace Ryujinx.Ava
{
if (showVersionUpToDate)
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(
+ UserResult userResult = await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
string.Empty);
+
+ if (userResult is UserResult.Yes)
+ {
+ OpenHelper.OpenUrl(ReleaseInformation.GetChangelogForVersion(currentVersion));
+ }
}
_running = false;
@@ -206,19 +211,29 @@ namespace Ryujinx.Ava
await Dispatcher.UIThread.InvokeAsync(async () =>
{
+ string newVersionString = ReleaseInformation.IsCanaryBuild
+ ? $"Canary {currentVersion} -> Canary {newVersion}"
+ : $"{currentVersion} -> {newVersion}";
+
+ RequestUserToUpdate:
// Show a message asking the user if they want to update
- var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(
+ UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog(
LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
- $"{Program.Version} -> {newVersion}");
+ newVersionString);
- if (shouldUpdate)
+ switch (shouldUpdate)
{
- await UpdateRyujinx(mainWindow, _buildUrl);
- }
- else
- {
- _running = false;
+ case UserResult.Yes:
+ await UpdateRyujinx(mainWindow, _buildUrl);
+ break;
+ // Secondary button maps to no, which in this case is the show changelog button.
+ case UserResult.No:
+ OpenHelper.OpenUrl(ReleaseInformation.GetChangelogUrl(currentVersion, newVersion));
+ goto RequestUserToUpdate;
+ default:
+ _running = false;
+ break;
}
});
}
From 49eeb26b6f4fd9ab94a1168d1a77bdcee4617ef9 Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Fri, 22 Nov 2024 14:46:10 -0600
Subject: [PATCH 20/33] UI: I may be stupid. Primary button result is Ok, not
Yes.
---
src/Ryujinx/Updater.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs
index 5f3ddb119..47acbc343 100644
--- a/src/Ryujinx/Updater.cs
+++ b/src/Ryujinx/Updater.cs
@@ -180,7 +180,7 @@ namespace Ryujinx.Ava
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
string.Empty);
- if (userResult is UserResult.Yes)
+ if (userResult is UserResult.Ok)
{
OpenHelper.OpenUrl(ReleaseInformation.GetChangelogForVersion(currentVersion));
}
From e05875a079e1a31a8e5401932949c6cdb0196856 Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Fri, 22 Nov 2024 14:52:56 -0600
Subject: [PATCH 21/33] UI: It's called "live testing."
---
src/Ryujinx/Updater.cs | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs
index 47acbc343..bdb44d668 100644
--- a/src/Ryujinx/Updater.cs
+++ b/src/Ryujinx/Updater.cs
@@ -114,9 +114,14 @@ namespace Ryujinx.Ava
{
if (showVersionUpToDate)
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(
+ UserResult userResult = await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
string.Empty);
+
+ if (userResult is UserResult.Ok)
+ {
+ OpenHelper.OpenUrl(ReleaseInformation.GetChangelogForVersion(currentVersion));
+ }
}
_running = false;
@@ -133,9 +138,14 @@ namespace Ryujinx.Ava
{
if (showVersionUpToDate)
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(
+ UserResult userResult = await ContentDialogHelper.CreateUpdaterUpToDateInfoDialog(
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
string.Empty);
+
+ if (userResult is UserResult.Ok)
+ {
+ OpenHelper.OpenUrl(ReleaseInformation.GetChangelogForVersion(currentVersion));
+ }
}
_running = false;
From 55340011528aa8c05a826397ea41178cfc8de226 Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Fri, 22 Nov 2024 15:08:24 -0600
Subject: [PATCH 22/33] UI: Always save screenshots to the Ryujinx data
directory.
---
src/Ryujinx/AppHost.cs | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs
index 7246be4b9..d1398f194 100644
--- a/src/Ryujinx/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
@@ -352,11 +352,7 @@ namespace Ryujinx.Ava
string filename = $"{sanitizedApplicationName}_{currentTime.Year}-{currentTime.Month:D2}-{currentTime.Day:D2}_{currentTime.Hour:D2}-{currentTime.Minute:D2}-{currentTime.Second:D2}.png";
- string directory = AppDataManager.Mode switch
- {
- AppDataManager.LaunchMode.Portable or AppDataManager.LaunchMode.Custom => Path.Combine(AppDataManager.BaseDirPath, "screenshots"),
- _ => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Ryujinx"),
- };
+ string directory = Path.Combine(AppDataManager.BaseDirPath, "screenshots");
string path = Path.Combine(directory, filename);
From e653848a2cdbd6571a325bededd3535a5dc09de2 Mon Sep 17 00:00:00 2001
From: LotP1 <68976644+LotP1@users.noreply.github.com>
Date: Fri, 22 Nov 2024 22:33:44 +0100
Subject: [PATCH 23/33] JIT Sparse Function Table (#250)
More up to date build of the JIT Sparse PR for continued development.
JIT Sparse Function Table was originally developed by riperiperi for the
original Ryujinx project, and decreased the amount of layers in the
Function Table structure, to decrease lookup times at the cost of
slightly higher RAM usage.
This PR rebalances the JIT Sparse Function Table to be a bit more RAM
intensive, but faster in workloads where the JIT Function Table is a
bottleneck. Faster RAM will see a bigger impact and slower RAM (DDR3 and
potentially slow DDR4) will see a slight performance decrease.
This PR also implements a base for a PPTC profile system that could
allow for PPTC with ExeFS mods enabled in the future.
This PR also potentially fixes a strange issue where Avalonia would time
out in some rare instances, e.g. when running ExeFS mods with TotK and a
strange controller configuration.
---------
Co-authored-by: Evan Husted
---
src/ARMeilleure/Common/AddressTable.cs | 252 ---------
src/ARMeilleure/Common/AddressTableLevel.cs | 44 ++
src/ARMeilleure/Common/AddressTablePresets.cs | 75 +++
src/ARMeilleure/Common/Allocator.cs | 2 +-
src/ARMeilleure/Common/IAddressTable.cs | 51 ++
src/ARMeilleure/Common/NativeAllocator.cs | 2 +-
.../Instructions/InstEmitFlowHelper.cs | 26 +
.../Signal/NativeSignalHandlerGenerator.cs | 2 +-
.../Translation/ArmEmitterContext.cs | 4 +-
src/ARMeilleure/Translation/PTC/Ptc.cs | 15 +-
src/ARMeilleure/Translation/Translator.cs | 30 +-
.../Translation/TranslatorStubs.cs | 4 +-
src/Ryujinx.Cpu/AddressTable.cs | 482 ++++++++++++++++++
src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs | 2 +-
src/Ryujinx.Cpu/ICpuContext.cs | 2 +-
src/Ryujinx.Cpu/Jit/JitCpuContext.cs | 10 +-
.../Arm32/Target/Arm64/InstEmitFlow.cs | 62 ++-
.../Arm64/Target/Arm64/InstEmitSystem.cs | 62 ++-
.../LightningJit/LightningJitCpuContext.cs | 11 +-
src/Ryujinx.Cpu/LightningJit/Translator.cs | 23 +-
.../LightningJit/TranslatorStubs.cs | 4 +-
src/Ryujinx.HLE/HOS/ArmProcessContext.cs | 8 +-
.../HOS/ArmProcessContextFactory.cs | 2 +-
src/Ryujinx.Memory/SparseMemoryBlock.cs | 125 +++++
src/Ryujinx.Tests/Cpu/CpuContext.cs | 3 +-
src/Ryujinx.Tests/Cpu/EnvironmentTests.cs | 7 +-
src/Ryujinx.Tests/Memory/PartialUnmaps.cs | 7 +-
27 files changed, 990 insertions(+), 327 deletions(-)
delete mode 100644 src/ARMeilleure/Common/AddressTable.cs
create mode 100644 src/ARMeilleure/Common/AddressTableLevel.cs
create mode 100644 src/ARMeilleure/Common/AddressTablePresets.cs
create mode 100644 src/ARMeilleure/Common/IAddressTable.cs
create mode 100644 src/Ryujinx.Cpu/AddressTable.cs
create mode 100644 src/Ryujinx.Memory/SparseMemoryBlock.cs
diff --git a/src/ARMeilleure/Common/AddressTable.cs b/src/ARMeilleure/Common/AddressTable.cs
deleted file mode 100644
index a3ffaf470..000000000
--- a/src/ARMeilleure/Common/AddressTable.cs
+++ /dev/null
@@ -1,252 +0,0 @@
-using ARMeilleure.Diagnostics;
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-
-namespace ARMeilleure.Common
-{
- ///
- /// Represents a table of guest address to a value.
- ///
- /// Type of the value
- public unsafe class AddressTable : IDisposable where TEntry : unmanaged
- {
- ///
- /// Represents a level in an .
- ///
- public readonly struct Level
- {
- ///
- /// Gets the index of the in the guest address.
- ///
- public int Index { get; }
-
- ///
- /// Gets the length of the in the guest address.
- ///
- public int Length { get; }
-
- ///
- /// Gets the mask which masks the bits used by the .
- ///
- public ulong Mask => ((1ul << Length) - 1) << Index;
-
- ///
- /// Initializes a new instance of the structure with the specified
- /// and .
- ///
- /// Index of the
- /// Length of the
- public Level(int index, int length)
- {
- (Index, Length) = (index, length);
- }
-
- ///
- /// Gets the value of the from the specified guest .
- ///
- /// Guest address
- /// Value of the from the specified guest
- public int GetValue(ulong address)
- {
- return (int)((address & Mask) >> Index);
- }
- }
-
- private bool _disposed;
- private TEntry** _table;
- private readonly List _pages;
-
- ///
- /// Gets the bits used by the of the instance.
- ///
- public ulong Mask { get; }
-
- ///
- /// Gets the s used by the instance.
- ///
- public Level[] Levels { get; }
-
- ///
- /// Gets or sets the default fill value of newly created leaf pages.
- ///
- public TEntry Fill { get; set; }
-
- ///
- /// Gets the base address of the .
- ///
- /// instance was disposed
- public nint Base
- {
- get
- {
- ObjectDisposedException.ThrowIf(_disposed, this);
-
- lock (_pages)
- {
- return (nint)GetRootPage();
- }
- }
- }
-
- ///
- /// Constructs a new instance of the class with the specified list of
- /// .
- ///
- /// is null
- /// Length of is less than 2
- public AddressTable(Level[] levels)
- {
- ArgumentNullException.ThrowIfNull(levels);
-
- if (levels.Length < 2)
- {
- throw new ArgumentException("Table must be at least 2 levels deep.", nameof(levels));
- }
-
- _pages = new List(capacity: 16);
-
- Levels = levels;
- Mask = 0;
-
- foreach (var level in Levels)
- {
- Mask |= level.Mask;
- }
- }
-
- ///
- /// Determines if the specified is in the range of the
- /// .
- ///
- /// Guest address
- /// if is valid; otherwise
- public bool IsValid(ulong address)
- {
- return (address & ~Mask) == 0;
- }
-
- ///
- /// Gets a reference to the value at the specified guest .
- ///
- /// Guest address
- /// Reference to the value at the specified guest
- /// instance was disposed
- /// is not mapped
- public ref TEntry GetValue(ulong address)
- {
- ObjectDisposedException.ThrowIf(_disposed, this);
-
- if (!IsValid(address))
- {
- throw new ArgumentException($"Address 0x{address:X} is not mapped onto the table.", nameof(address));
- }
-
- lock (_pages)
- {
- return ref GetPage(address)[Levels[^1].GetValue(address)];
- }
- }
-
- ///
- /// Gets the leaf page for the specified guest .
- ///
- /// Guest address
- /// Leaf page for the specified guest
- private TEntry* GetPage(ulong address)
- {
- TEntry** page = GetRootPage();
-
- for (int i = 0; i < Levels.Length - 1; i++)
- {
- ref Level level = ref Levels[i];
- ref TEntry* nextPage = ref page[level.GetValue(address)];
-
- if (nextPage == null)
- {
- ref Level nextLevel = ref Levels[i + 1];
-
- nextPage = i == Levels.Length - 2 ?
- (TEntry*)Allocate(1 << nextLevel.Length, Fill, leaf: true) :
- (TEntry*)Allocate(1 << nextLevel.Length, nint.Zero, leaf: false);
- }
-
- page = (TEntry**)nextPage;
- }
-
- return (TEntry*)page;
- }
-
- ///
- /// Lazily initialize and get the root page of the .
- ///
- /// Root page of the
- private TEntry** GetRootPage()
- {
- if (_table == null)
- {
- _table = (TEntry**)Allocate(1 << Levels[0].Length, fill: nint.Zero, leaf: false);
- }
-
- return _table;
- }
-
- ///
- /// Allocates a block of memory of the specified type and length.
- ///
- /// Type of elements
- /// Number of elements
- /// Fill value
- /// if leaf; otherwise
- /// Allocated block
- private nint Allocate(int length, T fill, bool leaf) where T : unmanaged
- {
- var size = sizeof(T) * length;
- var page = (nint)NativeAllocator.Instance.Allocate((uint)size);
- var span = new Span((void*)page, length);
-
- span.Fill(fill);
-
- _pages.Add(page);
-
- TranslatorEventSource.Log.AddressTableAllocated(size, leaf);
-
- return page;
- }
-
- ///
- /// Releases all resources used by the instance.
- ///
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ///
- /// Releases all unmanaged and optionally managed resources used by the
- /// instance.
- ///
- /// to dispose managed resources also; otherwise just unmanaged resouces
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- foreach (var page in _pages)
- {
- Marshal.FreeHGlobal(page);
- }
-
- _disposed = true;
- }
- }
-
- ///
- /// Frees resources used by the instance.
- ///
- ~AddressTable()
- {
- Dispose(false);
- }
- }
-}
diff --git a/src/ARMeilleure/Common/AddressTableLevel.cs b/src/ARMeilleure/Common/AddressTableLevel.cs
new file mode 100644
index 000000000..6107726ee
--- /dev/null
+++ b/src/ARMeilleure/Common/AddressTableLevel.cs
@@ -0,0 +1,44 @@
+namespace ARMeilleure.Common
+{
+ ///
+ /// Represents a level in an .
+ ///
+ public readonly struct AddressTableLevel
+ {
+ ///
+ /// Gets the index of the in the guest address.
+ ///
+ public int Index { get; }
+
+ ///
+ /// Gets the length of the in the guest address.
+ ///
+ public int Length { get; }
+
+ ///
+ /// Gets the mask which masks the bits used by the .
+ ///
+ public ulong Mask => ((1ul << Length) - 1) << Index;
+
+ ///
+ /// Initializes a new instance of the structure with the specified
+ /// and .
+ ///
+ /// Index of the
+ /// Length of the
+ public AddressTableLevel(int index, int length)
+ {
+ (Index, Length) = (index, length);
+ }
+
+ ///
+ /// Gets the value of the from the specified guest .
+ ///
+ /// Guest address
+ /// Value of the from the specified guest
+ public int GetValue(ulong address)
+ {
+ return (int)((address & Mask) >> Index);
+ }
+ }
+}
diff --git a/src/ARMeilleure/Common/AddressTablePresets.cs b/src/ARMeilleure/Common/AddressTablePresets.cs
new file mode 100644
index 000000000..977e84a36
--- /dev/null
+++ b/src/ARMeilleure/Common/AddressTablePresets.cs
@@ -0,0 +1,75 @@
+namespace ARMeilleure.Common
+{
+ public static class AddressTablePresets
+ {
+ private static readonly AddressTableLevel[] _levels64Bit =
+ new AddressTableLevel[]
+ {
+ new(31, 17),
+ new(23, 8),
+ new(15, 8),
+ new( 7, 8),
+ new( 2, 5),
+ };
+
+ private static readonly AddressTableLevel[] _levels32Bit =
+ new AddressTableLevel[]
+ {
+ new(31, 17),
+ new(23, 8),
+ new(15, 8),
+ new( 7, 8),
+ new( 1, 6),
+ };
+
+ private static readonly AddressTableLevel[] _levels64BitSparseTiny =
+ new AddressTableLevel[]
+ {
+ new( 11, 28),
+ new( 2, 9),
+ };
+
+ private static readonly AddressTableLevel[] _levels32BitSparseTiny =
+ new AddressTableLevel[]
+ {
+ new( 10, 22),
+ new( 1, 9),
+ };
+
+ private static readonly AddressTableLevel[] _levels64BitSparseGiant =
+ new AddressTableLevel[]
+ {
+ new( 38, 1),
+ new( 2, 36),
+ };
+
+ private static readonly AddressTableLevel[] _levels32BitSparseGiant =
+ new AddressTableLevel[]
+ {
+ new( 31, 1),
+ new( 1, 30),
+ };
+
+ //high power will run worse on DDR3 systems and some DDR4 systems due to the higher ram utilization
+ //low power will never run worse than non-sparse, but for most systems it won't be necessary
+ //high power is always used, but I've left low power in here for future reference
+ public static AddressTableLevel[] GetArmPreset(bool for64Bits, bool sparse, bool lowPower = false)
+ {
+ if (sparse)
+ {
+ if (lowPower)
+ {
+ return for64Bits ? _levels64BitSparseTiny : _levels32BitSparseTiny;
+ }
+ else
+ {
+ return for64Bits ? _levels64BitSparseGiant : _levels32BitSparseGiant;
+ }
+ }
+ else
+ {
+ return for64Bits ? _levels64Bit : _levels32Bit;
+ }
+ }
+ }
+}
diff --git a/src/ARMeilleure/Common/Allocator.cs b/src/ARMeilleure/Common/Allocator.cs
index 6905a614f..de6a77ebe 100644
--- a/src/ARMeilleure/Common/Allocator.cs
+++ b/src/ARMeilleure/Common/Allocator.cs
@@ -2,7 +2,7 @@ using System;
namespace ARMeilleure.Common
{
- unsafe abstract class Allocator : IDisposable
+ public unsafe abstract class Allocator : IDisposable
{
public T* Allocate(ulong count = 1) where T : unmanaged
{
diff --git a/src/ARMeilleure/Common/IAddressTable.cs b/src/ARMeilleure/Common/IAddressTable.cs
new file mode 100644
index 000000000..65077ec43
--- /dev/null
+++ b/src/ARMeilleure/Common/IAddressTable.cs
@@ -0,0 +1,51 @@
+using System;
+
+namespace ARMeilleure.Common
+{
+ public interface IAddressTable : IDisposable where TEntry : unmanaged
+ {
+ ///
+ /// True if the address table's bottom level is sparsely mapped.
+ /// This also ensures the second bottom level is filled with a dummy page rather than 0.
+ ///
+ bool Sparse { get; }
+
+ ///
+ /// Gets the bits used by the of the instance.
+ ///
+ ulong Mask { get; }
+
+ ///
+ /// Gets the s used by the instance.
+ ///
+ AddressTableLevel[] Levels { get; }
+
+ ///
+ /// Gets or sets the default fill value of newly created leaf pages.
+ ///
+ TEntry Fill { get; set; }
+
+ ///
+ /// Gets the base address of the .
+ ///
+ /// instance was disposed
+ nint Base { get; }
+
+ ///
+ /// Determines if the specified is in the range of the
+ /// .
+ ///
+ /// Guest address
+ /// if is valid; otherwise
+ bool IsValid(ulong address);
+
+ ///
+ /// Gets a reference to the value at the specified guest .
+ ///
+ /// Guest address
+ /// Reference to the value at the specified guest
+ /// instance was disposed
+ /// is not mapped
+ ref TEntry GetValue(ulong address);
+ }
+}
diff --git a/src/ARMeilleure/Common/NativeAllocator.cs b/src/ARMeilleure/Common/NativeAllocator.cs
index ca5d3a850..ffcffa4bc 100644
--- a/src/ARMeilleure/Common/NativeAllocator.cs
+++ b/src/ARMeilleure/Common/NativeAllocator.cs
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
namespace ARMeilleure.Common
{
- unsafe sealed class NativeAllocator : Allocator
+ public unsafe sealed class NativeAllocator : Allocator
{
public static NativeAllocator Instance { get; } = new();
diff --git a/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs
index 2009bafda..a602ea49e 100644
--- a/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs
+++ b/src/ARMeilleure/Instructions/InstEmitFlowHelper.cs
@@ -193,6 +193,8 @@ namespace ARMeilleure.Instructions
Operand hostAddress;
+ var table = context.FunctionTable;
+
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
// onto the dispatch stub.
if (guestAddress.Kind == OperandKind.Constant && context.FunctionTable.IsValid(guestAddress.Value))
@@ -203,6 +205,30 @@ namespace ARMeilleure.Instructions
hostAddress = context.Load(OperandType.I64, hostAddressAddr);
}
+ else if (table.Sparse)
+ {
+ // Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
+ // Deliberately attempts to avoid branches.
+
+ Operand tableBase = !context.HasPtc ?
+ Const(table.Base) :
+ Const(table.Base, Ptc.FunctionTableSymbol);
+
+ hostAddress = tableBase;
+
+ for (int i = 0; i < table.Levels.Length; i++)
+ {
+ var level = table.Levels[i];
+ int clearBits = 64 - (level.Index + level.Length);
+
+ Operand index = context.ShiftLeft(
+ context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits)), Const(clearBits + level.Index)),
+ Const(3)
+ );
+
+ hostAddress = context.Load(OperandType.I64, context.Add(hostAddress, index));
+ }
+ }
else
{
hostAddress = !context.HasPtc ?
diff --git a/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
index 1b3689e3f..35747d7a4 100644
--- a/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
+++ b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
@@ -8,7 +8,7 @@ namespace ARMeilleure.Signal
{
public static class NativeSignalHandlerGenerator
{
- public const int MaxTrackedRanges = 8;
+ public const int MaxTrackedRanges = 16;
private const int StructAddressOffset = 0;
private const int StructWriteOffset = 4;
diff --git a/src/ARMeilleure/Translation/ArmEmitterContext.cs b/src/ARMeilleure/Translation/ArmEmitterContext.cs
index 5d79171a2..82f12bb02 100644
--- a/src/ARMeilleure/Translation/ArmEmitterContext.cs
+++ b/src/ARMeilleure/Translation/ArmEmitterContext.cs
@@ -46,7 +46,7 @@ namespace ARMeilleure.Translation
public IMemoryManager Memory { get; }
public EntryTable CountTable { get; }
- public AddressTable FunctionTable { get; }
+ public IAddressTable FunctionTable { get; }
public TranslatorStubs Stubs { get; }
public ulong EntryAddress { get; }
@@ -62,7 +62,7 @@ namespace ARMeilleure.Translation
public ArmEmitterContext(
IMemoryManager memory,
EntryTable countTable,
- AddressTable funcTable,
+ IAddressTable funcTable,
TranslatorStubs stubs,
ulong entryAddress,
bool highCq,
diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs
index 8236150fe..c722ce6be 100644
--- a/src/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/src/ARMeilleure/Translation/PTC/Ptc.cs
@@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
- private const uint InternalVersion = 6950; //! To be incremented manually for each change to the ARMeilleure project.
+ private const uint InternalVersion = 6992; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";
@@ -41,6 +41,7 @@ namespace ARMeilleure.Translation.PTC
public static readonly Symbol PageTableSymbol = new(SymbolType.Special, 1);
public static readonly Symbol CountTableSymbol = new(SymbolType.Special, 2);
public static readonly Symbol DispatchStubSymbol = new(SymbolType.Special, 3);
+ public static readonly Symbol FunctionTableSymbol = new(SymbolType.Special, 4);
private const byte FillingByte = 0x00;
private const CompressionLevel SaveCompressionLevel = CompressionLevel.Fastest;
@@ -101,7 +102,7 @@ namespace ARMeilleure.Translation.PTC
Disable();
}
- public void Initialize(string titleIdText, string displayVersion, bool enabled, MemoryManagerType memoryMode)
+ public void Initialize(string titleIdText, string displayVersion, bool enabled, MemoryManagerType memoryMode, string cacheSelector)
{
Wait();
@@ -127,6 +128,8 @@ namespace ARMeilleure.Translation.PTC
DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
_memoryMode = memoryMode;
+ Logger.Info?.Print(LogClass.Ptc, $"PPTC (v{InternalVersion}) Profile: {DisplayVersion}-{cacheSelector}");
+
string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
@@ -140,8 +143,8 @@ namespace ARMeilleure.Translation.PTC
Directory.CreateDirectory(workPathBackup);
}
- CachePathActual = Path.Combine(workPathActual, DisplayVersion);
- CachePathBackup = Path.Combine(workPathBackup, DisplayVersion);
+ CachePathActual = Path.Combine(workPathActual, DisplayVersion) + "-" + cacheSelector;
+ CachePathBackup = Path.Combine(workPathBackup, DisplayVersion) + "-" + cacheSelector;
PreLoad();
Profiler.PreLoad();
@@ -706,6 +709,10 @@ namespace ARMeilleure.Translation.PTC
{
imm = translator.Stubs.DispatchStub;
}
+ else if (symbol == FunctionTableSymbol)
+ {
+ imm = translator.FunctionTable.Base;
+ }
if (imm == null)
{
diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs
index 24fbd7621..162368782 100644
--- a/src/ARMeilleure/Translation/Translator.cs
+++ b/src/ARMeilleure/Translation/Translator.cs
@@ -22,33 +22,13 @@ namespace ARMeilleure.Translation
{
public class Translator
{
- private static readonly AddressTable.Level[] _levels64Bit =
- new AddressTable.Level[]
- {
- new(31, 17),
- new(23, 8),
- new(15, 8),
- new( 7, 8),
- new( 2, 5),
- };
-
- private static readonly AddressTable.Level[] _levels32Bit =
- new AddressTable.Level[]
- {
- new(31, 17),
- new(23, 8),
- new(15, 8),
- new( 7, 8),
- new( 1, 6),
- };
-
private readonly IJitMemoryAllocator _allocator;
private readonly ConcurrentQueue> _oldFuncs;
private readonly Ptc _ptc;
internal TranslatorCache Functions { get; }
- internal AddressTable FunctionTable { get; }
+ internal IAddressTable FunctionTable { get; }
internal EntryTable CountTable { get; }
internal TranslatorStubs Stubs { get; }
internal TranslatorQueue Queue { get; }
@@ -57,7 +37,7 @@ namespace ARMeilleure.Translation
private Thread[] _backgroundTranslationThreads;
private volatile int _threadCount;
- public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, bool for64Bits)
+ public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, IAddressTable functionTable)
{
_allocator = allocator;
Memory = memory;
@@ -72,15 +52,15 @@ namespace ARMeilleure.Translation
CountTable = new EntryTable();
Functions = new TranslatorCache();
- FunctionTable = new AddressTable(for64Bits ? _levels64Bit : _levels32Bit);
+ FunctionTable = functionTable;
Stubs = new TranslatorStubs(FunctionTable);
FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
}
- public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled)
+ public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
{
- _ptc.Initialize(titleIdText, displayVersion, enabled, Memory.Type);
+ _ptc.Initialize(titleIdText, displayVersion, enabled, Memory.Type, cacheSelector);
return _ptc;
}
diff --git a/src/ARMeilleure/Translation/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs
index 364cca13c..bd9aed8d4 100644
--- a/src/ARMeilleure/Translation/TranslatorStubs.cs
+++ b/src/ARMeilleure/Translation/TranslatorStubs.cs
@@ -19,7 +19,7 @@ namespace ARMeilleure.Translation
private bool _disposed;
- private readonly AddressTable _functionTable;
+ private readonly IAddressTable _functionTable;
private readonly Lazy _dispatchStub;
private readonly Lazy _dispatchLoop;
private readonly Lazy _contextWrapper;
@@ -86,7 +86,7 @@ namespace ARMeilleure.Translation
///
/// Function table used to store pointers to the functions that the guest code will call
/// is null
- public TranslatorStubs(AddressTable functionTable)
+ public TranslatorStubs(IAddressTable functionTable)
{
ArgumentNullException.ThrowIfNull(functionTable);
diff --git a/src/Ryujinx.Cpu/AddressTable.cs b/src/Ryujinx.Cpu/AddressTable.cs
new file mode 100644
index 000000000..d87b12ab0
--- /dev/null
+++ b/src/Ryujinx.Cpu/AddressTable.cs
@@ -0,0 +1,482 @@
+using ARMeilleure.Memory;
+using Ryujinx.Common;
+using Ryujinx.Cpu.Signal;
+using Ryujinx.Memory;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading;
+using static Ryujinx.Cpu.MemoryEhMeilleure;
+
+namespace ARMeilleure.Common
+{
+ ///
+ /// Represents a table of guest address to a value.
+ ///
+ /// Type of the value
+ public unsafe class AddressTable : IAddressTable where TEntry : unmanaged
+ {
+ ///
+ /// Represents a page of the address table.
+ ///
+ private readonly struct AddressTablePage
+ {
+ ///
+ /// True if the allocation belongs to a sparse block, false otherwise.
+ ///
+ public readonly bool IsSparse;
+
+ ///
+ /// Base address for the page.
+ ///
+ public readonly IntPtr Address;
+
+ public AddressTablePage(bool isSparse, IntPtr address)
+ {
+ IsSparse = isSparse;
+ Address = address;
+ }
+ }
+
+ ///
+ /// A sparsely mapped block of memory with a signal handler to map pages as they're accessed.
+ ///
+ private readonly struct TableSparseBlock : IDisposable
+ {
+ public readonly SparseMemoryBlock Block;
+ private readonly TrackingEventDelegate _trackingEvent;
+
+ public TableSparseBlock(ulong size, Action ensureMapped, PageInitDelegate pageInit)
+ {
+ var block = new SparseMemoryBlock(size, pageInit, null);
+
+ _trackingEvent = (ulong address, ulong size, bool write) =>
+ {
+ ulong pointer = (ulong)block.Block.Pointer + address;
+ ensureMapped((IntPtr)pointer);
+ return pointer;
+ };
+
+ bool added = NativeSignalHandler.AddTrackedRegion(
+ (nuint)block.Block.Pointer,
+ (nuint)(block.Block.Pointer + (IntPtr)block.Block.Size),
+ Marshal.GetFunctionPointerForDelegate(_trackingEvent));
+
+ if (!added)
+ {
+ throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
+ }
+
+ Block = block;
+ }
+
+ public void Dispose()
+ {
+ NativeSignalHandler.RemoveTrackedRegion((nuint)Block.Block.Pointer);
+
+ Block.Dispose();
+ }
+ }
+
+ private bool _disposed;
+ private TEntry** _table;
+ private readonly List _pages;
+ private TEntry _fill;
+
+ private readonly MemoryBlock _sparseFill;
+ private readonly SparseMemoryBlock _fillBottomLevel;
+ private readonly TEntry* _fillBottomLevelPtr;
+
+ private readonly List _sparseReserved;
+ private readonly ReaderWriterLockSlim _sparseLock;
+
+ private ulong _sparseBlockSize;
+ private ulong _sparseReservedOffset;
+
+ public bool Sparse { get; }
+
+ ///
+ public ulong Mask { get; }
+
+ ///
+ public AddressTableLevel[] Levels { get; }
+
+ ///
+ public TEntry Fill
+ {
+ get
+ {
+ return _fill;
+ }
+ set
+ {
+ UpdateFill(value);
+ }
+ }
+
+ ///
+ public IntPtr Base
+ {
+ get
+ {
+ ObjectDisposedException.ThrowIf(_disposed, this);
+
+ lock (_pages)
+ {
+ return (IntPtr)GetRootPage();
+ }
+ }
+ }
+
+ ///
+ /// Constructs a new instance of the class with the specified list of
+ /// .
+ ///
+ /// Levels for the address table
+ /// True if the bottom page should be sparsely mapped
+ /// is null
+ /// Length of is less than 2
+ public AddressTable(AddressTableLevel[] levels, bool sparse)
+ {
+ ArgumentNullException.ThrowIfNull(levels);
+
+ _pages = new List(capacity: 16);
+
+ Levels = levels;
+ Mask = 0;
+
+ foreach (var level in Levels)
+ {
+ Mask |= level.Mask;
+ }
+
+ Sparse = sparse;
+
+ if (sparse)
+ {
+ // If the address table is sparse, allocate a fill block
+
+ _sparseFill = new MemoryBlock(268435456ul, MemoryAllocationFlags.Mirrorable); //low Power TC uses size: 65536ul
+
+ ulong bottomLevelSize = (1ul << levels.Last().Length) * (ulong)sizeof(TEntry);
+
+ _fillBottomLevel = new SparseMemoryBlock(bottomLevelSize, null, _sparseFill);
+ _fillBottomLevelPtr = (TEntry*)_fillBottomLevel.Block.Pointer;
+
+ _sparseReserved = new List();
+ _sparseLock = new ReaderWriterLockSlim();
+
+ _sparseBlockSize = bottomLevelSize;
+ }
+ }
+
+ ///
+ /// Create an instance for an ARM function table.
+ /// Selects the best table structure for A32/A64, taking into account the selected memory manager type.
+ ///
+ /// True if the guest is A64, false otherwise
+ /// Memory manager type
+ /// An for ARM function lookup
+ public static AddressTable CreateForArm(bool for64Bits, MemoryManagerType type)
+ {
+ // Assume software memory means that we don't want to use any signal handlers.
+ bool sparse = type != MemoryManagerType.SoftwareMmu && type != MemoryManagerType.SoftwarePageTable;
+
+ return new AddressTable(AddressTablePresets.GetArmPreset(for64Bits, sparse), sparse);
+ }
+
+ ///
+ /// Update the fill value for the bottom level of the table.
+ ///
+ /// New fill value
+ private void UpdateFill(TEntry fillValue)
+ {
+ if (_sparseFill != null)
+ {
+ Span span = _sparseFill.GetSpan(0, (int)_sparseFill.Size);
+ MemoryMarshal.Cast(span).Fill(fillValue);
+ }
+
+ _fill = fillValue;
+ }
+
+ ///
+ /// Signal that the given code range exists.
+ ///
+ ///
+ ///
+ public void SignalCodeRange(ulong address, ulong size)
+ {
+ AddressTableLevel bottom = Levels.Last();
+ ulong bottomLevelEntries = 1ul << bottom.Length;
+
+ ulong entryIndex = address >> bottom.Index;
+ ulong entries = size >> bottom.Index;
+ entries += entryIndex - BitUtils.AlignDown(entryIndex, bottomLevelEntries);
+
+ _sparseBlockSize = Math.Max(_sparseBlockSize, BitUtils.AlignUp(entries, bottomLevelEntries) * (ulong)sizeof(TEntry));
+ }
+
+ ///
+ public bool IsValid(ulong address)
+ {
+ return (address & ~Mask) == 0;
+ }
+
+ ///
+ public ref TEntry GetValue(ulong address)
+ {
+ ObjectDisposedException.ThrowIf(_disposed, this);
+
+ if (!IsValid(address))
+ {
+ throw new ArgumentException($"Address 0x{address:X} is not mapped onto the table.", nameof(address));
+ }
+
+ lock (_pages)
+ {
+ TEntry* page = GetPage(address);
+
+ int index = Levels[^1].GetValue(address);
+
+ EnsureMapped((IntPtr)(page + index));
+
+ return ref page[index];
+ }
+ }
+
+ ///
+ /// Gets the leaf page for the specified guest .
+ ///
+ /// Guest address
+ /// Leaf page for the specified guest
+ private TEntry* GetPage(ulong address)
+ {
+ TEntry** page = GetRootPage();
+
+ for (int i = 0; i < Levels.Length - 1; i++)
+ {
+ ref AddressTableLevel level = ref Levels[i];
+ ref TEntry* nextPage = ref page[level.GetValue(address)];
+
+ if (nextPage == null || nextPage == _fillBottomLevelPtr)
+ {
+ ref AddressTableLevel nextLevel = ref Levels[i + 1];
+
+ if (i == Levels.Length - 2)
+ {
+ nextPage = (TEntry*)Allocate(1 << nextLevel.Length, Fill, leaf: true);
+ }
+ else
+ {
+ nextPage = (TEntry*)Allocate(1 << nextLevel.Length, GetFillValue(i), leaf: false);
+ }
+ }
+
+ page = (TEntry**)nextPage;
+ }
+
+ return (TEntry*)page;
+ }
+
+ ///
+ /// Ensure the given pointer is mapped in any overlapping sparse reservations.
+ ///
+ /// Pointer to be mapped
+ private void EnsureMapped(IntPtr ptr)
+ {
+ if (Sparse)
+ {
+ // Check sparse allocations to see if the pointer is in any of them.
+ // Ensure the page is committed if there's a match.
+
+ _sparseLock.EnterReadLock();
+
+ try
+ {
+ foreach (TableSparseBlock reserved in _sparseReserved)
+ {
+ SparseMemoryBlock sparse = reserved.Block;
+
+ if (ptr >= sparse.Block.Pointer && ptr < sparse.Block.Pointer + (IntPtr)sparse.Block.Size)
+ {
+ sparse.EnsureMapped((ulong)(ptr - sparse.Block.Pointer));
+
+ break;
+ }
+ }
+ }
+ finally
+ {
+ _sparseLock.ExitReadLock();
+ }
+ }
+ }
+
+ ///
+ /// Get the fill value for a non-leaf level of the table.
+ ///
+ /// Level to get the fill value for
+ /// The fill value
+ private IntPtr GetFillValue(int level)
+ {
+ if (_fillBottomLevel != null && level == Levels.Length - 2)
+ {
+ return (IntPtr)_fillBottomLevelPtr;
+ }
+ else
+ {
+ return IntPtr.Zero;
+ }
+ }
+
+ ///
+ /// Lazily initialize and get the root page of the .
+ ///
+ /// Root page of the
+ private TEntry** GetRootPage()
+ {
+ if (_table == null)
+ {
+ if (Levels.Length == 1)
+ _table = (TEntry**)Allocate(1 << Levels[0].Length, Fill, leaf: true);
+ else
+ _table = (TEntry**)Allocate(1 << Levels[0].Length, GetFillValue(0), leaf: false);
+ }
+
+ return _table;
+ }
+
+ ///
+ /// Initialize a leaf page with the fill value.
+ ///
+ /// Page to initialize
+ private void InitLeafPage(Span page)
+ {
+ MemoryMarshal.Cast(page).Fill(_fill);
+ }
+
+ ///
+ /// Reserve a new sparse block, and add it to the list.
+ ///
+ /// The new sparse block that was added
+ private TableSparseBlock ReserveNewSparseBlock()
+ {
+ var block = new TableSparseBlock(_sparseBlockSize, EnsureMapped, InitLeafPage);
+
+ _sparseReserved.Add(block);
+ _sparseReservedOffset = 0;
+
+ return block;
+ }
+
+ ///
+ /// Allocates a block of memory of the specified type and length.
+ ///
+ /// Type of elements
+ /// Number of elements
+ /// Fill value
+ /// if leaf; otherwise
+ /// Allocated block
+ private IntPtr Allocate(int length, T fill, bool leaf) where T : unmanaged
+ {
+ var size = sizeof(T) * length;
+
+ AddressTablePage page;
+
+ if (Sparse && leaf)
+ {
+ _sparseLock.EnterWriteLock();
+
+ SparseMemoryBlock block;
+
+ if (_sparseReserved.Count == 0)
+ {
+ block = ReserveNewSparseBlock().Block;
+ }
+ else
+ {
+ block = _sparseReserved.Last().Block;
+
+ if (_sparseReservedOffset == block.Block.Size)
+ {
+ block = ReserveNewSparseBlock().Block;
+ }
+ }
+
+ page = new AddressTablePage(true, block.Block.Pointer + (IntPtr)_sparseReservedOffset);
+
+ _sparseReservedOffset += (ulong)size;
+
+ _sparseLock.ExitWriteLock();
+ }
+ else
+ {
+ var address = (IntPtr)NativeAllocator.Instance.Allocate((uint)size);
+ page = new AddressTablePage(false, address);
+
+ var span = new Span((void*)page.Address, length);
+ span.Fill(fill);
+ }
+
+ _pages.Add(page);
+
+ //TranslatorEventSource.Log.AddressTableAllocated(size, leaf);
+
+ return page.Address;
+ }
+
+ ///
+ /// Releases all resources used by the instance.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases all unmanaged and optionally managed resources used by the
+ /// instance.
+ ///
+ /// to dispose managed resources also; otherwise just unmanaged resouces
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ foreach (var page in _pages)
+ {
+ if (!page.IsSparse)
+ {
+ Marshal.FreeHGlobal(page.Address);
+ }
+ }
+
+ if (Sparse)
+ {
+ foreach (TableSparseBlock block in _sparseReserved)
+ {
+ block.Dispose();
+ }
+
+ _sparseReserved.Clear();
+
+ _fillBottomLevel.Dispose();
+ _sparseFill.Dispose();
+ _sparseLock.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+
+ ///
+ /// Frees resources used by the instance.
+ ///
+ ~AddressTable()
+ {
+ Dispose(false);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
index 99e4c0479..784949441 100644
--- a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
+++ b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
@@ -32,7 +32,7 @@ namespace Ryujinx.Cpu.AppleHv
{
}
- public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled)
+ public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
{
return new DummyDiskCacheLoadState();
}
diff --git a/src/Ryujinx.Cpu/ICpuContext.cs b/src/Ryujinx.Cpu/ICpuContext.cs
index edcebdfc4..1fb3b674d 100644
--- a/src/Ryujinx.Cpu/ICpuContext.cs
+++ b/src/Ryujinx.Cpu/ICpuContext.cs
@@ -48,7 +48,7 @@ namespace Ryujinx.Cpu
/// Version of the application
/// True if the cache should be loaded from disk if it exists, false otherwise
/// Disk cache load progress reporter and manager
- IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled);
+ IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector);
///
/// Indicates that code has been loaded into guest memory, and that it might be executed in the future.
diff --git a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
index 9893c59b2..0793f382d 100644
--- a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
+++ b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
@@ -1,3 +1,4 @@
+using ARMeilleure.Common;
using ARMeilleure.Memory;
using ARMeilleure.Translation;
using Ryujinx.Cpu.Signal;
@@ -9,11 +10,13 @@ namespace Ryujinx.Cpu.Jit
{
private readonly ITickSource _tickSource;
private readonly Translator _translator;
+ private readonly AddressTable _functionTable;
public JitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit)
{
_tickSource = tickSource;
- _translator = new Translator(new JitMemoryAllocator(forJit: true), memory, for64Bit);
+ _functionTable = AddressTable.CreateForArm(for64Bit, memory.Type);
+ _translator = new Translator(new JitMemoryAllocator(forJit: true), memory, _functionTable);
if (memory.Type.IsHostMappedOrTracked())
{
@@ -47,14 +50,15 @@ namespace Ryujinx.Cpu.Jit
}
///
- public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled)
+ public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
{
- return new JitDiskCacheLoadState(_translator.LoadDiskCache(titleIdText, displayVersion, enabled));
+ return new JitDiskCacheLoadState(_translator.LoadDiskCache(titleIdText, displayVersion, enabled, cacheSelector));
}
///
public void PrepareCodeRange(ulong address, ulong size)
{
+ _functionTable.SignalCodeRange(address, size);
_translator.PrepareCodeRange(address, size);
}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs
index 7f5e4835c..48bdbb573 100644
--- a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs
@@ -140,6 +140,10 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
bool isTail = false)
{
int tempRegister;
+ int tempGuestAddress = -1;
+
+ bool inlineLookup = guestAddress.Kind != OperandKind.Constant &&
+ funcTable is { Sparse: true };
if (guestAddress.Kind == OperandKind.Constant)
{
@@ -153,9 +157,16 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
else
{
asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
+
+ if (inlineLookup && guestAddress.Value == 0)
+ {
+ // X0 will be overwritten. Move the address to a temp register.
+ tempGuestAddress = regAlloc.AllocateTempGprRegister();
+ asm.Mov(Register(tempGuestAddress), guestAddress);
+ }
}
- tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
+ tempRegister = NextFreeRegister(1, tempGuestAddress);
if (!isTail)
{
@@ -176,6 +187,40 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
asm.Mov(rn, funcPtrLoc & ~0xfffUL);
asm.LdrRiUn(rn, rn, (int)(funcPtrLoc & 0xfffUL));
}
+ else if (inlineLookup)
+ {
+ // Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
+
+ Operand indexReg = Register(NextFreeRegister(tempRegister + 1, tempGuestAddress));
+
+ if (tempGuestAddress != -1)
+ {
+ guestAddress = Register(tempGuestAddress);
+ }
+
+ ulong tableBase = (ulong)funcTable.Base;
+
+ // Index into the table.
+ asm.Mov(rn, tableBase);
+
+ for (int i = 0; i < funcTable.Levels.Length; i++)
+ {
+ var level = funcTable.Levels[i];
+ asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
+ asm.Lsl(indexReg, indexReg, Const(3));
+
+ // Index into the page.
+ asm.Add(rn, rn, indexReg);
+
+ // Load the page address.
+ asm.LdrRiUn(rn, rn, 0);
+ }
+
+ if (tempGuestAddress != -1)
+ {
+ regAlloc.FreeTempGprRegister(tempGuestAddress);
+ }
+ }
else
{
asm.Mov(rn, (ulong)funcPtr);
@@ -252,5 +297,20 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
{
return new Operand(register, RegisterType.Integer, type);
}
+
+ private static Operand Const(long value, OperandType type = OperandType.I64)
+ {
+ return new Operand(type, (ulong)value);
+ }
+
+ private static int NextFreeRegister(int start, int avoid)
+ {
+ if (start == avoid)
+ {
+ start++;
+ }
+
+ return start;
+ }
}
}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs
index 1eeeb746e..f534e8b6e 100644
--- a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs
@@ -305,6 +305,10 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
bool isTail = false)
{
int tempRegister;
+ int tempGuestAddress = -1;
+
+ bool inlineLookup = guestAddress.Kind != OperandKind.Constant &&
+ funcTable is { Sparse: true };
if (guestAddress.Kind == OperandKind.Constant)
{
@@ -318,9 +322,16 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
else
{
asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
+
+ if (inlineLookup && guestAddress.Value == 0)
+ {
+ // X0 will be overwritten. Move the address to a temp register.
+ tempGuestAddress = regAlloc.AllocateTempGprRegister();
+ asm.Mov(Register(tempGuestAddress), guestAddress);
+ }
}
- tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
+ tempRegister = NextFreeRegister(1, tempGuestAddress);
if (!isTail)
{
@@ -341,6 +352,40 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
asm.Mov(rn, funcPtrLoc & ~0xfffUL);
asm.LdrRiUn(rn, rn, (int)(funcPtrLoc & 0xfffUL));
}
+ else if (inlineLookup)
+ {
+ // Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
+
+ Operand indexReg = Register(NextFreeRegister(tempRegister + 1, tempGuestAddress));
+
+ if (tempGuestAddress != -1)
+ {
+ guestAddress = Register(tempGuestAddress);
+ }
+
+ ulong tableBase = (ulong)funcTable.Base;
+
+ // Index into the table.
+ asm.Mov(rn, tableBase);
+
+ for (int i = 0; i < funcTable.Levels.Length; i++)
+ {
+ var level = funcTable.Levels[i];
+ asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
+ asm.Lsl(indexReg, indexReg, Const(3));
+
+ // Index into the page.
+ asm.Add(rn, rn, indexReg);
+
+ // Load the page address.
+ asm.LdrRiUn(rn, rn, 0);
+ }
+
+ if (tempGuestAddress != -1)
+ {
+ regAlloc.FreeTempGprRegister(tempGuestAddress);
+ }
+ }
else
{
asm.Mov(rn, (ulong)funcPtr);
@@ -613,5 +658,20 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
{
return new Operand(register, RegisterType.Integer, type);
}
+
+ private static Operand Const(long value, OperandType type = OperandType.I64)
+ {
+ return new Operand(type, (ulong)value);
+ }
+
+ private static int NextFreeRegister(int start, int avoid)
+ {
+ if (start == avoid)
+ {
+ start++;
+ }
+
+ return start;
+ }
}
}
diff --git a/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
index b63636e39..0f47ffb15 100644
--- a/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
+++ b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
@@ -1,3 +1,4 @@
+using ARMeilleure.Common;
using ARMeilleure.Memory;
using Ryujinx.Cpu.Jit;
using Ryujinx.Cpu.LightningJit.State;
@@ -8,11 +9,16 @@ namespace Ryujinx.Cpu.LightningJit
{
private readonly ITickSource _tickSource;
private readonly Translator _translator;
+ private readonly AddressTable _functionTable;
public LightningJitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit)
{
_tickSource = tickSource;
- _translator = new Translator(memory, for64Bit);
+
+ _functionTable = AddressTable.CreateForArm(for64Bit, memory.Type);
+
+ _translator = new Translator(memory, _functionTable);
+
memory.UnmapEvent += UnmapHandler;
}
@@ -40,7 +46,7 @@ namespace Ryujinx.Cpu.LightningJit
}
///
- public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled)
+ public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled, string cacheSelector)
{
return new DummyDiskCacheLoadState();
}
@@ -48,6 +54,7 @@ namespace Ryujinx.Cpu.LightningJit
///
public void PrepareCodeRange(ulong address, ulong size)
{
+ _functionTable.SignalCodeRange(address, size);
}
public void Dispose()
diff --git a/src/Ryujinx.Cpu/LightningJit/Translator.cs b/src/Ryujinx.Cpu/LightningJit/Translator.cs
index b4710e34e..4c4011f11 100644
--- a/src/Ryujinx.Cpu/LightningJit/Translator.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Translator.cs
@@ -19,25 +19,6 @@ namespace Ryujinx.Cpu.LightningJit
// Should be enabled on platforms that enforce W^X.
private static bool IsNoWxPlatform => false;
- private static readonly AddressTable.Level[] _levels64Bit =
- new AddressTable.Level[]
- {
- new(31, 17),
- new(23, 8),
- new(15, 8),
- new( 7, 8),
- new( 2, 5),
- };
-
- private static readonly AddressTable.Level[] _levels32Bit =
- new AddressTable.Level[]
- {
- new(23, 9),
- new(15, 8),
- new( 7, 8),
- new( 1, 6),
- };
-
private readonly ConcurrentQueue> _oldFuncs;
private readonly NoWxCache _noWxCache;
private bool _disposed;
@@ -47,7 +28,7 @@ namespace Ryujinx.Cpu.LightningJit
internal TranslatorStubs Stubs { get; }
internal IMemoryManager Memory { get; }
- public Translator(IMemoryManager memory, bool for64Bits)
+ public Translator(IMemoryManager memory, AddressTable functionTable)
{
Memory = memory;
@@ -63,7 +44,7 @@ namespace Ryujinx.Cpu.LightningJit
}
Functions = new TranslatorCache();
- FunctionTable = new AddressTable(for64Bits ? _levels64Bit : _levels32Bit);
+ FunctionTable = functionTable;
Stubs = new TranslatorStubs(FunctionTable, _noWxCache);
FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs b/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs
index e88414d5e..c5231e506 100644
--- a/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs
+++ b/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs
@@ -23,7 +23,7 @@ namespace Ryujinx.Cpu.LightningJit
private bool _disposed;
- private readonly AddressTable _functionTable;
+ private readonly IAddressTable _functionTable;
private readonly NoWxCache _noWxCache;
private readonly GetFunctionAddressDelegate _getFunctionAddressRef;
private readonly nint _getFunctionAddress;
@@ -79,7 +79,7 @@ namespace Ryujinx.Cpu.LightningJit
/// Function table used to store pointers to the functions that the guest code will call
/// Cache used on platforms that enforce W^X, otherwise should be null
/// is null
- public TranslatorStubs(AddressTable functionTable, NoWxCache noWxCache)
+ public TranslatorStubs(IAddressTable functionTable, NoWxCache noWxCache)
{
ArgumentNullException.ThrowIfNull(functionTable);
diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
index fde489ab7..09a721644 100644
--- a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
+++ b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
@@ -13,7 +13,8 @@ namespace Ryujinx.HLE.HOS
string displayVersion,
bool diskCacheEnabled,
ulong codeAddress,
- ulong codeSize);
+ ulong codeSize,
+ string cacheSelector);
}
class ArmProcessContext : IArmProcessContext where T : class, IVirtualMemoryManagerTracked, IMemoryManager
@@ -67,10 +68,11 @@ namespace Ryujinx.HLE.HOS
string displayVersion,
bool diskCacheEnabled,
ulong codeAddress,
- ulong codeSize)
+ ulong codeSize,
+ string cacheSelector)
{
_cpuContext.PrepareCodeRange(codeAddress, codeSize);
- return _cpuContext.LoadDiskCache(titleIdText, displayVersion, diskCacheEnabled);
+ return _cpuContext.LoadDiskCache(titleIdText, displayVersion, diskCacheEnabled, cacheSelector);
}
public void InvalidateCacheRegion(ulong address, ulong size)
diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
index 6646826cb..14775fb1d 100644
--- a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
+++ b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
@@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS
}
}
- DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize);
+ DiskCacheLoadState = processContext.Initialize(_titleIdText, _displayVersion, _diskCacheEnabled, _codeAddress, _codeSize, "default"); //Ready for exefs profiles
return processContext;
}
diff --git a/src/Ryujinx.Memory/SparseMemoryBlock.cs b/src/Ryujinx.Memory/SparseMemoryBlock.cs
new file mode 100644
index 000000000..523685de1
--- /dev/null
+++ b/src/Ryujinx.Memory/SparseMemoryBlock.cs
@@ -0,0 +1,125 @@
+using Ryujinx.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+
+namespace Ryujinx.Memory
+{
+ public delegate void PageInitDelegate(Span page);
+
+ public class SparseMemoryBlock : IDisposable
+ {
+ private const ulong MapGranularity = 1UL << 17;
+
+ private readonly PageInitDelegate _pageInit;
+
+ private readonly object _lock = new object();
+ private readonly ulong _pageSize;
+ private readonly MemoryBlock _reservedBlock;
+ private readonly List _mappedBlocks;
+ private ulong _mappedBlockUsage;
+
+ private readonly ulong[] _mappedPageBitmap;
+
+ public MemoryBlock Block => _reservedBlock;
+
+ public SparseMemoryBlock(ulong size, PageInitDelegate pageInit, MemoryBlock fill)
+ {
+ _pageSize = MemoryBlock.GetPageSize();
+ _reservedBlock = new MemoryBlock(size, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
+ _mappedBlocks = new List();
+ _pageInit = pageInit;
+
+ int pages = (int)BitUtils.DivRoundUp(size, _pageSize);
+ int bitmapEntries = BitUtils.DivRoundUp(pages, 64);
+ _mappedPageBitmap = new ulong[bitmapEntries];
+
+ if (fill != null)
+ {
+ // Fill the block with mappings from the fill block.
+
+ if (fill.Size % _pageSize != 0)
+ {
+ throw new ArgumentException("Fill memory block should be page aligned.", nameof(fill));
+ }
+
+ int repeats = (int)BitUtils.DivRoundUp(size, fill.Size);
+
+ ulong offset = 0;
+ for (int i = 0; i < repeats; i++)
+ {
+ _reservedBlock.MapView(fill, 0, offset, Math.Min(fill.Size, size - offset));
+ offset += fill.Size;
+ }
+ }
+
+ // If a fill block isn't provided, the pages that aren't EnsureMapped are unmapped.
+ // The caller can rely on signal handler to fill empty pages instead.
+ }
+
+ private void MapPage(ulong pageOffset)
+ {
+ // Take a page from the latest mapped block.
+ MemoryBlock block = _mappedBlocks.LastOrDefault();
+
+ if (block == null || _mappedBlockUsage == MapGranularity)
+ {
+ // Need to map some more memory.
+
+ block = new MemoryBlock(MapGranularity, MemoryAllocationFlags.Mirrorable);
+
+ _mappedBlocks.Add(block);
+
+ _mappedBlockUsage = 0;
+ }
+
+ _pageInit(block.GetSpan(_mappedBlockUsage, (int)_pageSize));
+ _reservedBlock.MapView(block, _mappedBlockUsage, pageOffset, _pageSize);
+
+ _mappedBlockUsage += _pageSize;
+ }
+
+ public void EnsureMapped(ulong offset)
+ {
+ int pageIndex = (int)(offset / _pageSize);
+ int bitmapIndex = pageIndex >> 6;
+
+ ref ulong entry = ref _mappedPageBitmap[bitmapIndex];
+ ulong bit = 1UL << (pageIndex & 63);
+
+ if ((Volatile.Read(ref entry) & bit) == 0)
+ {
+ // Not mapped.
+
+ lock (_lock)
+ {
+ // Check the bit while locked to make sure that this only happens once.
+
+ ulong lockedEntry = Volatile.Read(ref entry);
+
+ if ((lockedEntry & bit) == 0)
+ {
+ MapPage(offset & ~(_pageSize - 1));
+
+ lockedEntry |= bit;
+
+ Interlocked.Exchange(ref entry, lockedEntry);
+ }
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ _reservedBlock.Dispose();
+
+ foreach (MemoryBlock block in _mappedBlocks)
+ {
+ block.Dispose();
+ }
+
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/Ryujinx.Tests/Cpu/CpuContext.cs b/src/Ryujinx.Tests/Cpu/CpuContext.cs
index 96b4965a2..81e8ba8c9 100644
--- a/src/Ryujinx.Tests/Cpu/CpuContext.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuContext.cs
@@ -1,3 +1,4 @@
+using ARMeilleure.Common;
using ARMeilleure.Memory;
using ARMeilleure.State;
using ARMeilleure.Translation;
@@ -12,7 +13,7 @@ namespace Ryujinx.Tests.Cpu
public CpuContext(IMemoryManager memory, bool for64Bit)
{
- _translator = new Translator(new JitMemoryAllocator(), memory, for64Bit);
+ _translator = new Translator(new JitMemoryAllocator(), memory, AddressTable.CreateForArm(for64Bit, memory.Type));
memory.UnmapEvent += UnmapHandler;
}
diff --git a/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs b/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs
index 2a4775a31..43c84c193 100644
--- a/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs
+++ b/src/Ryujinx.Tests/Cpu/EnvironmentTests.cs
@@ -1,3 +1,5 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
using ARMeilleure.Translation;
using NUnit.Framework;
using Ryujinx.Cpu.Jit;
@@ -17,7 +19,10 @@ namespace Ryujinx.Tests.Cpu
private static void EnsureTranslator()
{
// Create a translator, as one is needed to register the signal handler or emit methods.
- _translator ??= new Translator(new JitMemoryAllocator(), new MockMemoryManager(), true);
+ _translator ??= new Translator(
+ new JitMemoryAllocator(),
+ new MockMemoryManager(),
+ AddressTable.CreateForArm(true, MemoryManagerType.SoftwarePageTable));
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
diff --git a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
index 6d2ad8fb0..3e5b47423 100644
--- a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
+++ b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
@@ -1,3 +1,5 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
using ARMeilleure.Signal;
using ARMeilleure.Translation;
using NUnit.Framework;
@@ -53,7 +55,10 @@ namespace Ryujinx.Tests.Memory
private static void EnsureTranslator()
{
// Create a translator, as one is needed to register the signal handler or emit methods.
- _translator ??= new Translator(new JitMemoryAllocator(), new MockMemoryManager(), true);
+ _translator ??= new Translator(
+ new JitMemoryAllocator(),
+ new MockMemoryManager(),
+ AddressTable.CreateForArm(true, MemoryManagerType.SoftwarePageTable));
}
[Test]
From 3b6731a3519f408a361b7355f368583fbcc76107 Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Fri, 22 Nov 2024 17:51:42 -0600
Subject: [PATCH 24/33] infra: Undo packing native libraries into executable.
---
.github/workflows/canary.yml | 4 ++--
.github/workflows/release.yml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
index a24436de3..df28e4784 100644
--- a/.github/workflows/canary.yml
+++ b/.github/workflows/canary.yml
@@ -103,8 +103,8 @@ jobs:
- name: Publish
run: |
- dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained -p:IncludeNativeLibrariesForSelfExtract=true
- dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained -p:IncludeNativeLibrariesForSelfExtract=true
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ec02976a1..fbf715756 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -102,8 +102,8 @@ jobs:
- name: Publish
run: |
- dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained -p:IncludeNativeLibrariesForSelfExtract=true
- dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained -p:IncludeNativeLibrariesForSelfExtract=true
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
From e8d3ad4d8b0d8ad195db32a04c97b7a253f98c1c Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Sat, 23 Nov 2024 13:10:53 -0600
Subject: [PATCH 25/33] UI: RPC: TSUKIHIME -A piece of blue glass moon- asset
image
---
src/Ryujinx.UI.Common/DiscordIntegrationModule.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
index a26f6a7b2..295a663b2 100644
--- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
+++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
@@ -264,6 +264,7 @@ namespace Ryujinx.UI.Common
"0100800015926000", // Suika Game
"0100e46006708000", // Terraria
"01000a10041ea000", // The Elder Scrolls V: Skyrim
+ "010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
"010080b00ad66000", // Undertale
];
}
From a81212bbf12418c0862384104f191b396732b2c7 Mon Sep 17 00:00:00 2001
From: Daniel Zauner
Date: Sun, 24 Nov 2024 16:49:44 +0100
Subject: [PATCH 26/33] Fix window decorations being too wide (#309)
---
src/Ryujinx/Assets/Styles/Styles.xaml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/Ryujinx/Assets/Styles/Styles.xaml b/src/Ryujinx/Assets/Styles/Styles.xaml
index 05212a7dd..878b5e7f1 100644
--- a/src/Ryujinx/Assets/Styles/Styles.xaml
+++ b/src/Ryujinx/Assets/Styles/Styles.xaml
@@ -1,7 +1,8 @@
+ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
+ xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia">
@@ -231,7 +232,7 @@
-
From 7e16fccfc108c92aef1015fb6b37d956f9526947 Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Sun, 24 Nov 2024 18:33:53 +0100
Subject: [PATCH 27/33] UI: Fix icons getting cutoff in the About window (#310)
Before:

After:

---
src/Ryujinx/UI/Windows/AboutWindow.axaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Ryujinx/UI/Windows/AboutWindow.axaml b/src/Ryujinx/UI/Windows/AboutWindow.axaml
index 6d4a7b7e3..1d0e36ae9 100644
--- a/src/Ryujinx/UI/Windows/AboutWindow.axaml
+++ b/src/Ryujinx/UI/Windows/AboutWindow.axaml
@@ -6,8 +6,10 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModel="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- Width="550"
- Height="260"
+ MinWidth="550"
+ MinHeight="260"
+ MaxWidth="600"
+ MaxHeight="500"
Margin="0,-12,0,0"
d:DesignHeight="260"
d:DesignWidth="550"
From 2e6794e69b33405990aff15e7dbe5a0f589666bf Mon Sep 17 00:00:00 2001
From: Keaton
Date: Mon, 25 Nov 2024 13:39:09 -0600
Subject: [PATCH 28/33] Add custom refresh rate mode to VSync option (#238)
Rebased @jcm93's refreshinterval branch:
https://github.com/jcm93/Ryujinx/tree/refreshinterval
The option is placed under System/Hacks. Disabled, it's the default
Ryujinx behavior. Enabled, the behavior is shown in the attached
screenshots. If a framerate is too high or low, you can adjust the value
where you normally toggle VSync on and off. It will also cycle through
the default on/off toggles.
Also, in order to reduce clutter, I made an adjustment to remove the
target FPS and only show the percentage.
---------
Co-authored-by: jcm <6864788+jcm93@users.noreply.github.com>
---
.../Configuration/Hid/KeyboardHotkeys.cs | 4 +-
src/Ryujinx.Common/Configuration/VSyncMode.cs | 9 ++
src/Ryujinx.Graphics.GAL/IWindow.cs | 2 +-
.../Multithreading/ThreadedWindow.cs | 2 +-
src/Ryujinx.Graphics.GAL/VSyncMode.cs | 9 ++
src/Ryujinx.Graphics.OpenGL/Window.cs | 2 +-
src/Ryujinx.Graphics.Vulkan/Window.cs | 13 +-
src/Ryujinx.Graphics.Vulkan/WindowBase.cs | 2 +-
src/Ryujinx.HLE/HLEConfiguration.cs | 18 ++-
.../Services/SurfaceFlinger/SurfaceFlinger.cs | 20 ++-
src/Ryujinx.HLE/Switch.cs | 38 +++++-
src/Ryujinx.Headless.SDL2/Options.cs | 7 +-
src/Ryujinx.Headless.SDL2/Program.cs | 5 +-
.../StatusUpdatedEventArgs.cs | 4 +-
src/Ryujinx.Headless.SDL2/WindowBase.cs | 2 +-
.../Configuration/ConfigurationFileFormat.cs | 20 ++-
.../ConfigurationState.Migration.cs | 45 +++++--
.../Configuration/ConfigurationState.Model.cs | 24 +++-
.../Configuration/ConfigurationState.cs | 10 +-
src/Ryujinx/AppHost.cs | 105 +++++++++++++--
src/Ryujinx/Assets/Locales/en_US.json | 20 ++-
src/Ryujinx/Assets/Styles/Themes.xaml | 5 +-
src/Ryujinx/Common/KeyboardHotkeyState.cs | 4 +-
src/Ryujinx/UI/Models/Input/HotkeyConfig.cs | 38 +++++-
src/Ryujinx/UI/Models/SaveModel.cs | 2 +-
.../UI/Models/StatusUpdatedEventArgs.cs | 7 +-
.../UI/ViewModels/MainWindowViewModel.cs | 123 ++++++++++++++++--
.../UI/ViewModels/SettingsViewModel.cs | 82 +++++++++++-
.../UI/Views/Main/MainStatusBarView.axaml | 54 +++++++-
.../UI/Views/Main/MainStatusBarView.axaml.cs | 7 +-
.../Views/Settings/SettingsHotkeysView.axaml | 20 ++-
.../Settings/SettingsHotkeysView.axaml.cs | 10 +-
.../Views/Settings/SettingsSystemView.axaml | 71 +++++++++-
src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 4 +-
34 files changed, 678 insertions(+), 110 deletions(-)
create mode 100644 src/Ryujinx.Common/Configuration/VSyncMode.cs
create mode 100644 src/Ryujinx.Graphics.GAL/VSyncMode.cs
diff --git a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
index 0cb49ca8c..6b8152b9d 100644
--- a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
@@ -2,7 +2,7 @@ namespace Ryujinx.Common.Configuration.Hid
{
public class KeyboardHotkeys
{
- public Key ToggleVsync { get; set; }
+ public Key ToggleVSyncMode { get; set; }
public Key Screenshot { get; set; }
public Key ShowUI { get; set; }
public Key Pause { get; set; }
@@ -11,5 +11,7 @@ namespace Ryujinx.Common.Configuration.Hid
public Key ResScaleDown { get; set; }
public Key VolumeUp { get; set; }
public Key VolumeDown { get; set; }
+ public Key CustomVSyncIntervalIncrement { get; set; }
+ public Key CustomVSyncIntervalDecrement { get; set; }
}
}
diff --git a/src/Ryujinx.Common/Configuration/VSyncMode.cs b/src/Ryujinx.Common/Configuration/VSyncMode.cs
new file mode 100644
index 000000000..ca93b5e1c
--- /dev/null
+++ b/src/Ryujinx.Common/Configuration/VSyncMode.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Common.Configuration
+{
+ public enum VSyncMode
+ {
+ Switch,
+ Unbounded,
+ Custom
+ }
+}
diff --git a/src/Ryujinx.Graphics.GAL/IWindow.cs b/src/Ryujinx.Graphics.GAL/IWindow.cs
index 83418e709..12686cb28 100644
--- a/src/Ryujinx.Graphics.GAL/IWindow.cs
+++ b/src/Ryujinx.Graphics.GAL/IWindow.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.GAL
void SetSize(int width, int height);
- void ChangeVSyncMode(bool vsyncEnabled);
+ void ChangeVSyncMode(VSyncMode vSyncMode);
void SetAntiAliasing(AntiAliasing antialiasing);
void SetScalingFilter(ScalingFilter type);
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
index acda37ef3..102fdb1bb 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
@@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_impl.Window.SetSize(width, height);
}
- public void ChangeVSyncMode(bool vsyncEnabled) { }
+ public void ChangeVSyncMode(VSyncMode vSyncMode) { }
public void SetAntiAliasing(AntiAliasing effect) { }
diff --git a/src/Ryujinx.Graphics.GAL/VSyncMode.cs b/src/Ryujinx.Graphics.GAL/VSyncMode.cs
new file mode 100644
index 000000000..c5794b8f7
--- /dev/null
+++ b/src/Ryujinx.Graphics.GAL/VSyncMode.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public enum VSyncMode
+ {
+ Switch,
+ Unbounded,
+ Custom
+ }
+}
diff --git a/src/Ryujinx.Graphics.OpenGL/Window.cs b/src/Ryujinx.Graphics.OpenGL/Window.cs
index 285ab725e..1dc8a51f6 100644
--- a/src/Ryujinx.Graphics.OpenGL/Window.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Window.cs
@@ -54,7 +54,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
}
- public void ChangeVSyncMode(bool vsyncEnabled) { }
+ public void ChangeVSyncMode(VSyncMode vSyncMode) { }
public void SetSize(int width, int height)
{
diff --git a/src/Ryujinx.Graphics.Vulkan/Window.cs b/src/Ryujinx.Graphics.Vulkan/Window.cs
index 3dc6d4e19..3e8d3b375 100644
--- a/src/Ryujinx.Graphics.Vulkan/Window.cs
+++ b/src/Ryujinx.Graphics.Vulkan/Window.cs
@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Vulkan
private int _width;
private int _height;
- private bool _vsyncEnabled;
+ private VSyncMode _vSyncMode;
private bool _swapchainIsDirty;
private VkFormat _format;
private AntiAliasing _currentAntiAliasing;
@@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
ImageArrayLayers = 1,
PreTransform = capabilities.CurrentTransform,
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
- PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
+ PresentMode = ChooseSwapPresentMode(presentModes, _vSyncMode),
Clipped = true,
};
@@ -279,9 +279,9 @@ namespace Ryujinx.Graphics.Vulkan
}
}
- private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
+ private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, VSyncMode vSyncMode)
{
- if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
+ if (vSyncMode == VSyncMode.Unbounded && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
{
return PresentModeKHR.ImmediateKhr;
}
@@ -634,9 +634,10 @@ namespace Ryujinx.Graphics.Vulkan
_swapchainIsDirty = true;
}
- public override void ChangeVSyncMode(bool vsyncEnabled)
+ public override void ChangeVSyncMode(VSyncMode vSyncMode)
{
- _vsyncEnabled = vsyncEnabled;
+ _vSyncMode = vSyncMode;
+ //present mode may change, so mark the swapchain for recreation
_swapchainIsDirty = true;
}
diff --git a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs
index edb9c688c..ca06ec0b8 100644
--- a/src/Ryujinx.Graphics.Vulkan/WindowBase.cs
+++ b/src/Ryujinx.Graphics.Vulkan/WindowBase.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
public abstract void Dispose();
public abstract void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback);
public abstract void SetSize(int width, int height);
- public abstract void ChangeVSyncMode(bool vsyncEnabled);
+ public abstract void ChangeVSyncMode(VSyncMode vSyncMode);
public abstract void SetAntiAliasing(AntiAliasing effect);
public abstract void SetScalingFilter(ScalingFilter scalerType);
public abstract void SetScalingFilterLevel(float scale);
diff --git a/src/Ryujinx.HLE/HLEConfiguration.cs b/src/Ryujinx.HLE/HLEConfiguration.cs
index 70fcf278d..f75ead588 100644
--- a/src/Ryujinx.HLE/HLEConfiguration.cs
+++ b/src/Ryujinx.HLE/HLEConfiguration.cs
@@ -9,6 +9,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.UI;
using System;
+using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
namespace Ryujinx.HLE
{
@@ -84,9 +85,14 @@ namespace Ryujinx.HLE
internal readonly RegionCode Region;
///
- /// Control the initial state of the vertical sync in the SurfaceFlinger service.
+ /// Control the initial state of the present interval in the SurfaceFlinger service (previously Vsync).
///
- internal readonly bool EnableVsync;
+ internal readonly VSyncMode VSyncMode;
+
+ ///
+ /// Control the custom VSync interval, if enabled and active.
+ ///
+ internal readonly int CustomVSyncInterval;
///
/// Control the initial state of the docked mode.
@@ -195,7 +201,7 @@ namespace Ryujinx.HLE
IHostUIHandler hostUIHandler,
SystemLanguage systemLanguage,
RegionCode region,
- bool enableVsync,
+ VSyncMode vSyncMode,
bool enableDockedMode,
bool enablePtc,
bool enableInternetAccess,
@@ -212,7 +218,8 @@ namespace Ryujinx.HLE
MultiplayerMode multiplayerMode,
bool multiplayerDisableP2p,
string multiplayerLdnPassphrase,
- string multiplayerLdnServer)
+ string multiplayerLdnServer,
+ int customVSyncInterval)
{
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
@@ -225,7 +232,8 @@ namespace Ryujinx.HLE
HostUIHandler = hostUIHandler;
SystemLanguage = systemLanguage;
Region = region;
- EnableVsync = enableVsync;
+ VSyncMode = vSyncMode;
+ CustomVSyncInterval = customVSyncInterval;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
EnableInternetAccess = enableInternetAccess;
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index 4c17e7aed..601e85867 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -10,13 +10,12 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
+using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
class SurfaceFlinger : IConsumerListener, IDisposable
{
- private const int TargetFps = 60;
-
private readonly Switch _device;
private readonly Dictionary _layers;
@@ -32,6 +31,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private readonly long _spinTicks;
private readonly long _1msTicks;
+ private VSyncMode _vSyncMode;
+ private long _targetVSyncInterval;
+
private int _swapInterval;
private int _swapIntervalDelay;
@@ -88,7 +90,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
else
{
- _ticksPerFrame = Stopwatch.Frequency / TargetFps;
+ _ticksPerFrame = Stopwatch.Frequency / _device.TargetVSyncInterval;
+ _targetVSyncInterval = _device.TargetVSyncInterval;
}
}
@@ -370,15 +373,20 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
if (acquireStatus == Status.Success)
{
- // If device vsync is disabled, reflect the change.
- if (!_device.EnableDeviceVsync)
+ if (_device.VSyncMode == VSyncMode.Unbounded)
{
if (_swapInterval != 0)
{
UpdateSwapInterval(0);
+ _vSyncMode = _device.VSyncMode;
}
}
- else if (item.SwapInterval != _swapInterval)
+ else if (_device.VSyncMode != _vSyncMode)
+ {
+ UpdateSwapInterval(_device.VSyncMode == VSyncMode.Unbounded ? 0 : item.SwapInterval);
+ _vSyncMode = _device.VSyncMode;
+ }
+ else if (item.SwapInterval != _swapInterval || _device.TargetVSyncInterval != _targetVSyncInterval)
{
UpdateSwapInterval(item.SwapInterval);
}
diff --git a/src/Ryujinx.HLE/Switch.cs b/src/Ryujinx.HLE/Switch.cs
index d12cb8f77..466352152 100644
--- a/src/Ryujinx.HLE/Switch.cs
+++ b/src/Ryujinx.HLE/Switch.cs
@@ -27,7 +27,11 @@ namespace Ryujinx.HLE
public TamperMachine TamperMachine { get; }
public IHostUIHandler UIHandler { get; }
- public bool EnableDeviceVsync { get; set; }
+ public VSyncMode VSyncMode { get; set; } = VSyncMode.Switch;
+ public bool CustomVSyncIntervalEnabled { get; set; } = false;
+ public int CustomVSyncInterval { get; set; }
+
+ public long TargetVSyncInterval { get; set; } = 60;
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
@@ -59,12 +63,14 @@ namespace Ryujinx.HLE
System.State.SetLanguage(Configuration.SystemLanguage);
System.State.SetRegion(Configuration.Region);
- EnableDeviceVsync = Configuration.EnableVsync;
+ VSyncMode = Configuration.VSyncMode;
+ CustomVSyncInterval = Configuration.CustomVSyncInterval;
System.State.DockedMode = Configuration.EnableDockedMode;
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
System.EnablePtc = Configuration.EnablePtc;
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
+ UpdateVSyncInterval();
#pragma warning restore IDE0055
}
@@ -75,6 +81,34 @@ namespace Ryujinx.HLE
Gpu.GPFifo.DispatchCalls();
}
+ public void IncrementCustomVSyncInterval()
+ {
+ CustomVSyncInterval += 1;
+ UpdateVSyncInterval();
+ }
+
+ public void DecrementCustomVSyncInterval()
+ {
+ CustomVSyncInterval -= 1;
+ UpdateVSyncInterval();
+ }
+
+ public void UpdateVSyncInterval()
+ {
+ switch (VSyncMode)
+ {
+ case VSyncMode.Custom:
+ TargetVSyncInterval = CustomVSyncInterval;
+ break;
+ case VSyncMode.Switch:
+ TargetVSyncInterval = 60;
+ break;
+ case VSyncMode.Unbounded:
+ TargetVSyncInterval = 1;
+ break;
+ }
+ }
+
public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile);
public bool LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId);
public bool LoadNca(string ncaFile) => Processes.LoadNca(ncaFile);
diff --git a/src/Ryujinx.Headless.SDL2/Options.cs b/src/Ryujinx.Headless.SDL2/Options.cs
index 8078ca5e4..4e2ad5b58 100644
--- a/src/Ryujinx.Headless.SDL2/Options.cs
+++ b/src/Ryujinx.Headless.SDL2/Options.cs
@@ -115,8 +115,11 @@ namespace Ryujinx.Headless.SDL2
[Option("fs-global-access-log-mode", Required = false, Default = 0, HelpText = "Enables FS access log output to the console.")]
public int FsGlobalAccessLogMode { get; set; }
- [Option("disable-vsync", Required = false, HelpText = "Disables Vertical Sync.")]
- public bool DisableVSync { get; set; }
+ [Option("vsync-mode", Required = false, Default = VSyncMode.Switch, HelpText = "Sets the emulated VSync mode (Switch, Unbounded, or Custom).")]
+ public VSyncMode VSyncMode { get; set; }
+
+ [Option("custom-refresh-rate", Required = false, Default = 90, HelpText = "Sets the custom refresh rate target value (integer).")]
+ public int CustomVSyncInterval { get; set; }
[Option("disable-shader-cache", Required = false, HelpText = "Disables Shader cache.")]
public bool DisableShaderCache { get; set; }
diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs
index e3bbd1e51..ff87a3845 100644
--- a/src/Ryujinx.Headless.SDL2/Program.cs
+++ b/src/Ryujinx.Headless.SDL2/Program.cs
@@ -563,7 +563,7 @@ namespace Ryujinx.Headless.SDL2
window,
options.SystemLanguage,
options.SystemRegion,
- !options.DisableVSync,
+ options.VSyncMode,
!options.DisableDockedMode,
!options.DisablePTC,
options.EnableInternetAccess,
@@ -580,7 +580,8 @@ namespace Ryujinx.Headless.SDL2
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
false,
"",
- "");
+ "",
+ options.CustomVSyncInterval);
return new Switch(configuration);
}
diff --git a/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs b/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs
index cd7715712..c1dd3805f 100644
--- a/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs
+++ b/src/Ryujinx.Headless.SDL2/StatusUpdatedEventArgs.cs
@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Headless.SDL2
{
class StatusUpdatedEventArgs(
- bool vSyncEnabled,
+ string vSyncMode,
string dockedMode,
string aspectRatio,
string gameStatus,
@@ -11,7 +11,7 @@ namespace Ryujinx.Headless.SDL2
string gpuName)
: EventArgs
{
- public bool VSyncEnabled = vSyncEnabled;
+ public string VSyncMode = vSyncMode;
public string DockedMode = dockedMode;
public string AspectRatio = aspectRatio;
public string GameStatus = gameStatus;
diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs
index 6d681e100..2479ec127 100644
--- a/src/Ryujinx.Headless.SDL2/WindowBase.cs
+++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs
@@ -314,7 +314,7 @@ namespace Ryujinx.Headless.SDL2
}
StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs(
- Device.EnableDeviceVsync,
+ Device.VSyncMode.ToString(),
dockedMode,
Device.Configuration.AspectRatio.ToText(),
$"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)",
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
index 80ba1b186..027e1052b 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Multiplayer;
@@ -16,7 +17,7 @@ namespace Ryujinx.UI.Common.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 56;
+ public const int CurrentVersion = 57;
///
/// Version of the configuration file format
@@ -191,8 +192,25 @@ namespace Ryujinx.UI.Common.Configuration
///
/// Enables or disables Vertical Sync
///
+ /// Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)
+ /// TODO: Remove this when those older versions aren't in use anymore.
public bool EnableVsync { get; set; }
+ ///
+ /// Current VSync mode; 60 (Switch), unbounded ("Vsync off"), or custom
+ ///
+ public VSyncMode VSyncMode { get; set; }
+
+ ///
+ /// Enables or disables the custom present interval
+ ///
+ public bool EnableCustomVSyncInterval { get; set; }
+
+ ///
+ /// The custom present interval value
+ ///
+ public int CustomVSyncInterval { get; set; }
+
///
/// Enables or disables Shader cache
///
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Migration.cs
index 65dd88106..a41ea2cd7 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Migration.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Migration.cs
@@ -82,7 +82,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = Key.F1,
+ ToggleVSyncMode = Key.F1,
};
configurationFileUpdated = true;
@@ -276,7 +276,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = Key.F1,
+ ToggleVSyncMode = Key.F1,
Screenshot = Key.F8,
};
@@ -289,7 +289,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = Key.F1,
+ ToggleVSyncMode = Key.F1,
Screenshot = Key.F8,
ShowUI = Key.F4,
};
@@ -332,7 +332,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
+ ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = Key.F5,
@@ -347,7 +347,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
+ ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
@@ -421,7 +421,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
+ ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
@@ -448,7 +448,7 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
- ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
+ ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
@@ -611,6 +611,33 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 57)
+ {
+ Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 57.");
+
+ configurationFileFormat.VSyncMode = VSyncMode.Switch;
+ configurationFileFormat.EnableCustomVSyncInterval = false;
+
+ configurationFileFormat.Hotkeys = new KeyboardHotkeys
+ {
+ ToggleVSyncMode = Key.F1,
+ Screenshot = configurationFileFormat.Hotkeys.Screenshot,
+ ShowUI = configurationFileFormat.Hotkeys.ShowUI,
+ Pause = configurationFileFormat.Hotkeys.Pause,
+ ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
+ ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
+ ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
+ VolumeUp = configurationFileFormat.Hotkeys.VolumeUp,
+ VolumeDown = configurationFileFormat.Hotkeys.VolumeDown,
+ CustomVSyncIntervalIncrement = Key.Unbound,
+ CustomVSyncIntervalDecrement = Key.Unbound,
+ };
+
+ configurationFileFormat.CustomVSyncInterval = 120;
+
+ configurationFileUpdated = true;
+ }
+
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
@@ -646,7 +673,9 @@ namespace Ryujinx.UI.Common.Configuration
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
HideCursor.Value = configurationFileFormat.HideCursor;
- Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
+ Graphics.VSyncMode.Value = configurationFileFormat.VSyncMode;
+ Graphics.EnableCustomVSyncInterval.Value = configurationFileFormat.EnableCustomVSyncInterval;
+ Graphics.CustomVSyncInterval.Value = configurationFileFormat.CustomVSyncInterval;
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Model.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Model.cs
index 9be8f4df7..f28ce0348 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Model.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.Model.cs
@@ -1,4 +1,4 @@
-using ARMeilleure;
+using ARMeilleure;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
@@ -474,9 +474,19 @@ namespace Ryujinx.UI.Common.Configuration
public ReactiveObject ShadersDumpPath { get; private set; }
///
- /// Enables or disables Vertical Sync
+ /// Toggles the present interval mode. Options are Switch (60Hz), Unbounded (previously Vsync off), and Custom, if enabled.
///
- public ReactiveObject EnableVsync { get; private set; }
+ public ReactiveObject VSyncMode { get; private set; }
+
+ ///
+ /// Enables or disables the custom present interval mode.
+ ///
+ public ReactiveObject EnableCustomVSyncInterval { get; private set; }
+
+ ///
+ /// Changes the custom present interval.
+ ///
+ public ReactiveObject CustomVSyncInterval { get; private set; }
///
/// Enables or disables Shader cache
@@ -536,8 +546,12 @@ namespace Ryujinx.UI.Common.Configuration
AspectRatio = new ReactiveObject();
AspectRatio.LogChangesToValue(nameof(AspectRatio));
ShadersDumpPath = new ReactiveObject();
- EnableVsync = new ReactiveObject();
- EnableVsync.LogChangesToValue(nameof(EnableVsync));
+ VSyncMode = new ReactiveObject();
+ VSyncMode.LogChangesToValue(nameof(VSyncMode));
+ EnableCustomVSyncInterval = new ReactiveObject();
+ EnableCustomVSyncInterval.LogChangesToValue(nameof(EnableCustomVSyncInterval));
+ CustomVSyncInterval = new ReactiveObject();
+ CustomVSyncInterval.LogChangesToValue(nameof(CustomVSyncInterval));
EnableShaderCache = new ReactiveObject();
EnableShaderCache.LogChangesToValue(nameof(EnableShaderCache));
EnableTextureRecompression = new ReactiveObject();
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
index b3012568e..badb047df 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
@@ -64,7 +64,9 @@ namespace Ryujinx.UI.Common.Configuration
ShowTitleBar = ShowTitleBar,
EnableHardwareAcceleration = EnableHardwareAcceleration,
HideCursor = HideCursor,
- EnableVsync = Graphics.EnableVsync,
+ VSyncMode = Graphics.VSyncMode,
+ EnableCustomVSyncInterval = Graphics.EnableCustomVSyncInterval,
+ CustomVSyncInterval = Graphics.CustomVSyncInterval,
EnableShaderCache = Graphics.EnableShaderCache,
EnableTextureRecompression = Graphics.EnableTextureRecompression,
EnableMacroHLE = Graphics.EnableMacroHLE,
@@ -179,7 +181,9 @@ namespace Ryujinx.UI.Common.Configuration
ShowTitleBar.Value = !OperatingSystem.IsWindows();
EnableHardwareAcceleration.Value = true;
HideCursor.Value = HideCursorMode.OnIdle;
- Graphics.EnableVsync.Value = true;
+ Graphics.VSyncMode.Value = VSyncMode.Switch;
+ Graphics.CustomVSyncInterval.Value = 120;
+ Graphics.EnableCustomVSyncInterval.Value = false;
Graphics.EnableShaderCache.Value = true;
Graphics.EnableTextureRecompression.Value = false;
Graphics.EnableMacroHLE.Value = true;
@@ -240,7 +244,7 @@ namespace Ryujinx.UI.Common.Configuration
Hid.EnableMouse.Value = false;
Hid.Hotkeys.Value = new KeyboardHotkeys
{
- ToggleVsync = Key.F1,
+ ToggleVSyncMode = Key.F1,
ToggleMute = Key.F2,
Screenshot = Key.F8,
ShowUI = Key.F4,
diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs
index d1398f194..5789737d6 100644
--- a/src/Ryujinx/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
@@ -57,6 +57,8 @@ using Key = Ryujinx.Input.Key;
using MouseButton = Ryujinx.Input.MouseButton;
using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter;
using Size = Avalonia.Size;
+using Switch = Ryujinx.HLE.Switch;
+using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
namespace Ryujinx.Ava
{
@@ -203,6 +205,9 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter;
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel;
ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event += UpdateColorSpacePassthrough;
+ ConfigurationState.Instance.Graphics.VSyncMode.Event += UpdateVSyncMode;
+ ConfigurationState.Instance.Graphics.CustomVSyncInterval.Event += UpdateCustomVSyncIntervalValue;
+ ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Event += UpdateCustomVSyncIntervalEnabled;
ConfigurationState.Instance.System.EnableInternetAccess.Event += UpdateEnableInternetAccessState;
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
@@ -295,6 +300,66 @@ namespace Ryujinx.Ava
_renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
}
+ public void UpdateVSyncMode(object sender, ReactiveEventArgs e)
+ {
+ if (Device != null)
+ {
+ Device.VSyncMode = e.NewValue;
+ Device.UpdateVSyncInterval();
+ }
+ _renderer.Window?.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)e.NewValue);
+
+ _viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
+ }
+
+ public void VSyncModeToggle()
+ {
+ VSyncMode oldVSyncMode = Device.VSyncMode;
+ VSyncMode newVSyncMode = VSyncMode.Switch;
+ bool customVSyncIntervalEnabled = ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Value;
+
+ switch (oldVSyncMode)
+ {
+ case VSyncMode.Switch:
+ newVSyncMode = VSyncMode.Unbounded;
+ break;
+ case VSyncMode.Unbounded:
+ if (customVSyncIntervalEnabled)
+ {
+ newVSyncMode = VSyncMode.Custom;
+ }
+ else
+ {
+ newVSyncMode = VSyncMode.Switch;
+ }
+
+ break;
+ case VSyncMode.Custom:
+ newVSyncMode = VSyncMode.Switch;
+ break;
+ }
+
+ UpdateVSyncMode(this, new ReactiveEventArgs(oldVSyncMode, newVSyncMode));
+ }
+
+ private void UpdateCustomVSyncIntervalValue(object sender, ReactiveEventArgs e)
+ {
+ if (Device != null)
+ {
+ Device.TargetVSyncInterval = e.NewValue;
+ Device.UpdateVSyncInterval();
+ }
+ }
+
+ private void UpdateCustomVSyncIntervalEnabled(object sender, ReactiveEventArgs e)
+ {
+ if (Device != null)
+ {
+ Device.CustomVSyncIntervalEnabled = e.NewValue;
+ Device.UpdateVSyncInterval();
+ }
+ }
+
private void ShowCursor()
{
Dispatcher.UIThread.Post(() =>
@@ -505,12 +570,6 @@ namespace Ryujinx.Ava
Device.Configuration.MultiplayerDisableP2p = e.NewValue;
}
- public void ToggleVSync()
- {
- Device.EnableDeviceVsync = !Device.EnableDeviceVsync;
- _renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);
- }
-
public void Stop()
{
_isActive = false;
@@ -864,7 +923,7 @@ namespace Ryujinx.Ava
_viewModel.UiHandler,
(SystemLanguage)ConfigurationState.Instance.System.Language.Value,
(RegionCode)ConfigurationState.Instance.System.Region.Value,
- ConfigurationState.Instance.Graphics.EnableVsync,
+ ConfigurationState.Instance.Graphics.VSyncMode,
ConfigurationState.Instance.System.EnableDockedMode,
ConfigurationState.Instance.System.EnablePtc,
ConfigurationState.Instance.System.EnableInternetAccess,
@@ -881,7 +940,8 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Multiplayer.Mode,
ConfigurationState.Instance.Multiplayer.DisableP2p,
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
- ConfigurationState.Instance.Multiplayer.LdnServer));
+ ConfigurationState.Instance.Multiplayer.LdnServer,
+ ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value));
}
private static IHardwareDeviceDriver InitializeAudio()
@@ -1002,7 +1062,7 @@ namespace Ryujinx.Ava
Device.Gpu.SetGpuThread();
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
- _renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);
+ _renderer.Window.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)Device.VSyncMode);
while (_isActive)
{
@@ -1063,6 +1123,7 @@ namespace Ryujinx.Ava
{
// Run a status update only when a frame is to be drawn. This prevents from updating the ui and wasting a render when no frame is queued.
string dockedMode = ConfigurationState.Instance.System.EnableDockedMode ? LocaleManager.Instance[LocaleKeys.Docked] : LocaleManager.Instance[LocaleKeys.Handheld];
+ string vSyncMode = Device.VSyncMode.ToString();
UpdateShaderCount();
@@ -1072,7 +1133,7 @@ namespace Ryujinx.Ava
}
StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs(
- Device.EnableDeviceVsync,
+ vSyncMode,
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
dockedMode,
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
@@ -1175,8 +1236,16 @@ namespace Ryujinx.Ava
{
switch (currentHotkeyState)
{
- case KeyboardHotkeyState.ToggleVSync:
- ToggleVSync();
+ case KeyboardHotkeyState.ToggleVSyncMode:
+ VSyncModeToggle();
+ break;
+ case KeyboardHotkeyState.CustomVSyncIntervalDecrement:
+ Device.DecrementCustomVSyncInterval();
+ _viewModel.CustomVSyncInterval -= 1;
+ break;
+ case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
+ Device.IncrementCustomVSyncInterval();
+ _viewModel.CustomVSyncInterval += 1;
break;
case KeyboardHotkeyState.Screenshot:
ScreenshotRequested = true;
@@ -1263,9 +1332,9 @@ namespace Ryujinx.Ava
{
KeyboardHotkeyState state = KeyboardHotkeyState.None;
- if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleVsync))
+ if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleVSyncMode))
{
- state = KeyboardHotkeyState.ToggleVSync;
+ state = KeyboardHotkeyState.ToggleVSyncMode;
}
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Screenshot))
{
@@ -1299,6 +1368,14 @@ namespace Ryujinx.Ava
{
state = KeyboardHotkeyState.VolumeDown;
}
+ else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.CustomVSyncIntervalIncrement))
+ {
+ state = KeyboardHotkeyState.CustomVSyncIntervalIncrement;
+ }
+ else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.CustomVSyncIntervalDecrement))
+ {
+ state = KeyboardHotkeyState.CustomVSyncIntervalDecrement;
+ }
return state;
}
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 23135866d..13ffeb759 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -142,9 +142,20 @@
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Latin American Spanish",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Simplified Chinese",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditional Chinese",
- "SettingsTabSystemSystemTimeZone": "System TimeZone:",
+ "SettingsTabSystemSystemTimeZone": "System Time Zone:",
"SettingsTabSystemSystemTime": "System Time:",
- "SettingsTabSystemEnableVsync": "VSync",
+ "SettingsTabSystemVSyncMode": "VSync:",
+ "SettingsTabSystemEnableCustomVSyncInterval": "Enable custom refresh rate (Experimental)",
+ "SettingsTabSystemVSyncModeSwitch": "Switch",
+ "SettingsTabSystemVSyncModeUnbounded": "Unbounded",
+ "SettingsTabSystemVSyncModeCustom": "Custom Refresh Rate",
+ "SettingsTabSystemVSyncModeTooltip": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate.",
+ "SettingsTabSystemVSyncModeTooltipCustom": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate. 'Custom' emulates the specified custom refresh rate.",
+ "SettingsTabSystemEnableCustomVSyncIntervalTooltip": "Allows the user to specify an emulated refresh rate. In some titles, this may speed up or slow down the rate of gameplay logic. In other titles, it may allow for capping FPS at some multiple of the refresh rate, or lead to unpredictable behavior. This is an experimental feature, with no guarantees for how gameplay will be affected. \n\nLeave OFF if unsure.",
+ "SettingsTabSystemCustomVSyncIntervalValueTooltip": "The custom refresh rate target value.",
+ "SettingsTabSystemCustomVSyncIntervalSliderTooltip": "The custom refresh rate, as a percentage of the normal Switch refresh rate.",
+ "SettingsTabSystemCustomVSyncIntervalPercentage": "Custom Refresh Rate %:",
+ "SettingsTabSystemCustomVSyncIntervalValue": "Custom Refresh Rate Value:",
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC cache",
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks",
@@ -153,6 +164,7 @@
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
+ "SettingsTabSystemCustomVSyncInterval": "Interval",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": "May cause instability",
"SettingsTabSystemDramSize": "DRAM size:",
@@ -720,11 +732,13 @@
"RyujinxUpdater": "Ryujinx Updater",
"SettingsTabHotkeys": "Keyboard Hotkeys",
"SettingsTabHotkeysHotkeys": "Keyboard Hotkeys",
- "SettingsTabHotkeysToggleVsyncHotkey": "Toggle VSync:",
+ "SettingsTabHotkeysToggleVSyncModeHotkey": "Toggle VSync mode:",
"SettingsTabHotkeysScreenshotHotkey": "Screenshot:",
"SettingsTabHotkeysShowUiHotkey": "Show UI:",
"SettingsTabHotkeysPauseHotkey": "Pause:",
"SettingsTabHotkeysToggleMuteHotkey": "Mute:",
+ "SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey": "Raise custom refresh rate",
+ "SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey": "Lower custom refresh rate",
"ControllerMotionTitle": "Motion Control Settings",
"ControllerRumbleTitle": "Rumble Settings",
"SettingsSelectThemeFileDialogTitle": "Select Theme File",
diff --git a/src/Ryujinx/Assets/Styles/Themes.xaml b/src/Ryujinx/Assets/Styles/Themes.xaml
index 0f323f84b..056eba228 100644
--- a/src/Ryujinx/Assets/Styles/Themes.xaml
+++ b/src/Ryujinx/Assets/Styles/Themes.xaml
@@ -26,8 +26,9 @@
#b3ffffff#80cccccc#A0000000
- #FF2EEAC9
- #FFFF4554
+ #FF2EEAC9
+ #FFFF4554
+ #6483F5 _toggleVsync;
+ get => _toggleVSyncMode;
set
{
- _toggleVsync = value;
+ _toggleVSyncMode = value;
OnPropertyChanged();
}
}
@@ -104,11 +104,33 @@ namespace Ryujinx.Ava.UI.Models.Input
}
}
+ private Key _customVSyncIntervalIncrement;
+ public Key CustomVSyncIntervalIncrement
+ {
+ get => _customVSyncIntervalIncrement;
+ set
+ {
+ _customVSyncIntervalIncrement = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _customVSyncIntervalDecrement;
+ public Key CustomVSyncIntervalDecrement
+ {
+ get => _customVSyncIntervalDecrement;
+ set
+ {
+ _customVSyncIntervalDecrement = value;
+ OnPropertyChanged();
+ }
+ }
+
public HotkeyConfig(KeyboardHotkeys config)
{
if (config != null)
{
- ToggleVsync = config.ToggleVsync;
+ ToggleVSyncMode = config.ToggleVSyncMode;
Screenshot = config.Screenshot;
ShowUI = config.ShowUI;
Pause = config.Pause;
@@ -117,6 +139,8 @@ namespace Ryujinx.Ava.UI.Models.Input
ResScaleDown = config.ResScaleDown;
VolumeUp = config.VolumeUp;
VolumeDown = config.VolumeDown;
+ CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
+ CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
}
}
@@ -124,7 +148,7 @@ namespace Ryujinx.Ava.UI.Models.Input
{
var config = new KeyboardHotkeys
{
- ToggleVsync = ToggleVsync,
+ ToggleVSyncMode = ToggleVSyncMode,
Screenshot = Screenshot,
ShowUI = ShowUI,
Pause = Pause,
@@ -133,6 +157,8 @@ namespace Ryujinx.Ava.UI.Models.Input
ResScaleDown = ResScaleDown,
VolumeUp = VolumeUp,
VolumeDown = VolumeDown,
+ CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
+ CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
};
return config;
diff --git a/src/Ryujinx/UI/Models/SaveModel.cs b/src/Ryujinx/UI/Models/SaveModel.cs
index 55408ac3a..cfc397c6e 100644
--- a/src/Ryujinx/UI/Models/SaveModel.cs
+++ b/src/Ryujinx/UI/Models/SaveModel.cs
@@ -47,7 +47,7 @@ namespace Ryujinx.Ava.UI.Models
TitleId = info.ProgramId;
UserId = info.UserId;
- var appData = App.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase));
+ var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase));
InGameList = appData != null;
diff --git a/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs
index 40f783c44..6f0f5ab5d 100644
--- a/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs
+++ b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs
@@ -4,18 +4,17 @@ namespace Ryujinx.Ava.UI.Models
{
internal class StatusUpdatedEventArgs : EventArgs
{
- public bool VSyncEnabled { get; }
+ public string VSyncMode { get; }
public string VolumeStatus { get; }
public string AspectRatio { get; }
public string DockedMode { get; }
public string FifoStatus { get; }
public string GameStatus { get; }
-
public uint ShaderCount { get; }
- public StatusUpdatedEventArgs(bool vSyncEnabled, string volumeStatus, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, uint shaderCount)
+ public StatusUpdatedEventArgs(string vSyncMode, string volumeStatus, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, uint shaderCount)
{
- VSyncEnabled = vSyncEnabled;
+ VSyncMode = vSyncMode;
VolumeStatus = volumeStatus;
DockedMode = dockedMode;
AspectRatio = aspectRatio;
diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index f1587a0ff..824fdd717 100644
--- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
@@ -63,6 +63,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private string _searchText;
private Timer _searchTimer;
private string _dockedStatusText;
+ private string _vSyncModeText;
private string _fifoStatusText;
private string _gameStatusText;
private string _volumeStatusText;
@@ -80,7 +81,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private bool _showStatusSeparator;
private Brush _progressBarForegroundColor;
private Brush _progressBarBackgroundColor;
- private Brush _vsyncColor;
+ private Brush _vSyncModeColor;
private byte[] _selectedIcon;
private bool _isAppletMenuActive;
private int _statusBarProgressMaximum;
@@ -111,6 +112,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private WindowState _windowState;
private double _windowWidth;
private double _windowHeight;
+ private int _customVSyncInterval;
+ private int _customVSyncIntervalPercentageProxy;
private bool _isActive;
private bool _isSubMenuOpen;
@@ -145,6 +148,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Volume = ConfigurationState.Instance.System.AudioVolume;
}
+ CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
}
public void Initialize(
@@ -447,17 +451,87 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
- public Brush VsyncColor
+ public Brush VSyncModeColor
{
- get => _vsyncColor;
+ get => _vSyncModeColor;
set
{
- _vsyncColor = value;
+ _vSyncModeColor = value;
OnPropertyChanged();
}
}
+ public bool ShowCustomVSyncIntervalPicker
+ {
+ get
+ {
+ if (_isGameRunning)
+ {
+ return AppHost.Device.VSyncMode ==
+ VSyncMode.Custom;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ set
+ {
+ OnPropertyChanged();
+ }
+ }
+
+ public int CustomVSyncIntervalPercentageProxy
+ {
+ get => _customVSyncIntervalPercentageProxy;
+ set
+ {
+ int newInterval = (int)((value / 100f) * 60);
+ _customVSyncInterval = newInterval;
+ _customVSyncIntervalPercentageProxy = value;
+ if (_isGameRunning)
+ {
+ AppHost.Device.CustomVSyncInterval = newInterval;
+ AppHost.Device.UpdateVSyncInterval();
+ }
+ OnPropertyChanged((nameof(CustomVSyncInterval)));
+ OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
+ }
+ }
+
+ public string CustomVSyncIntervalPercentageText
+ {
+ get
+ {
+ string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
+ return text;
+ }
+ set
+ {
+
+ }
+ }
+
+ public int CustomVSyncInterval
+ {
+ get => _customVSyncInterval;
+ set
+ {
+ _customVSyncInterval = value;
+ int newPercent = (int)((value / 60f) * 100);
+ _customVSyncIntervalPercentageProxy = newPercent;
+ if (_isGameRunning)
+ {
+ AppHost.Device.CustomVSyncInterval = value;
+ AppHost.Device.UpdateVSyncInterval();
+ }
+ OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
+ OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
+ OnPropertyChanged();
+ }
+ }
+
public byte[] SelectedIcon
{
get => _selectedIcon;
@@ -578,6 +652,17 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
+ public string VSyncModeText
+ {
+ get => _vSyncModeText;
+ set
+ {
+ _vSyncModeText = value;
+
+ OnPropertyChanged();
+ }
+ }
+
public string DockedStatusText
{
get => _dockedStatusText;
@@ -1292,17 +1377,18 @@ namespace Ryujinx.Ava.UI.ViewModels
{
Dispatcher.UIThread.InvokeAsync(() =>
{
- Application.Current!.Styles.TryGetResource(args.VSyncEnabled
- ? "VsyncEnabled"
- : "VsyncDisabled",
+ Application.Current!.Styles.TryGetResource(args.VSyncMode,
Application.Current.ActualThemeVariant,
out object color);
if (color is Color clr)
{
- VsyncColor = new SolidColorBrush(clr);
+ VSyncModeColor = new SolidColorBrush(clr);
}
+ VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
+ ShowCustomVSyncIntervalPicker =
+ args.VSyncMode == VSyncMode.Custom.ToString();
DockedStatusText = args.DockedMode;
AspectRatioStatusText = args.AspectRatio;
GameStatusText = args.GameStatus;
@@ -1495,6 +1581,27 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
+ public void ToggleVSyncMode()
+ {
+ AppHost.VSyncModeToggle();
+ OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
+ }
+
+ public void VSyncModeSettingChanged()
+ {
+ if (_isGameRunning)
+ {
+ AppHost.Device.CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
+ AppHost.Device.UpdateVSyncInterval();
+ }
+
+ CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
+ OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
+ OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
+ OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
+ OnPropertyChanged(nameof(CustomVSyncInterval));
+ }
+
public async Task ExitCurrentState()
{
if (WindowState is WindowState.FullScreen)
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index 2da252d00..a5abeb36b 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -52,6 +52,10 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _graphicsBackendIndex;
private int _scalingFilter;
private int _scalingFilterLevel;
+ private int _customVSyncInterval;
+ private bool _enableCustomVSyncInterval;
+ private int _customVSyncIntervalPercentageProxy;
+ private VSyncMode _vSyncMode;
public event Action CloseWindow;
public event Action SaveSettingsEvent;
@@ -154,7 +158,74 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
- public bool EnableVsync { get; set; }
+ public VSyncMode VSyncMode
+ {
+ get => _vSyncMode;
+ set
+ {
+ if (value == VSyncMode.Custom ||
+ value == VSyncMode.Switch ||
+ value == VSyncMode.Unbounded)
+ {
+ _vSyncMode = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
+ public int CustomVSyncIntervalPercentageProxy
+ {
+ get => _customVSyncIntervalPercentageProxy;
+ set
+ {
+ int newInterval = (int)((value / 100f) * 60);
+ _customVSyncInterval = newInterval;
+ _customVSyncIntervalPercentageProxy = value;
+ OnPropertyChanged((nameof(CustomVSyncInterval)));
+ OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
+ }
+ }
+
+ public string CustomVSyncIntervalPercentageText
+ {
+ get
+ {
+ string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
+ return text;
+ }
+ }
+
+ public bool EnableCustomVSyncInterval
+ {
+ get => _enableCustomVSyncInterval;
+ set
+ {
+ _enableCustomVSyncInterval = value;
+ if (_vSyncMode == VSyncMode.Custom && !value)
+ {
+ VSyncMode = VSyncMode.Switch;
+ }
+ else if (value)
+ {
+ VSyncMode = VSyncMode.Custom;
+ }
+ OnPropertyChanged();
+ }
+ }
+
+ public int CustomVSyncInterval
+ {
+ get => _customVSyncInterval;
+ set
+ {
+ _customVSyncInterval = value;
+ int newPercent = (int)((value / 60f) * 100);
+ _customVSyncIntervalPercentageProxy = newPercent;
+ OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
+ OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
+ OnPropertyChanged();
+ }
+ }
public bool EnablePptc { get; set; }
public bool EnableLowPowerPptc { get; set; }
public bool EnableInternetAccess { get; set; }
@@ -484,7 +555,9 @@ namespace Ryujinx.Ava.UI.ViewModels
CurrentDate = currentDateTime.Date;
CurrentTime = currentDateTime.TimeOfDay;
- EnableVsync = config.Graphics.EnableVsync;
+ EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval.Value;
+ CustomVSyncInterval = config.Graphics.CustomVSyncInterval;
+ VSyncMode = config.Graphics.VSyncMode;
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
DramSize = config.System.DramSize;
IgnoreMissingServices = config.System.IgnoreMissingServices;
@@ -590,7 +663,9 @@ namespace Ryujinx.Ava.UI.ViewModels
}
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
- config.Graphics.EnableVsync.Value = EnableVsync;
+ config.Graphics.VSyncMode.Value = VSyncMode;
+ config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
+ config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
config.System.DramSize.Value = DramSize;
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
@@ -660,6 +735,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
MainWindow.UpdateGraphicsConfig();
+ MainWindow.MainWindowViewModel.VSyncModeSettingChanged();
SaveSettingsEvent?.Invoke();
diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
index 0e0526f49..597cf10e1 100644
--- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
@@ -79,15 +79,59 @@
MaxHeight="18"
Orientation="Horizontal">
+ PointerReleased="VSyncMode_PointerReleased"
+ Text="{Binding VSyncModeText}"
+ TextAlignment="Start"/>
+
-
-
-
+
+
+
@@ -103,6 +103,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
index fb0fe2bb1..609f61633 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
@@ -82,8 +82,8 @@ namespace Ryujinx.Ava.UI.Views.Settings
switch (button.Name)
{
- case "ToggleVsync":
- viewModel.KeyboardHotkey.ToggleVsync = buttonValue.AsHidType();
+ case "ToggleVSyncMode":
+ viewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType();
break;
case "Screenshot":
viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType();
@@ -109,6 +109,12 @@ namespace Ryujinx.Ava.UI.Views.Settings
case "VolumeDown":
viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType();
break;
+ case "CustomVSyncIntervalIncrement":
+ viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = buttonValue.AsHidType();
+ break;
+ case "CustomVSyncIntervalDecrement":
+ viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType();
+ break;
}
}
};
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml
index 4fe57b425..e04e541c3 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml
@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
@@ -181,11 +182,68 @@
Width="350"
ToolTip.Tip="{ext:Locale TimeTooltip}" />
-
+
-
+ VerticalAlignment="Center"
+ Text="{ext:Locale SettingsTabSystemVSyncMode}"
+ ToolTip.Tip="{ext:Locale SettingsTabSystemVSyncModeTooltip}"
+ Width="250" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
index 829db4bc9..059f99a60 100644
--- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
@@ -38,6 +38,8 @@ namespace Ryujinx.Ava.UI.Windows
{
public partial class MainWindow : StyleableAppWindow
{
+ internal static MainWindowViewModel MainWindowViewModel { get; private set; }
+
public MainWindowViewModel ViewModel { get; }
internal readonly AvaHostUIHandler UiHandler;
@@ -73,7 +75,7 @@ namespace Ryujinx.Ava.UI.Windows
public MainWindow()
{
- DataContext = ViewModel = new MainWindowViewModel
+ DataContext = ViewModel = MainWindowViewModel = new MainWindowViewModel
{
Window = this
};
From a18cecbc30168e347757ced631e652a40b001133 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hack=E8=8C=B6=E3=82=93?=
<120134269+Hackjjang@users.noreply.github.com>
Date: Tue, 26 Nov 2024 04:40:39 +0900
Subject: [PATCH 29/33] Korean "Show Changelog" translation (#313)
---
src/Ryujinx/Assets/Locales/ko_KR.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index 47a619054..8baf559be 100644
--- a/src/Ryujinx/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
@@ -457,7 +457,7 @@
"DialogUpdaterExtractionMessage": "업데이트 추출 중...",
"DialogUpdaterRenamingMessage": "이름 변경 업데이트...",
"DialogUpdaterAddingFilesMessage": "새 업데이트 추가 중...",
- "DialogUpdaterShowChangelogMessage": "Show Changelog",
+ "DialogUpdaterShowChangelogMessage": "변경 로그 보기",
"DialogUpdaterCompleteMessage": "업데이트가 완료되었습니다!",
"DialogUpdaterRestartMessage": "지금 Ryujinx를 다시 시작하시겠습니까?",
"DialogUpdaterNoInternetMessage": "인터넷에 연결되어 있지 않습니다!",
From f72d2c1b2bd17aa25df146d31a39b98a47b524aa Mon Sep 17 00:00:00 2001
From: GabCoolGuy
Date: Mon, 25 Nov 2024 20:43:01 +0100
Subject: [PATCH 30/33] UI: Add Mii Edit Applet Locale (#311)
This allows the "Mii Edit Applet" dropdown to be localized ( I already
went ahead and localized French )
---
src/Ryujinx/Assets/Locales/ar_SA.json | 1 +
src/Ryujinx/Assets/Locales/de_DE.json | 1 +
src/Ryujinx/Assets/Locales/el_GR.json | 1 +
src/Ryujinx/Assets/Locales/en_US.json | 1 +
src/Ryujinx/Assets/Locales/es_ES.json | 1 +
src/Ryujinx/Assets/Locales/fr_FR.json | 1 +
src/Ryujinx/Assets/Locales/he_IL.json | 1 +
src/Ryujinx/Assets/Locales/it_IT.json | 1 +
src/Ryujinx/Assets/Locales/ja_JP.json | 1 +
src/Ryujinx/Assets/Locales/ko_KR.json | 1 +
src/Ryujinx/Assets/Locales/pl_PL.json | 1 +
src/Ryujinx/Assets/Locales/pt_BR.json | 1 +
src/Ryujinx/Assets/Locales/ru_RU.json | 1 +
src/Ryujinx/Assets/Locales/th_TH.json | 1 +
src/Ryujinx/Assets/Locales/tr_TR.json | 1 +
src/Ryujinx/Assets/Locales/uk_UA.json | 1 +
src/Ryujinx/Assets/Locales/zh_CN.json | 1 +
src/Ryujinx/Assets/Locales/zh_TW.json | 1 +
src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml | 2 +-
19 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json
index c937a2eed..62992ff34 100644
--- a/src/Ryujinx/Assets/Locales/ar_SA.json
+++ b/src/Ryujinx/Assets/Locales/ar_SA.json
@@ -1,6 +1,7 @@
{
"Language": "اَلْعَرَبِيَّةُ",
"MenuBarFileOpenApplet": "فتح التطبيق المصغر",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "افتح تطبيق تحرير Mii في الوضع المستقل",
"SettingsTabInputDirectMouseAccess": "الوصول المباشر للفأرة",
"SettingsTabSystemMemoryManagerMode": "وضع إدارة الذاكرة:",
diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index c27de5608..91141b7af 100644
--- a/src/Ryujinx/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
@@ -1,6 +1,7 @@
{
"Language": "Deutsch",
"MenuBarFileOpenApplet": "Öffne Anwendung",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Öffnet das Mii-Editor-Applet im Standalone-Modus",
"SettingsTabInputDirectMouseAccess": "Direkter Mauszugriff",
"SettingsTabSystemMemoryManagerMode": "Speichermanagermodus:",
diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index d47c8b9fe..a589d31ad 100644
--- a/src/Ryujinx/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
@@ -1,6 +1,7 @@
{
"Language": "Ελληνικά",
"MenuBarFileOpenApplet": "Άνοιγμα Applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Άνοιγμα του Mii Editor Applet σε Αυτόνομη λειτουργία",
"SettingsTabInputDirectMouseAccess": "Άμεση Πρόσβαση Ποντικιού",
"SettingsTabSystemMemoryManagerMode": "Λειτουργία Διαχείρισης Μνήμης:",
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 13ffeb759..90290b760 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -1,6 +1,7 @@
{
"Language": "English (US)",
"MenuBarFileOpenApplet": "Open Applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Open Mii Editor Applet in Standalone mode",
"SettingsTabInputDirectMouseAccess": "Direct Mouse Access",
"SettingsTabSystemMemoryManagerMode": "Memory Manager Mode:",
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index 8456040ce..8a426b3a4 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -1,6 +1,7 @@
{
"Language": "Español (ES)",
"MenuBarFileOpenApplet": "Abrir applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abre el editor de Mii en modo autónomo",
"SettingsTabInputDirectMouseAccess": "Acceso directo al ratón",
"SettingsTabSystemMemoryManagerMode": "Modo del administrador de memoria:",
diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json
index f17a7ba95..355c2814d 100644
--- a/src/Ryujinx/Assets/Locales/fr_FR.json
+++ b/src/Ryujinx/Assets/Locales/fr_FR.json
@@ -1,6 +1,7 @@
{
"Language": "Français",
"MenuBarFileOpenApplet": "Ouvrir un programme",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Éditeur de Mii",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Ouvrir l'éditeur Mii en mode Standalone",
"SettingsTabInputDirectMouseAccess": "Accès direct à la souris",
"SettingsTabSystemMemoryManagerMode": "Mode de gestion de la mémoire :",
diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index f0cf4eb68..51c3c8835 100644
--- a/src/Ryujinx/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
@@ -1,6 +1,7 @@
{
"Language": "עִברִית",
"MenuBarFileOpenApplet": "פתח יישומון",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "פתח את יישומון עורך ה- Mii במצב עצמאי",
"SettingsTabInputDirectMouseAccess": "גישה ישירה לעכבר",
"SettingsTabSystemMemoryManagerMode": "מצב מנהל זיכרון:",
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index dd408bf5b..52ea833d3 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -1,6 +1,7 @@
{
"Language": "Italiano",
"MenuBarFileOpenApplet": "Apri applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Apri l'applet Mii Editor in modalità Standalone",
"SettingsTabInputDirectMouseAccess": "Accesso diretto al mouse",
"SettingsTabSystemMemoryManagerMode": "Modalità di gestione della memoria:",
diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index 244730494..59b7aa3b3 100644
--- a/src/Ryujinx/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
@@ -1,6 +1,7 @@
{
"Language": "日本語",
"MenuBarFileOpenApplet": "アプレットを開く",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "スタンドアロンモードで Mii エディタアプレットを開きます",
"SettingsTabInputDirectMouseAccess": "マウス直接アクセス",
"SettingsTabSystemMemoryManagerMode": "メモリ管理モード:",
diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index 8baf559be..aeeb84c62 100644
--- a/src/Ryujinx/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
@@ -1,6 +1,7 @@
{
"Language": "한국어",
"MenuBarFileOpenApplet": "애플릿 열기",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "독립 실행형 모드로 Mii 편집기 애플릿 열기",
"SettingsTabInputDirectMouseAccess": "마우스 직접 접근",
"SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드 :",
diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index cfa9d7a76..1d8cf4f03 100644
--- a/src/Ryujinx/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
@@ -1,6 +1,7 @@
{
"Language": "Polski",
"MenuBarFileOpenApplet": "Otwórz Aplet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Otwórz aplet Mii Editor w trybie indywidualnym",
"SettingsTabInputDirectMouseAccess": "Bezpośredni dostęp do myszy",
"SettingsTabSystemMemoryManagerMode": "Tryb menedżera pamięci:",
diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index 352fae46b..7574c1d20 100644
--- a/src/Ryujinx/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
@@ -1,6 +1,7 @@
{
"Language": "Português (BR)",
"MenuBarFileOpenApplet": "Abrir Applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abrir editor Mii em modo avulso",
"SettingsTabInputDirectMouseAccess": "Acesso direto ao mouse",
"SettingsTabSystemMemoryManagerMode": "Modo de gerenciamento de memória:",
diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index 112735e2d..86e51f09f 100644
--- a/src/Ryujinx/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
@@ -1,6 +1,7 @@
{
"Language": "Русский (RU)",
"MenuBarFileOpenApplet": "Открыть апплет",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Открывает апплет Mii Editor в автономном режиме",
"SettingsTabInputDirectMouseAccess": "Прямой ввод мыши",
"SettingsTabSystemMemoryManagerMode": "Режим менеджера памяти:",
diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json
index 35959ddbd..259828583 100644
--- a/src/Ryujinx/Assets/Locales/th_TH.json
+++ b/src/Ryujinx/Assets/Locales/th_TH.json
@@ -1,6 +1,7 @@
{
"Language": "ภาษาไทย",
"MenuBarFileOpenApplet": "เปิด Applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "เปิดโปรแกรม Mii Editor Applet",
"SettingsTabInputDirectMouseAccess": "เข้าถึงเมาส์ได้โดยตรง",
"SettingsTabSystemMemoryManagerMode": "โหมดจัดการหน่วยความจำ:",
diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index 5d50b67db..18dbb12b0 100644
--- a/src/Ryujinx/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
@@ -1,6 +1,7 @@
{
"Language": "Türkçe",
"MenuBarFileOpenApplet": "Applet'i Aç",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Mii Editör Applet'ini Bağımsız Mod'da Aç",
"SettingsTabInputDirectMouseAccess": "Doğrudan Mouse Erişimi",
"SettingsTabSystemMemoryManagerMode": "Hafıza Yönetim Modu:",
diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index a45208486..e123afa6b 100644
--- a/src/Ryujinx/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
@@ -1,6 +1,7 @@
{
"Language": "Українська",
"MenuBarFileOpenApplet": "Відкрити аплет",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Відкрити аплет Mii Editor в автономному режимі",
"SettingsTabInputDirectMouseAccess": "Прямий доступ мишею",
"SettingsTabSystemMemoryManagerMode": "Режим диспетчера пам’яті:",
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index 8a4995ea7..8fcd41cd2 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -1,6 +1,7 @@
{
"Language": "简体中文",
"MenuBarFileOpenApplet": "打开小程序",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "打开独立的 Mii 小程序",
"SettingsTabInputDirectMouseAccess": "直通鼠标操作",
"SettingsTabSystemMemoryManagerMode": "内存管理模式:",
diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index 5649ba00a..d219bc708 100644
--- a/src/Ryujinx/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
@@ -1,6 +1,7 @@
{
"Language": "繁體中文 (台灣)",
"MenuBarFileOpenApplet": "開啟小程式",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "在獨立模式下開啟 Mii 編輯器小程式",
"SettingsTabInputDirectMouseAccess": "滑鼠直接存取",
"SettingsTabSystemMemoryManagerMode": "記憶體管理員模式:",
diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
index 883bf8971..6cf76cf49 100644
--- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
@@ -58,7 +58,7 @@
From 0caeab22707b336d66427d91b35c437f44d9c6d2 Mon Sep 17 00:00:00 2001
From: Luke Warner <65521430+LukeWarnut@users.noreply.github.com>
Date: Mon, 25 Nov 2024 14:46:41 -0500
Subject: [PATCH 31/33] Remove 'Enter' hotkey in settings menu (#95)
This allows the Enter key to be bound to a button when using the
Avalonia UI.
---
src/Ryujinx/UI/Windows/SettingsWindow.axaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.axaml b/src/Ryujinx/UI/Windows/SettingsWindow.axaml
index f9d10fe4f..2bf5b55e7 100644
--- a/src/Ryujinx/UI/Windows/SettingsWindow.axaml
+++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml
@@ -109,7 +109,6 @@
HorizontalAlignment="Right"
ReverseOrder="{Binding IsMacOS}">
From 2a72fb2088c74f249f51d6f79059cf1cd99ed99d Mon Sep 17 00:00:00 2001
From: Evan Husted
Date: Tue, 26 Nov 2024 17:15:11 -0600
Subject: [PATCH 32/33] UI: RPC: Add Diablo III
---
src/Ryujinx.UI.Common/DiscordIntegrationModule.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
index 295a663b2..338d28531 100644
--- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
+++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
@@ -247,6 +247,7 @@ namespace Ryujinx.UI.Common
"0100dbf01000a000", // Burnout Paradise Remastered
"0100744001588000", // Cars 3: Driven to Win
"0100b41013c82000", // Cruis'n Blast
+ "01001b300b9be000", // Diablo III: Eternal Collection
"01008c8012920000", // Dying Light Platinum Edition
"010073c01af34000", // LEGO Horizon Adventures
"0100770008dd8000", // Monster Hunter Generations Ultimate
From baf179efdbe92160cb291b10663460cfa06e976e Mon Sep 17 00:00:00 2001
From: TheToid
Date: Fri, 29 Nov 2024 08:55:51 +1000
Subject: [PATCH 33/33] ignore macos attribute files (#302)
---
.gitignore | 3 +++
src/ARMeilleure/ARMeilleure.csproj | 1 +
.../Ryujinx.Audio.Backends.OpenAL.csproj | 1 +
.../Ryujinx.Audio.Backends.SDL2.csproj | 1 +
.../Ryujinx.Audio.Backends.SoundIo.csproj | 1 +
src/Ryujinx.Audio/Ryujinx.Audio.csproj | 1 +
src/Ryujinx.Common/Ryujinx.Common.csproj | 1 +
src/Ryujinx.Cpu/Ryujinx.Cpu.csproj | 1 +
src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj | 1 +
src/Ryujinx.Graphics.GAL/Ryujinx.Graphics.GAL.csproj | 1 +
src/Ryujinx.Graphics.Gpu/Ryujinx.Graphics.Gpu.csproj | 1 +
src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj | 1 +
.../Ryujinx.Graphics.Nvdec.FFmpeg.csproj | 1 +
.../Ryujinx.Graphics.Nvdec.Vp9.csproj | 1 +
src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj | 1 +
src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj | 1 +
src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj | 1 +
src/Ryujinx.Graphics.Texture/Ryujinx.Graphics.Texture.csproj | 1 +
src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj | 1 +
src/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj | 1 +
src/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj | 1 +
src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj | 1 +
src/Ryujinx.HLE/Ryujinx.HLE.csproj | 1 +
src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj | 1 +
src/Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj | 1 +
.../Ryujinx.Horizon.Generators.csproj | 1 +
.../Ryujinx.Horizon.Kernel.Generators.csproj | 2 ++
src/Ryujinx.Horizon/Ryujinx.Horizon.csproj | 1 +
src/Ryujinx.Input.SDL2/Ryujinx.Input.SDL2.csproj | 1 +
src/Ryujinx.Input/Ryujinx.Input.csproj | 1 +
src/Ryujinx.Memory/Ryujinx.Memory.csproj | 1 +
src/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj | 1 +
src/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj | 1 +
src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj | 1 +
src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj | 1 +
src/Ryujinx.Tests/Ryujinx.Tests.csproj | 1 +
src/Ryujinx.UI.Common/Ryujinx.UI.Common.csproj | 1 +
.../Ryujinx.UI.LocaleGenerator.csproj | 1 +
src/Ryujinx/Ryujinx.csproj | 1 +
src/Spv.Generator/Spv.Generator.csproj | 1 +
40 files changed, 43 insertions(+)
diff --git a/.gitignore b/.gitignore
index f71237b1a..9a192926f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -175,3 +175,6 @@ PublishProfiles/
# Glade backup files
*.glade~
+
+# Ignore MacOS Attribute Files
+._*
diff --git a/src/ARMeilleure/ARMeilleure.csproj b/src/ARMeilleure/ARMeilleure.csproj
index 550e50c26..4b67fdb3b 100644
--- a/src/ARMeilleure/ARMeilleure.csproj
+++ b/src/ARMeilleure/ARMeilleure.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj b/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj
index b5fd8f9e7..bdf46d688 100644
--- a/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj
+++ b/src/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj b/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj
index dd18e70a1..940e47308 100644
--- a/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj
+++ b/src/Ryujinx.Audio.Backends.SDL2/Ryujinx.Audio.Backends.SDL2.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj b/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
index 5c9423463..671a6ad5e 100644
--- a/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
+++ b/src/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
@@ -4,6 +4,7 @@
net8.0truewin-x64;osx-x64;linux-x64
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Audio/Ryujinx.Audio.csproj b/src/Ryujinx.Audio/Ryujinx.Audio.csproj
index fc20f4ec4..8901bbf59 100644
--- a/src/Ryujinx.Audio/Ryujinx.Audio.csproj
+++ b/src/Ryujinx.Audio/Ryujinx.Audio.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Common/Ryujinx.Common.csproj b/src/Ryujinx.Common/Ryujinx.Common.csproj
index dee462fdb..85d4b58bd 100644
--- a/src/Ryujinx.Common/Ryujinx.Common.csproj
+++ b/src/Ryujinx.Common/Ryujinx.Common.csproj
@@ -4,6 +4,7 @@
net8.0true$(DefineConstants);$(ExtraDefineConstants)
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Cpu/Ryujinx.Cpu.csproj b/src/Ryujinx.Cpu/Ryujinx.Cpu.csproj
index 5a6bf5c3d..0a55a7dea 100644
--- a/src/Ryujinx.Cpu/Ryujinx.Cpu.csproj
+++ b/src/Ryujinx.Cpu/Ryujinx.Cpu.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj b/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj
index 973a9e260..58f54de7d 100644
--- a/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj
+++ b/src/Ryujinx.Graphics.Device/Ryujinx.Graphics.Device.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.GAL/Ryujinx.Graphics.GAL.csproj b/src/Ryujinx.Graphics.GAL/Ryujinx.Graphics.GAL.csproj
index d88b641a3..a230296c1 100644
--- a/src/Ryujinx.Graphics.GAL/Ryujinx.Graphics.GAL.csproj
+++ b/src/Ryujinx.Graphics.GAL/Ryujinx.Graphics.GAL.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Gpu/Ryujinx.Graphics.Gpu.csproj b/src/Ryujinx.Graphics.Gpu/Ryujinx.Graphics.Gpu.csproj
index 6f1cce6ac..8c740fadc 100644
--- a/src/Ryujinx.Graphics.Gpu/Ryujinx.Graphics.Gpu.csproj
+++ b/src/Ryujinx.Graphics.Gpu/Ryujinx.Graphics.Gpu.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj b/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj
index d631d039f..92077e26a 100644
--- a/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj
+++ b/src/Ryujinx.Graphics.Host1x/Ryujinx.Graphics.Host1x.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj
index d1a6358c2..7659c4b25 100644
--- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj
+++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Ryujinx.Graphics.Nvdec.FFmpeg.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Ryujinx.Graphics.Nvdec.Vp9.csproj b/src/Ryujinx.Graphics.Nvdec.Vp9/Ryujinx.Graphics.Nvdec.Vp9.csproj
index d1a6358c2..7659c4b25 100644
--- a/src/Ryujinx.Graphics.Nvdec.Vp9/Ryujinx.Graphics.Nvdec.Vp9.csproj
+++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Ryujinx.Graphics.Nvdec.Vp9.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj b/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj
index 6c00e9a7c..7a13b5d1b 100644
--- a/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj
+++ b/src/Ryujinx.Graphics.Nvdec/Ryujinx.Graphics.Nvdec.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj b/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj
index f3071f486..931e70c03 100644
--- a/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj
+++ b/src/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj b/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj
index 8ccf5348f..be32641eb 100644
--- a/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj
+++ b/src/Ryujinx.Graphics.Shader/Ryujinx.Graphics.Shader.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Texture/Ryujinx.Graphics.Texture.csproj b/src/Ryujinx.Graphics.Texture/Ryujinx.Graphics.Texture.csproj
index 51721490e..48d10f1d5 100644
--- a/src/Ryujinx.Graphics.Texture/Ryujinx.Graphics.Texture.csproj
+++ b/src/Ryujinx.Graphics.Texture/Ryujinx.Graphics.Texture.csproj
@@ -2,6 +2,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj b/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj
index a6c4fb2bb..820e807e6 100644
--- a/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj
+++ b/src/Ryujinx.Graphics.Vic/Ryujinx.Graphics.Vic.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj b/src/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj
index abff58a53..d85effe32 100644
--- a/src/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj
+++ b/src/Ryujinx.Graphics.Video/Ryujinx.Graphics.Video.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj b/src/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj
index aae28733f..b138e309a 100644
--- a/src/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj
+++ b/src/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj b/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj
index eeab9c0e9..4791a3b27 100644
--- a/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj
+++ b/src/Ryujinx.HLE.Generators/Ryujinx.HLE.Generators.csproj
@@ -6,6 +6,7 @@
trueGeneratedtrue
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.HLE/Ryujinx.HLE.csproj b/src/Ryujinx.HLE/Ryujinx.HLE.csproj
index 5f7f6db69..83e7b8810 100644
--- a/src/Ryujinx.HLE/Ryujinx.HLE.csproj
+++ b/src/Ryujinx.HLE/Ryujinx.HLE.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj b/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj
index ebda97b46..8fbf9be1e 100644
--- a/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj
+++ b/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj
@@ -9,6 +9,7 @@
$(DefineConstants);$(ExtraDefineConstants)-true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj b/src/Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj
index fa1544c4f..00e0b1af9 100644
--- a/src/Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj
+++ b/src/Ryujinx.Horizon.Common/Ryujinx.Horizon.Common.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj b/src/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj
index d58803993..416eefc27 100644
--- a/src/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj
+++ b/src/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj
@@ -3,6 +3,7 @@
netstandard2.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Horizon.Kernel.Generators/Ryujinx.Horizon.Kernel.Generators.csproj b/src/Ryujinx.Horizon.Kernel.Generators/Ryujinx.Horizon.Kernel.Generators.csproj
index d58803993..02a8ec2c6 100644
--- a/src/Ryujinx.Horizon.Kernel.Generators/Ryujinx.Horizon.Kernel.Generators.csproj
+++ b/src/Ryujinx.Horizon.Kernel.Generators/Ryujinx.Horizon.Kernel.Generators.csproj
@@ -3,6 +3,8 @@
netstandard2.0true
+ $(DefaultItemExcludes);._*
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj b/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj
index bf34ddd17..18c639d67 100644
--- a/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj
+++ b/src/Ryujinx.Horizon/Ryujinx.Horizon.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Input.SDL2/Ryujinx.Input.SDL2.csproj b/src/Ryujinx.Input.SDL2/Ryujinx.Input.SDL2.csproj
index 1ab79d08a..3d880d5fa 100644
--- a/src/Ryujinx.Input.SDL2/Ryujinx.Input.SDL2.csproj
+++ b/src/Ryujinx.Input.SDL2/Ryujinx.Input.SDL2.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Input/Ryujinx.Input.csproj b/src/Ryujinx.Input/Ryujinx.Input.csproj
index 59a9eeb61..0974b707a 100644
--- a/src/Ryujinx.Input/Ryujinx.Input.csproj
+++ b/src/Ryujinx.Input/Ryujinx.Input.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Memory/Ryujinx.Memory.csproj b/src/Ryujinx.Memory/Ryujinx.Memory.csproj
index 8310a3e5c..17745dd61 100644
--- a/src/Ryujinx.Memory/Ryujinx.Memory.csproj
+++ b/src/Ryujinx.Memory/Ryujinx.Memory.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj b/src/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj
index 8e7953045..0811ad850 100644
--- a/src/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj
+++ b/src/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj b/src/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj
index ab89fb5c7..639ceeac2 100644
--- a/src/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj
+++ b/src/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj
@@ -4,6 +4,7 @@
net8.0ExeDebug;Release
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj b/src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj
index f05060838..3bb4bf74d 100644
--- a/src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj
+++ b/src/Ryujinx.Tests.Memory/Ryujinx.Tests.Memory.csproj
@@ -3,6 +3,7 @@
net8.0false
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj b/src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj
index befacfb22..2f7695356 100644
--- a/src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj
+++ b/src/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj
@@ -4,6 +4,7 @@
net8.0trueDebug;Release
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.Tests/Ryujinx.Tests.csproj b/src/Ryujinx.Tests/Ryujinx.Tests.csproj
index 3be9787a3..0480c206e 100644
--- a/src/Ryujinx.Tests/Ryujinx.Tests.csproj
+++ b/src/Ryujinx.Tests/Ryujinx.Tests.csproj
@@ -10,6 +10,7 @@
linuxDebug;Release$(MSBuildProjectDirectory)\.runsettings
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.UI.Common/Ryujinx.UI.Common.csproj b/src/Ryujinx.UI.Common/Ryujinx.UI.Common.csproj
index df6532a63..7f57c7bf5 100644
--- a/src/Ryujinx.UI.Common/Ryujinx.UI.Common.csproj
+++ b/src/Ryujinx.UI.Common/Ryujinx.UI.Common.csproj
@@ -3,6 +3,7 @@
net8.0true
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx.UI.LocaleGenerator/Ryujinx.UI.LocaleGenerator.csproj b/src/Ryujinx.UI.LocaleGenerator/Ryujinx.UI.LocaleGenerator.csproj
index 05cbc7644..e4e627072 100644
--- a/src/Ryujinx.UI.LocaleGenerator/Ryujinx.UI.LocaleGenerator.csproj
+++ b/src/Ryujinx.UI.LocaleGenerator/Ryujinx.UI.LocaleGenerator.csproj
@@ -5,6 +5,7 @@
enablelatesttrue
+ $(DefaultItemExcludes);._*
diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj
index b41ec1cd4..989a3a5bd 100644
--- a/src/Ryujinx/Ryujinx.csproj
+++ b/src/Ryujinx/Ryujinx.csproj
@@ -11,6 +11,7 @@
truetrueapp.manifest
+ $(DefaultItemExcludes);._*
diff --git a/src/Spv.Generator/Spv.Generator.csproj b/src/Spv.Generator/Spv.Generator.csproj
index ae2821edb..5dec0b64e 100644
--- a/src/Spv.Generator/Spv.Generator.csproj
+++ b/src/Spv.Generator/Spv.Generator.csproj
@@ -2,6 +2,7 @@
net8.0
+ $(DefaultItemExcludes);._*