Compare commits

..

22 Commits

Author SHA1 Message Date
Daenorth
6b55d158b7 Norwegian locale update & update Jackbox 5 & 6 compat (#658) 2025-02-13 22:38:55 -06:00
Daniel Nylander
91f73a4891 Updated Swedish translation (#594) 2025-02-13 19:28:39 -06:00
Evan Husted
883d4d863a i18n: chore: [ci skip] missing closing single quote in translation (not JSON breaking) 2025-02-13 19:16:05 -06:00
Dennis
ca5de909a1 Updated German translation (#626) 2025-02-13 19:14:02 -06:00
Willians
5172567b08 Update Brazilian Translation PT-BR (#633)
I updated the Brazilian Portuguese translation, I added the texts that
were not translated.
2025-02-13 19:08:48 -06:00
heihei123456780
6fe4cee7c0 Update zh_CN translation (#650) 2025-02-13 18:16:12 -06:00
Evan Husted
8623452abc docs: new discord invite 2025-02-13 03:23:02 -06:00
Evan Husted
17e8ae1d9a UI: More advanced customization for what happens when Ryujinx loses focus 2025-02-13 01:57:08 -06:00
Evan Husted
7591b07fce infra: Update workflows to ubuntu 24.04 (20.04 will be deprecated soon) 2025-02-12 16:21:03 -06:00
Evan Husted
89b4389ed2 docs: compat: [ci skip] forgot to update time for FUSER 2025-02-12 16:03:26 -06:00
Evan Husted
d9ee729199 docs: compat: FUSER is now Ingame 2025-02-12 15:21:19 -06:00
Evan Husted
ba0cd13cff misc: chore: fix warning [ci skip] 2025-02-11 22:54:24 -06:00
Evan Husted
501b199e24 UI: setting: Disable Input when Out of Focus 2025-02-11 22:12:05 -06:00
Evan Husted
8aecccadb8 misc: chore: Format AvaHostUIHandler 2025-02-11 21:23:04 -06:00
Evan Husted
e23d610f49 UI: Change Update Available button text color to white 2025-02-11 21:18:05 -06:00
Evan Husted
f6822f7358 misc: chore: add direct error code tuple to DisplayErrorAppletDialog
for use when i find the list of error codes -> causes
2025-02-11 21:09:55 -06:00
Evan Husted
d3f84a1305 misc: chore: Rename UserSelectorDialog to ProfileSelectorDialog 2025-02-11 20:50:06 -06:00
Evan Husted
06d34a5992 misc: chore: optimize UserSelectorDialog closed handler 2025-02-11 20:36:11 -06:00
Evan Husted
e8e1dc6619 misc: chore: this isn't even bound to a XAML element, why was this an async void 2025-02-11 20:30:46 -06:00
Evan Husted
c5603d4c36 UI: Make about window text bigger and add a separator in the right side 2025-02-11 20:22:29 -06:00
Evan Husted
05b56730d6 docs: compat: remove title ID column from compat entries for homebrew 2025-02-11 20:22:09 -06:00
Evan Husted
43f7b000ca misc: chore: Optimize AboutWindowViewModel resource disposal 2025-02-11 20:08:38 -06:00
31 changed files with 627 additions and 246 deletions

View File

@@ -29,7 +29,7 @@ env:
jobs:
tag:
name: Create tag
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
@@ -202,7 +202,7 @@ jobs:
macos_release:
name: Release MacOS universal
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

View File

@@ -18,7 +18,7 @@ env:
jobs:
tag:
name: Create tag
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
@@ -183,7 +183,7 @@ jobs:
macos_release:
name: Release MacOS universal
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

View File

@@ -39,12 +39,12 @@
<p align="center">
Click below to join the Discord:
<br>
<a href="https://discord.gg/dHPrkBkkyA">
<a href="https://discord.gg/PEuzjrFXUA">
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
</a>
<br>
<br>
<img src="https://raw.githubusercontent.com/GreemDev/Ryujinx/refs/heads/master/docs/shell.png">
<img src="https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/docs/shell.png">
</p>
## Usage

View File

@@ -1249,7 +1249,7 @@
0100A6B00D4EC000,"Furwind",,playable,2021-02-19 19:44:08
0100ECE00C0C4000,"Fury Unleashed",crash;services,ingame,2020-10-18 11:52:40
010070000ED9E000,"Fury Unleashed Demo",,playable,2020-10-08 20:09:21
0100E1F013674000,"FUSER™",nvdec;UE4,playable,2022-10-17 20:58:32
0100E1F013674000,"FUSER™",nvdec;UE4;slow;gpu,ingame,2025-02-12 16:03:00
0100A7A015E4C000,"Fushigi no Gensokyo Lotus Labyrinth",Needs Update;audio;gpu;nvdec,ingame,2021-01-20 15:30:02
01003C300B274000,"Futari de! Nyanko Daisensou",,playable,2024-01-05 22:26:52
010055801134E000,"FUZE Player",online-broken;vulkan-backend-bug,ingame,2022-10-18 12:23:53
@@ -2063,7 +2063,7 @@
010002700C34C000,"Numbala",,playable,2020-05-11 12:01:07
010020500C8C8000,"Number Place 10000",gpu,menus,2021-11-24 09:14:23
010003701002C000,"Nurse Love Syndrome",,playable,2022-10-13 10:05:22
0000000000000000,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
,"nxquake2",services;crash;homebrew,nothing,2022-08-04 23:14:04
010049F00EC30000,"Nyan Cat: Lost in Space",online,playable,2021-06-12 13:22:03
01002E6014FC4000,"O---O",,playable,2022-10-29 12:12:14
@@ -2471,7 +2471,7 @@
0100AFE00DDAC000,"Royal Roads",,playable,2020-11-17 12:54:38
0100E2C00B414000,"RPG Maker MV",nvdec,playable,2021-01-05 20:12:01
01005CD015986000,"rRootage Reloaded",,playable,2022-08-05 23:20:18
0000000000000000,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
010009B00D33C000,"Rugby Challenge 4",slow;online-broken;UE4,playable,2022-10-06 12:45:53
01006EC00F2CC000,"RUINER",UE4,playable,2022-10-03 14:11:33
010074F00DE4A000,"Run the Fan",,playable,2021-02-27 13:36:28
@@ -2674,10 +2674,10 @@
01004F401BEBE000,"Song of Nunu: A League of Legends Story",,ingame,2024-07-12 18:53:44
0100E5400BF94000,"Songbird Symphony",,playable,2021-02-27 02:44:04
010031D00A604000,"Songbringer",,playable,2020-06-22 10:42:02
0000000000000000,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
0000000000000000,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
0000000000000000,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
0000000000000000,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
010040E0116B8000,"Sonic Colors: Ultimate",,playable,2022-11-12 21:24:26
01001270012B6000,"SONIC FORCES™",,playable,2024-07-28 13:11:21
01004AD014BF0000,"Sonic Frontiers",gpu;deadlock;amd-vendor-bug;intel-vendor-bug,ingame,2024-09-05 09:18:53
@@ -2694,7 +2694,7 @@
0100707011722000,"Space Elite Force",,playable,2020-11-27 15:21:05
010047B010260000,"Space Pioneer",,playable,2022-10-20 12:24:37
010010A009830000,"Space Ribbon",,playable,2022-08-15 17:17:10
0000000000000000,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
0100D9B0041CE000,"Spacecats with Lasers",,playable,2022-08-15 17:22:44
010034800FB60000,"Spaceland",,playable,2020-11-01 14:31:56
010028D0045CE000,"Sparkle 2",,playable,2020-10-19 11:51:39
@@ -2839,7 +2839,7 @@
0100000000010000,"Super Mario Odyssey™",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34
010036B0034E4000,"Super Mario Party™",gpu;Needs Update;ldn-works,ingame,2024-06-21 05:10:16
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
0000000000000000,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
010028600EBDA000,"Super Mario™ 3D World + Bowsers Fury",ldn-works,playable,2024-07-31 10:45:37
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
@@ -2988,8 +2988,8 @@
010015D003EE4000,"The Jackbox Party Pack 2",online-working,playable,2022-08-22 18:23:40
0100CC80013D6000,"The Jackbox Party Pack 3",slow;online-working,playable,2022-08-22 18:41:06
0100E1F003EE8000,"The Jackbox Party Pack 4",online-working,playable,2022-08-22 18:56:34
01006fe0096ac000,"The Jackbox Party Pack 5",ldn-untested,boots,2025-02-03 22:32:00
01005a400db52000,"The Jackbox Party Pack 6",ldn-untested,boots,2025-02-03 22:32:00
01006fe0096ac000,"The Jackbox Party Pack 5",slow;online-working,ingame,2025-02-14 05:32:00
01005a400db52000,"The Jackbox Party Pack 6",slow;online-working,ingame,2025-02-14 05:26:00
010052C00B184000,"The Journey Down: Chapter One",nvdec,playable,2021-02-24 13:32:41
01006BC00B188000,"The Journey Down: Chapter Three",nvdec,playable,2021-02-24 13:45:27
01009AB00B186000,"The Journey Down: Chapter Two",nvdec,playable,2021-02-24 13:32:13
1 title_id game_name labels status last_updated
1249 0100A6B00D4EC000 Furwind playable 2021-02-19 19:44:08
1250 0100ECE00C0C4000 Fury Unleashed crash;services ingame 2020-10-18 11:52:40
1251 010070000ED9E000 Fury Unleashed Demo playable 2020-10-08 20:09:21
1252 0100E1F013674000 FUSER™ nvdec;UE4 nvdec;UE4;slow;gpu playable ingame 2022-10-17 20:58:32 2025-02-12 16:03:00
1253 0100A7A015E4C000 Fushigi no Gensokyo Lotus Labyrinth Needs Update;audio;gpu;nvdec ingame 2021-01-20 15:30:02
1254 01003C300B274000 Futari de! Nyanko Daisensou playable 2024-01-05 22:26:52
1255 010055801134E000 FUZE Player online-broken;vulkan-backend-bug ingame 2022-10-18 12:23:53
2063 010002700C34C000 Numbala playable 2020-05-11 12:01:07
2064 010020500C8C8000 Number Place 10000 gpu menus 2021-11-24 09:14:23
2065 010003701002C000 Nurse Love Syndrome playable 2022-10-13 10:05:22
2066 0000000000000000 nx-hbmenu Needs Update;homebrew boots 2024-04-06 22:05:32
2067 nxquake2 services;crash;homebrew nothing 2022-08-04 23:14:04
2068 010049F00EC30000 Nyan Cat: Lost in Space online playable 2021-06-12 13:22:03
2069 01002E6014FC4000 O---O playable 2022-10-29 12:12:14
2471 0100AFE00DDAC000 Royal Roads playable 2020-11-17 12:54:38
2472 0100E2C00B414000 RPG Maker MV nvdec playable 2021-01-05 20:12:01
2473 01005CD015986000 rRootage Reloaded playable 2022-08-05 23:20:18
2474 0000000000000000 RSDKv5u homebrew ingame 2024-04-01 16:25:34
2475 010009B00D33C000 Rugby Challenge 4 slow;online-broken;UE4 playable 2022-10-06 12:45:53
2476 01006EC00F2CC000 RUINER UE4 playable 2022-10-03 14:11:33
2477 010074F00DE4A000 Run the Fan playable 2021-02-27 13:36:28
2674 01004F401BEBE000 Song of Nunu: A League of Legends Story ingame 2024-07-12 18:53:44
2675 0100E5400BF94000 Songbird Symphony playable 2021-02-27 02:44:04
2676 010031D00A604000 Songbringer playable 2020-06-22 10:42:02
2677 0000000000000000 Sonic 1 (2013) crash;homebrew ingame 2024-04-06 18:31:20
2678 0000000000000000 Sonic 2 (2013) crash;homebrew ingame 2024-04-01 16:25:30
2679 0000000000000000 Sonic A.I.R homebrew ingame 2024-04-01 16:25:32
2680 0000000000000000 Sonic CD crash;homebrew ingame 2024-04-01 16:25:31
2681 010040E0116B8000 Sonic Colors: Ultimate playable 2022-11-12 21:24:26
2682 01001270012B6000 SONIC FORCES™ playable 2024-07-28 13:11:21
2683 01004AD014BF0000 Sonic Frontiers gpu;deadlock;amd-vendor-bug;intel-vendor-bug ingame 2024-09-05 09:18:53
2694 0100707011722000 Space Elite Force playable 2020-11-27 15:21:05
2695 010047B010260000 Space Pioneer playable 2022-10-20 12:24:37
2696 010010A009830000 Space Ribbon playable 2022-08-15 17:17:10
2697 0000000000000000 SpaceCadetPinball homebrew ingame 2024-04-18 19:30:04
2698 0100D9B0041CE000 Spacecats with Lasers playable 2022-08-15 17:22:44
2699 010034800FB60000 Spaceland playable 2020-11-01 14:31:56
2700 010028D0045CE000 Sparkle 2 playable 2020-10-19 11:51:39
2839 0100000000010000 Super Mario Odyssey™ nvdec;intel-vendor-bug;mac-bug playable 2024-08-25 01:32:34
2840 010036B0034E4000 Super Mario Party™ gpu;Needs Update;ldn-works ingame 2024-06-21 05:10:16
2841 0100BC0018138000 Super Mario RPG™ gpu;audio;nvdec ingame 2024-06-19 17:43:42
2842 0000000000000000 Super Mario World homebrew boots 2024-06-13 01:40:31
2843 010049900F546000 Super Mario™ 3D All-Stars services-horizon;slow;vulkan;amd-vendor-bug ingame 2024-05-07 02:38:16
2844 010028600EBDA000 Super Mario™ 3D World + Bowser’s Fury ldn-works playable 2024-07-31 10:45:37
2845 01004F8006A78000 Super Meat Boy services playable 2020-04-02 23:10:07
2988 010015D003EE4000 The Jackbox Party Pack 2 online-working playable 2022-08-22 18:23:40
2989 0100CC80013D6000 The Jackbox Party Pack 3 slow;online-working playable 2022-08-22 18:41:06
2990 0100E1F003EE8000 The Jackbox Party Pack 4 online-working playable 2022-08-22 18:56:34
2991 01006fe0096ac000 The Jackbox Party Pack 5 ldn-untested slow;online-working boots ingame 2025-02-03 22:32:00 2025-02-14 05:32:00
2992 01005a400db52000 The Jackbox Party Pack 6 ldn-untested slow;online-working boots ingame 2025-02-03 22:32:00 2025-02-14 05:26:00
2993 010052C00B184000 The Journey Down: Chapter One nvdec playable 2021-02-24 13:32:41
2994 01006BC00B188000 The Journey Down: Chapter Three nvdec playable 2021-02-24 13:45:27
2995 01009AB00B186000 The Journey Down: Chapter Two nvdec playable 2021-02-24 13:32:13

View File

@@ -158,13 +158,15 @@ namespace Ryujinx.HLE.HOS.Applets.Error
string[] buttons = GetButtonsText(module, description, "DlgBtn");
bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons);
(uint Module, uint Description) errorCodeTuple = (module, uint.Parse(description.ToString("0000")));
bool showDetails = _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Code: {module}-{description:0000}", "\n" + message, buttons, errorCodeTuple);
if (showDetails)
{
message = GetMessageText(module, description, "FlvMsg");
buttons = GetButtonsText(module, description, "FlvBtn");
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons);
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Details: {module}-{description:0000}", "\n" + message, buttons, errorCodeTuple);
}
}

View File

@@ -45,10 +45,12 @@ namespace Ryujinx.HLE.UI
/// <param name="value">The value associated to the <paramref name="kind"/>.</param>
void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value);
/// <summary>
/// Displays a Message Dialog box specific to Error Applet and blocks until it is closed.
/// </summary>
/// <returns>False when OK is pressed, True when another button (Details) is pressed.</returns>
bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText);
// ReSharper disable once UnusedParameter.Global
bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText, (uint Module, uint Description)? errorCode = null);
/// <summary>
/// Creates a handler to process keyboard inputs into text strings.

View File

@@ -185,6 +185,15 @@ namespace Ryujinx.Input.HLE
}
}
public bool InputUpdatesBlocked
{
get
{
lock (_lock)
return _blockInputUpdates;
}
}
public void BlockInputUpdates()
{
lock (_lock)

View File

@@ -517,7 +517,7 @@ namespace Ryujinx.Ava
Device?.System.ChangeDockedModeState(e.NewValue);
}
private void UpdateAudioVolumeState(object sender, ReactiveEventArgs<float> e)
public void UpdateAudioVolumeState(object sender, ReactiveEventArgs<float> e)
{
Device?.SetVolume(e.NewValue);

View File

@@ -76,7 +76,7 @@
"ID": "MenuBarFileOpenAppletOpenMiiApplet",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Mii-Bearbeitungsapplet",
"el_GR": "",
"en_US": "Mii Edit Applet",
"es_ES": "Applet Editor Mii",
@@ -176,7 +176,7 @@
"ID": "SettingsTabSystemMemoryManagerModeSoftware",
"Translations": {
"ar_SA": "البرنامج",
"de_DE": "",
"de_DE": "Programme",
"el_GR": "Λογισμικό",
"en_US": "Software",
"es_ES": "",
@@ -326,7 +326,7 @@
"ID": "MenuBarFileOpenFromFileError",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Keine Anwendungen im ausgewählten Datei gefunden.",
"el_GR": "",
"en_US": "No applications found in selected file.",
"es_ES": "No se encontraron aplicaciones en el archivo seleccionado.",
@@ -376,7 +376,7 @@
"ID": "MenuBarFileLoadDlcFromFolder",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "DLC aus Ordner laden",
"el_GR": "",
"en_US": "Load DLC From Folder",
"es_ES": "Cargar DLC Desde Carpeta",
@@ -401,7 +401,7 @@
"ID": "MenuBarFileLoadTitleUpdatesFromFolder",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Titel-Updates aus Ordner laden",
"el_GR": "",
"en_US": "Load Title Updates From Folder",
"es_ES": "Cargar Actualizaciones de Títulos Desde Carpeta",
@@ -576,7 +576,7 @@
"ID": "MenuBarOptionsStartGamesWithoutUI",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Spiele ohne Benutzeroberfläche starten",
"el_GR": "",
"en_US": "Start Games with UI Hidden",
"es_ES": "",
@@ -585,11 +585,11 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "UI를 숨긴 상태에서 게임 시작",
"no_NO": "",
"no_NO": "Start Spillet med UI Gjemt",
"pl_PL": "",
"pt_BR": "Iniciar jogos ocultando a interface",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Starta spel med dolt användargränssnitt",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -751,7 +751,7 @@
"ID": "MenuBarActionsScanAmiiboBin",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Amiibo scannen (aus Bin-Datei)",
"el_GR": "",
"en_US": "Scan An Amiibo (From Bin)",
"es_ES": "",
@@ -851,7 +851,7 @@
"ID": "MenuBarActionsInstallKeys",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Schlüssel installieren",
"el_GR": "",
"en_US": "Install Keys",
"es_ES": "",
@@ -876,7 +876,7 @@
"ID": "MenuBarFileActionsInstallKeysFromFile",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Schlüssel aus KEYS oder ZIP installieren",
"el_GR": "",
"en_US": "Install keys from KEYS or ZIP",
"es_ES": "Instalar keys de KEYS o ZIP",
@@ -901,7 +901,7 @@
"ID": "MenuBarFileActionsInstallKeysFromFolder",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Schlüssel aus einem Verzeichnis installieren",
"el_GR": "",
"en_US": "Install keys from a directory",
"es_ES": "Instalar keys de un directorio",
@@ -1001,7 +1001,7 @@
"ID": "MenuBarActionsXCITrimmer",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "XCI-Dateien trimmen",
"el_GR": "",
"en_US": "Trim XCI Files",
"es_ES": "Recortar archivos XCI",
@@ -1226,7 +1226,7 @@
"ID": "MenuBarHelpFaqAndGuides",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "FAQ & Anleitungen",
"el_GR": "",
"en_US": "FAQ & Guides",
"es_ES": "",
@@ -1251,7 +1251,7 @@
"ID": "MenuBarHelpFaq",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "FAQ & Fehlerbehebung Seite",
"el_GR": "",
"en_US": "FAQ & Troubleshooting Page",
"es_ES": "",
@@ -1276,7 +1276,7 @@
"ID": "MenuBarHelpFaqTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Öffnet die FAQ- und Fehlerbehebungsseite im offiziellen Ryujinx-Wiki",
"el_GR": "",
"en_US": "Opens the FAQ and Troubleshooting page on the official Ryujinx wiki",
"es_ES": "",
@@ -1301,7 +1301,7 @@
"ID": "MenuBarHelpSetup",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Setup- und Konfigurationsanleitung",
"el_GR": "",
"en_US": "Setup & Configuration Guide",
"es_ES": "",
@@ -1326,7 +1326,7 @@
"ID": "MenuBarHelpSetupTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Öffnet die Setup- und Konfigurationsanleitung im offiziellen Ryujinx-Wiki",
"el_GR": "",
"en_US": "Opens the Setup & Configuration guide on the official Ryujinx wiki",
"es_ES": "",
@@ -1351,7 +1351,7 @@
"ID": "MenuBarHelpMultiplayer",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Multiplayer (LDN/LAN) Anleitung",
"el_GR": "",
"en_US": "Multiplayer (LDN/LAN) Guide",
"es_ES": "",
@@ -1376,7 +1376,7 @@
"ID": "MenuBarHelpMultiplayerTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Öffnet die Multiplayer-Anleitung im offiziellen Ryujinx-Wiki",
"el_GR": "",
"en_US": "Opens the Multiplayer guide on the official Ryujinx wiki",
"es_ES": "",
@@ -1526,7 +1526,7 @@
"ID": "GameListHeaderDeveloper",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Entwickelt von {0}",
"el_GR": "",
"en_US": "Developed by {0}",
"es_ES": "",
@@ -1535,7 +1535,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Utviklet av {0}",
"pl_PL": "",
"pt_BR": "Desenvolvido por {0}",
"ru_RU": "",
@@ -1826,7 +1826,7 @@
"ID": "GameListHeaderCompatibilityStatus",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Kompatibilität:",
"el_GR": "",
"en_US": "Compatibility:",
"es_ES": "",
@@ -1835,7 +1835,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Kompatibilitet",
"pl_PL": "",
"pt_BR": "Compatibilidade:",
"ru_RU": "",
@@ -1860,7 +1860,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Tittel ID:",
"pl_PL": "",
"pt_BR": "ID do título:",
"ru_RU": "",
@@ -1885,7 +1885,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Spill som Arrangeres: {0}",
"pl_PL": "",
"pt_BR": "Jogos hospedados: {0}",
"ru_RU": "",
@@ -1910,7 +1910,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Online-spillere: {0}",
"pl_PL": "",
"pt_BR": "Jogadores Online: {0}",
"ru_RU": "",
@@ -2260,7 +2260,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "PPTC 캐시 제거",
"no_NO": "",
"no_NO": "Tøm PPTC-bufferen",
"pl_PL": "",
"pt_BR": "Limpar cache PPTC",
"ru_RU": "",
@@ -2285,7 +2285,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "앱의 모든 PPTC 캐시 파일 삭제",
"no_NO": "",
"no_NO": "Sletter alle PPTC-cache-filer for applikasjonen",
"pl_PL": "",
"pt_BR": "Apagar os arquivos de cache PPTC do aplicativo",
"ru_RU": "",
@@ -2614,7 +2614,7 @@
"pl_PL": "",
"pt_BR": "Extraia o RomFS de um arquivo DLC selecionado",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Extrahera RomFS från en vald DLC-fil",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -2760,7 +2760,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "호환성 항목 표시",
"no_NO": "",
"no_NO": "Vis kompatibilitetsoppføring",
"pl_PL": "",
"pt_BR": "Mostrar entrada de compatibilidade",
"ru_RU": "",
@@ -2785,7 +2785,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "일반적으로 도움말 메뉴를 통해 접근할 수 있는 호환성 목록에 선택한 게임을 표시합니다.",
"no_NO": "",
"no_NO": "Vis det valgte spillet i kompatibilitetslisten, som du vanligvis får tilgang til via Hjelp-menyen.",
"pl_PL": "",
"pt_BR": "Exibe o jogo selecionado na Lista de Compatibilidade, que normalmente pode ser acessada pelo menu Ajuda.",
"ru_RU": "",
@@ -2810,7 +2810,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "게임 통계 표시",
"no_NO": "",
"no_NO": "Vis Spill Info",
"pl_PL": "",
"pt_BR": "Mostrar informações do jogo",
"ru_RU": "",
@@ -2835,7 +2835,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "그리드 보기 레이아웃에서 누락된 현재 선택된 게임에 대한 다양한 정보를 표시합니다.",
"no_NO": "",
"no_NO": "Vis statistikk og detaljer om det valgte spillet.",
"pl_PL": "",
"pt_BR": "Mostrar estatísticas e detalhes sobre o jogo selecionado no momento.",
"ru_RU": "",
@@ -3062,7 +3062,7 @@
"ko_KR": "XCI 파일 '{0}' 트리밍",
"no_NO": "Trimming av XCI-filen '{0}'",
"pl_PL": "",
"pt_BR": "Reduzindo arquivo XCI '{0}",
"pt_BR": "Reduzindo arquivo XCI '{0}'",
"ru_RU": "Обрезается XCI файл '{0}'",
"sv_SE": "Optimerar XCI-filen '{0}'",
"th_TH": "",
@@ -3360,15 +3360,15 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Se etter Oppdateringer:",
"pl_PL": "",
"pt_BR": "",
"pt_BR": "Verificar atualizações:",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "检查更新",
"zh_TW": ""
}
},
@@ -3385,15 +3385,15 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Av",
"pl_PL": "",
"pt_BR": "",
"pt_BR": "Desligado",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "关闭",
"zh_TW": ""
}
},
@@ -3410,7 +3410,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Spør",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
@@ -3418,7 +3418,7 @@
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "提示",
"zh_TW": ""
}
},
@@ -3435,15 +3435,165 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Bakgrunn",
"pl_PL": "",
"pt_BR": "",
"pt_BR": "Fundo",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "背景",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralFocusLossType",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "On Emulator Focus Lost:",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "På Emulator Fokus Tapt:",
"pl_PL": "",
"pt_BR": "Ao perder o Foco do emulador:",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "当模拟器在后台时:",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeDoNothing",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Do Nothing",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Gjør Ingenting",
"pl_PL": "",
"pt_BR": "Não fazer nada",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "什么事情也不做",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeBlockInput",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Block Input",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Blokkinngang",
"pl_PL": "",
"pt_BR": "Bloquear entrada",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "禁用输入",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeMuteAudio",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Mute Volume",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Demp Lyd",
"pl_PL": "",
"pt_BR": "Ficar mudo",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "静音",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Block Input & Mute Volume",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Blokker Inputs og demp Volumet",
"pl_PL": "",
"pt_BR": "Bloquear entrada & Ficar mudo",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "阻止输入且静音",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralFocusLossTypePauseEmulation",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Pause Emulation",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Pause Emulatoren",
"pl_PL": "",
"pt_BR": "Pausar a emulação",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "暂停模拟",
"zh_TW": ""
}
},
@@ -3497,6 +3647,31 @@
"zh_TW": "記住視窗大小/位置"
}
},
{
"ID": "SettingsTabGeneralDisableInputWhenOutOfFocus",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Disable Input when Out of Focus",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Deaktiver inndata når vinduet er ute av fokus",
"pl_PL": "",
"pt_BR": "Desativar entrada quando estiver fora de foco",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "在后台时禁用输入",
"zh_TW": ""
}
},
{
"ID": "SettingsTabGeneralShowTitleBar",
"Translations": {
@@ -4446,7 +4621,7 @@
"zh_CN": "繁体中文(推荐)",
"zh_TW": "正體中文 (建議)"
}
},
},
{
"ID": "SettingsTabSystemSystemLanguageSwedish",
"Translations": {
@@ -4460,7 +4635,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "스웨덴어",
"no_NO": "",
"no_NO": "Svensk",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
@@ -4468,10 +4643,10 @@
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "瑞典语",
"zh_TW": ""
}
},
},
{
"ID": "SettingsTabSystemSystemLanguageNorwegian",
"Translations": {
@@ -4493,7 +4668,7 @@
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "挪威语",
"zh_TW": ""
}
},
@@ -4560,7 +4735,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "매치 시스템 시간",
"no_NO": "",
"no_NO": "Match systemtid",
"pl_PL": "",
"pt_BR": "Sincronizar data e hora com o sistema PC",
"ru_RU": "",
@@ -5835,15 +6010,15 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Aktivere UI-logger",
"pl_PL": "",
"pt_BR": "",
"pt_BR": "Habilitar logs da IU",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "启用 UI 日志",
"zh_TW": ""
}
},
@@ -6235,7 +6410,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Tilbakestill innstillinger",
"pl_PL": "",
"pt_BR": "Redefinir configurações",
"ru_RU": "",
@@ -6260,7 +6435,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Jeg vil tilbakestille innstillingene mine.",
"pl_PL": "",
"pt_BR": "Quero redefinir minhas configurações.",
"ru_RU": "",
@@ -6289,7 +6464,7 @@
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Ok",
"th_TH": "ตกลง",
"tr_TR": "Tamam",
"uk_UA": "",
@@ -8185,11 +8360,11 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "비활성화",
"no_NO": "",
"no_NO": "Deaktiver",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Inaktivera",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -8210,11 +8385,11 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "레인보우",
"no_NO": "",
"no_NO": "Regnbue",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Regnbåge",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -8235,7 +8410,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "레인보우 속도",
"no_NO": "",
"no_NO": "Regnbue Hastighet",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
@@ -8260,11 +8435,11 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "색상",
"no_NO": "",
"no_NO": "Farge",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Färg",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -13510,7 +13685,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "다음에서 모든 PPTC 데이터를 제거하려고 합니다:\n\n{0}\n\n계속하시겠습니까?",
"no_NO": "",
"no_NO": "Du er i ferd med å slette alle PPTC-data fra:\n\n{0}\n\n\nEr du sikker på at du vil fortsette?",
"pl_PL": "",
"pt_BR": "Você está prestes a limpar todos os dados PPTC de:\n\n{0}\n\nTem certeza de que deseja continuar?",
"ru_RU": "",
@@ -15064,7 +15239,7 @@
"pl_PL": "Seria Amiibo",
"pt_BR": "Franquia Amiibo",
"ru_RU": "Серия Amiibo",
"sv_SE": "",
"sv_SE": "Amiibo-serie",
"th_TH": "",
"tr_TR": "Amiibo Serisi",
"uk_UA": "Серія Amiibo",
@@ -16835,15 +17010,15 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Skriver ut Avalonia (UI)-loggmeldinger i konsollen.",
"pl_PL": "",
"pt_BR": "",
"pt_BR": "Imprimir mensagens de log do Avalonia (IU) no console.",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "在控制台显示 Avalonia (UI) 的日志信息",
"zh_TW": ""
}
},
@@ -17760,15 +17935,15 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Oppdatering tilgjengelig!",
"pl_PL": "",
"pt_BR": "",
"pt_BR": "Atualização disponível!",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_CN": "有可用的更新!",
"zh_TW": ""
}
},
@@ -18412,7 +18587,7 @@
"ko_KR": "(실패)",
"no_NO": "(Mislyktes)",
"pl_PL": "",
"pt_BR": "Falhado",
"pt_BR": "Falhou",
"ru_RU": "(Ошибка)",
"sv_SE": "(misslyckades)",
"th_TH": "",
@@ -18489,7 +18664,7 @@
"pl_PL": "",
"pt_BR": "{0} - Informação",
"ru_RU": "{0} - Информация",
"sv_SE": "",
"sv_SE": "{0} - Information",
"th_TH": "{0} ข้อมูล",
"tr_TR": "{0} - Bilgi",
"uk_UA": "{0} - Інформація",
@@ -19560,11 +19735,11 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "LED 설정",
"no_NO": "",
"no_NO": "LED-innstillinger",
"pl_PL": "",
"pt_BR": "Configurações de LED",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "LED-inställningar",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -20412,7 +20587,7 @@
"ko_KR": "실패",
"no_NO": "Mislyktes",
"pl_PL": "",
"pt_BR": "Falhado",
"pt_BR": "Falhou",
"ru_RU": "Ошибка",
"sv_SE": "Misslyckades",
"th_TH": "",
@@ -20512,7 +20687,7 @@
"ko_KR": "표시됨 선택",
"no_NO": "Velg vist",
"pl_PL": "",
"pt_BR": "Seleccionar mostrado(s)",
"pt_BR": "Selecionar mostrado(s)",
"ru_RU": "Выбрать то что показано",
"sv_SE": "Markera visade",
"th_TH": "",
@@ -20537,7 +20712,7 @@
"ko_KR": "표시됨 선택 취소",
"no_NO": "Opphev valg av Vist",
"pl_PL": "",
"pt_BR": "Deseleccionar mostrado(s)",
"pt_BR": "Desmarcar mostrado(s)",
"ru_RU": "Отменить выбор показанного",
"sv_SE": "Avmarkera visade",
"th_TH": "",
@@ -21764,7 +21939,7 @@
"pl_PL": "Głoś",
"pt_BR": "",
"ru_RU": "Громкость",
"sv_SE": "",
"sv_SE": "Volym",
"th_TH": "ระดับเสียง",
"tr_TR": "Ses",
"uk_UA": "Гуч.",
@@ -23176,7 +23351,7 @@
"ID": "SettingsTabSystemVSyncModeTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Emulierte vertikale Synchronisation. \"Switch\" emuliert die 60Hz-Bildwiederholfrequenz der Switch. \"Unbounded\" ist eine unbegrenzte Bildwiederholfrequenz.",
"el_GR": "",
"en_US": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate.",
"es_ES": "",
@@ -23201,7 +23376,7 @@
"ID": "SettingsTabSystemVSyncModeTooltipCustom",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Emulierte vertikale Synchronisation. \"Switch\" emuliert die 60Hz-Bildwiederholfrequenz der Switch. „Unbounded“ ist eine unbegrenzte Bildwiederholfrequenz. „Benutzerdefinierte Bildwiederholfrequenz“ emuliert die angegebene benutzerdefinierte Bildwiederholfrequenz.",
"el_GR": "",
"en_US": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate. 'Custom Refresh Rate' emulates the specified custom refresh rate.",
"es_ES": "",
@@ -23226,7 +23401,7 @@
"ID": "SettingsTabSystemEnableCustomVSyncIntervalTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Ermöglicht es dem Benutzer, eine emulierte Bildwiederholfrequenz festzulegen. In einigen Titeln kann dies die Geschwindigkeit der Spiel-Logik erhöhen oder verringern. In anderen Titeln kann dies dazu führen, dass die FPS auf ein Vielfaches der Bildwiederholfrequenz begrenzt werden oder zu unvorhersehbarem Verhalten führen. Dies ist eine experimentelle Funktion, ohne Garantien dafür, wie sich das Gameplay auswirkt. \n\nLassen Sie diese Option deaktiviert, wenn Sie sich nicht sicher sind.",
"el_GR": "",
"en_US": "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.",
"es_ES": "",
@@ -23251,7 +23426,7 @@
"ID": "SettingsTabSystemCustomVSyncIntervalValueTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Der Zielwert für die benutzerdefinierte Bildwiederholfrequenz.",
"el_GR": "",
"en_US": "The custom refresh rate target value.",
"es_ES": "",
@@ -23276,7 +23451,7 @@
"ID": "SettingsTabSystemCustomVSyncIntervalSliderTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Die benutzerdefinierte Bildwiederholfrequenz als Prozentsatz der normalen Switch-Bildwiederholfrequenz.",
"el_GR": "",
"en_US": "The custom refresh rate, as a percentage of the normal Switch refresh rate.",
"es_ES": "",
@@ -23301,7 +23476,7 @@
"ID": "SettingsTabSystemCustomVSyncIntervalPercentage",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Benutzerdefinierte Bildwiederholfrequenz %:",
"el_GR": "",
"en_US": "Custom Refresh Rate %:",
"es_ES": "",
@@ -23326,7 +23501,7 @@
"ID": "SettingsTabSystemCustomVSyncIntervalValue",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Wert für benutzerdefinierte Bildwiederholfrequenz:",
"el_GR": "",
"en_US": "Custom Refresh Rate Value:",
"es_ES": "",
@@ -23376,7 +23551,7 @@
"ID": "SettingsTabHotkeysToggleVSyncModeHotkey",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "VSync-Modus umschalten:",
"el_GR": "",
"en_US": "Toggle VSync mode:",
"es_ES": "",
@@ -23401,7 +23576,7 @@
"ID": "SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Benutzerdefinierte Bildwiederholfrequenz erhöhen:",
"el_GR": "",
"en_US": "Raise custom refresh rate",
"es_ES": "",
@@ -23426,7 +23601,7 @@
"ID": "SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Benutzerdefinierte Bildwiederholfrequenz senken:",
"el_GR": "",
"en_US": "Lower custom refresh rate:",
"es_ES": "",
@@ -23451,7 +23626,7 @@
"ID": "CompatibilityListLastUpdated",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Zuletzt aktualisiert: {0}",
"el_GR": "",
"en_US": "Last updated: {0}",
"es_ES": "",
@@ -23476,7 +23651,7 @@
"ID": "CompatibilityListWarning",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Diese Kompatibilitätsliste könnte veraltete Einträge enthalten. Teste dennoch Spiele im \"Ingame\"-Status.",
"el_GR": "",
"en_US": "This compatibility list might contain out of date entries.\nDo not be opposed to testing games in the \"Ingame\" status.",
"es_ES": "",
@@ -23501,7 +23676,7 @@
"ID": "CompatibilityListSearchBoxWatermark",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Kompatibilitätseinträge durchsuchen...",
"el_GR": "",
"en_US": "Search compatibility entries...",
"es_ES": "",
@@ -23551,7 +23726,7 @@
"ID": "CompatibilityListOnlyShowOwnedGames",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Nur eigene Spiele anzeigen",
"el_GR": "",
"en_US": "Only show owned games",
"es_ES": "",
@@ -23576,7 +23751,7 @@
"ID": "CompatibilityListPlayable",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Spielbar",
"el_GR": "",
"en_US": "Playable",
"es_ES": "",
@@ -23601,7 +23776,7 @@
"ID": "CompatibilityListIngame",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Im Spiel",
"el_GR": "",
"en_US": "Ingame",
"es_ES": "",
@@ -23710,7 +23885,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Starter opp og spiller uten krasj eller GPU-feil av noe slag, og med en hastighet som er rask nok til å ha rimelig glede av på en gjennomsnittlig PC.",
"pl_PL": "",
"pt_BR": "Inicializa e roda sem travamentos ou bugs de GPU de qualquer tipo, e em uma velocidade rápida o suficiente para ser aproveitado em um PC comum.",
"ru_RU": "",
@@ -23735,7 +23910,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Starter og går i gang i spillet, men lider av ett eller flere av følgende: krasjer, fastlåser, GPU-feil, distraherende dårlig lyd eller er rett og slett for tregt. Spillet kan fortsatt spilles helt til ende, men ikke slik det er ment å spilles.",
"pl_PL": "",
"pt_BR": "Inicializa e entra no jogo, mas sofre de um ou mais dos seguintes: travamentos, deadlocks, bugs de GPU, áudio ruim que distrai ou é simplesmente muito lento. O jogo ainda pode ser jogado até o fim, mas não da forma como foi criado para ser jogado.",
"ru_RU": "",
@@ -23760,7 +23935,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Starter opp og går forbi tittelskjermen, men kommer ikke inn i hovedspillet.",
"pl_PL": "",
"pt_BR": "Inicializa e passa da tela de título, mas não entra no jogo principal.",
"ru_RU": "",
@@ -23776,7 +23951,7 @@
"ID": "CompatibilityListBootsTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Startet, kommt aber nicht über den Titelbildschirm hinaus.",
"el_GR": "",
"en_US": "Boots but does not make it past the title screen.",
"es_ES": "",
@@ -23785,7 +23960,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Starter, men kommer ikke lenger enn til tittelskjermen.",
"pl_PL": "",
"pt_BR": "Inizializa, mas não passa da tela de título.",
"ru_RU": "",
@@ -23801,7 +23976,7 @@
"ID": "CompatibilityListNothingTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Startet nicht oder zeigt keine Anzeichen von Aktivität.",
"el_GR": "",
"en_US": "Does not boot or shows no signs of activity.",
"es_ES": "",
@@ -23810,7 +23985,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Starter ikke opp eller viser ingen tegn til aktivitet.",
"pl_PL": "",
"pt_BR": "Não inicializa ou não mostra sinais de atividade.",
"ru_RU": "",
@@ -23826,7 +24001,7 @@
"ID": "ExtractAocListHeader",
"Translations": {
"ar_SA": "",
"de_DE": "",
"de_DE": "Wähle ein DLC zum Extrahieren aus",
"el_GR": "",
"en_US": "Select a DLC to Extract",
"es_ES": "",
@@ -23839,7 +24014,7 @@
"pl_PL": "",
"pt_BR": "Selecione um DLC para extrair",
"ru_RU": "",
"sv_SE": "",
"sv_SE": "Välj en DLC att extrahera",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
@@ -23860,7 +24035,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Rikt nærværsbilde",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
@@ -23885,7 +24060,7 @@
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"no_NO": "Dynamisk og rik tilstedeværelse",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",

View File

@@ -1,14 +0,0 @@
using System;
namespace Ryujinx.Ava.Common
{
public static class ThemeManager
{
public static event Action ThemeChanged;
public static void OnThemeChanged()
{
ThemeChanged?.Invoke();
}
}
}

View File

@@ -513,7 +513,7 @@ namespace Ryujinx.Headless
Exit();
}
public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText)
public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText, (uint Module, uint Description)? errorCode = null)
{
SDL_MessageBoxData data = new()
{
@@ -521,7 +521,7 @@ namespace Ryujinx.Headless
message = message,
buttons = new SDL_MessageBoxButtonData[buttonsText.Length],
numbuttons = buttonsText.Length,
window = WindowHandle,
window = WindowHandle
};
for (int i = 0; i < buttonsText.Length; i++)

View File

@@ -22,6 +22,8 @@ namespace Ryujinx.Ava
{
public class RyujinxApp : Application
{
public static event Action ThemeChanged;
internal static string FormatTitle(LocaleKeys? windowTitleKey = null, bool includeVersion = true)
=> windowTitleKey is null
? $"{FullAppName}{(includeVersion ? $" {Program.Version}" : string.Empty)}"
@@ -112,7 +114,7 @@ namespace Ryujinx.Ava
baseStyle = ConfigurationState.Instance.UI.BaseStyle;
}
ThemeManager.OnThemeChanged();
ThemeChanged?.Invoke();
RequestedThemeVariant = baseStyle switch
{

View File

@@ -75,31 +75,32 @@ namespace Ryujinx.Ava.UI.Applet
bool opened = false;
UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent,
title,
message,
string.Empty,
LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel],
string.Empty,
LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
(int)Symbol.Important,
deferEvent,
async window =>
{
if (opened)
{
return;
}
title,
message,
string.Empty,
LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel],
string.Empty,
LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
(int)Symbol.Important,
deferEvent,
async window =>
{
if (opened)
{
return;
}
opened = true;
opened = true;
_parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
_parent.SettingsWindow =
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
await _parent.SettingsWindow.ShowDialog(window);
await _parent.SettingsWindow.ShowDialog(window);
_parent.SettingsWindow = null;
_parent.SettingsWindow = null;
opened = false;
});
opened = false;
});
if (response == UserResult.Ok)
{
@@ -110,7 +111,9 @@ namespace Ryujinx.Ava.UI.Applet
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
dialogCloseEvent.Set();
}
@@ -134,7 +137,9 @@ namespace Ryujinx.Ava.UI.Applet
try
{
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
(UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
(UserResult result, string userInput) =
await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard],
args);
if (result == UserResult.Ok)
{
@@ -146,7 +151,9 @@ namespace Ryujinx.Ava.UI.Applet
{
error = true;
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
}
finally
{
@@ -177,7 +184,8 @@ namespace Ryujinx.Ava.UI.Applet
args.InitialText = "Ryujinx";
args.StringLengthMin = 1;
args.StringLengthMax = 25;
(UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args);
(UserResult result, string userInput) =
await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args);
if (result == UserResult.Ok)
{
inputText = userInput;
@@ -201,11 +209,13 @@ namespace Ryujinx.Ava.UI.Applet
Dispatcher.UIThread.InvokeAsync(async () =>
{
dialogCloseEvent.Set();
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.CabinetScanDialog],
string.Empty,
LocaleManager.Instance[LocaleKeys.InputDialogOk],
string.Empty,
LocaleManager.Instance[LocaleKeys.CabinetTitle]);
await ContentDialogHelper.CreateInfoDialog(
LocaleManager.Instance[LocaleKeys.CabinetScanDialog],
string.Empty,
LocaleManager.Instance[LocaleKeys.InputDialogOk],
string.Empty,
LocaleManager.Instance[LocaleKeys.CabinetTitle]
);
});
dialogCloseEvent.WaitOne();
}
@@ -217,7 +227,8 @@ namespace Ryujinx.Ava.UI.Applet
_parent.ViewModel.AppHost?.Stop();
}
public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
public bool DisplayErrorAppletDialog(string title, string message, string[] buttons,
(uint Module, uint Description)? errorCode = null)
{
ManualResetEvent dialogCloseEvent = new(false);
@@ -229,9 +240,7 @@ namespace Ryujinx.Ava.UI.Applet
{
ErrorAppletWindow msgDialog = new(_parent, buttons, message)
{
Title = title,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Width = 400
Title = title, WindowStartupLocation = WindowStartupLocation.CenterScreen, Width = 400
};
object response = await msgDialog.Run();
@@ -249,7 +258,9 @@ namespace Ryujinx.Ava.UI.Applet
{
dialogCloseEvent.Set();
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
}
});
@@ -259,38 +270,36 @@ namespace Ryujinx.Ava.UI.Applet
}
public IDynamicTextInputHandler CreateDynamicTextInputHandler() => new AvaloniaDynamicTextInputHandler(_parent);
public UserProfile ShowPlayerSelectDialog()
{
UserId selected = UserId.Null;
byte[] defaultGuestImage = EmbeddedResources.Read("Ryujinx.HLE/HOS/Services/Account/Acc/GuestUserImage.jpg");
UserProfile guest = new(new UserId("00000000000000000000000000000080"), "Guest", defaultGuestImage);
ManualResetEvent dialogCloseEvent = new(false);
Dispatcher.UIThread.InvokeAsync(async () =>
{
ObservableCollection<BaseModel> profiles = [];
NavigationDialogHost nav = new();
_parent.AccountManager.GetAllUsers()
.OrderBy(x => x.Name)
.ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav)));
profiles.Add(new Models.UserProfile(guest, nav));
UserSelectorDialogViewModel viewModel = new()
ProfileSelectorDialogViewModel viewModel = new()
{
Profiles = profiles,
SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
Profiles = profiles, SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
};
UserSelectorDialog content = new(viewModel);
(selected, _) = await UserSelectorDialog.ShowInputDialog(content);
(selected, _) = await ProfileSelectorDialog.ShowInputDialog(viewModel);
dialogCloseEvent.Set();
});
dialogCloseEvent.WaitOne();
UserProfile profile = _parent.AccountManager.LastOpenedUser;
if (selected == guest.UserId)
{
@@ -311,6 +320,7 @@ namespace Ryujinx.Ava.UI.Applet
}
}
}
return profile;
}
}

View File

@@ -1,5 +1,5 @@
<UserControl
x:Class="Ryujinx.Ava.UI.Applet.UserSelectorDialog"
x:Class="Ryujinx.Ava.UI.Applet.ProfileSelectorDialog"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -12,9 +12,9 @@
d:DesignWidth="800"
mc:Ignorable="d"
Focusable="True"
x:DataType="viewModels:UserSelectorDialogViewModel">
x:DataType="viewModels:ProfileSelectorDialogViewModel">
<Design.DataContext>
<viewModels:UserSelectorDialogViewModel />
<viewModels:ProfileSelectorDialogViewModel />
</Design.DataContext>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

View File

@@ -16,15 +16,15 @@ using UserProfileSft = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
namespace Ryujinx.Ava.UI.Applet
{
public partial class UserSelectorDialog : UserControl, INotifyPropertyChanged
public partial class ProfileSelectorDialog : UserControl
{
public UserSelectorDialogViewModel ViewModel { get; set; }
public ProfileSelectorDialogViewModel ViewModel { get; set; }
public UserSelectorDialog(UserSelectorDialogViewModel viewModel)
public ProfileSelectorDialog(ProfileSelectorDialogViewModel viewModel)
{
DataContext = ViewModel = viewModel;
InitializeComponent();
ViewModel = viewModel;
DataContext = ViewModel;
}
private void Grid_PointerEntered(object sender, PointerEventArgs e)
@@ -54,7 +54,7 @@ namespace Ryujinx.Ava.UI.Applet
if (ViewModel.Profiles[selectedIndex] is UserProfile userProfile)
{
ViewModel.SelectedUserId = userProfile.UserId;
Logger.Info?.Print(LogClass.UI, $"Selected user: {userProfile.UserId}");
Logger.Info?.Print(LogClass.UI, $"Selected: {userProfile.UserId}", "ProfileSelector");
ObservableCollection<BaseModel> newProfiles = [];
@@ -79,7 +79,7 @@ namespace Ryujinx.Ava.UI.Applet
}
}
public static async Task<(UserId Id, bool Result)> ShowInputDialog(UserSelectorDialog content)
public static async Task<(UserId Id, bool Result)> ShowInputDialog(ProfileSelectorDialogViewModel viewModel)
{
ContentDialog contentDialog = new()
{
@@ -87,22 +87,25 @@ namespace Ryujinx.Ava.UI.Applet
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue],
SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.Cancel],
Content = content,
Content = new ProfileSelectorDialog(viewModel),
Padding = new Thickness(0)
};
UserId result = UserId.Null;
bool input = false;
contentDialog.Closed += Handler;
await ContentDialogHelper.ShowAsync(contentDialog);
return (result, input);
void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs)
{
if (eventArgs.Result == ContentDialogResult.Primary)
{
if (contentDialog.Content is UserSelectorDialog view)
{
result = view.ViewModel.SelectedUserId;
input = true;
}
result = viewModel.SelectedUserId;
input = true;
}
else
{
@@ -110,12 +113,6 @@ namespace Ryujinx.Ava.UI.Applet
input = false;
}
}
contentDialog.Closed += Handler;
await ContentDialogHelper.ShowAsync(contentDialog);
return (result, input);
}
}
}

View File

@@ -2,6 +2,7 @@ using Avalonia.Media.Imaging;
using Avalonia.Styling;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using Gommon;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Utilities.Configuration;
@@ -24,30 +25,35 @@ namespace Ryujinx.Ava.UI.ViewModels
Version = RyujinxApp.FullAppName + "\n" + Program.Version;
UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value);
ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
RyujinxApp.ThemeChanged += Ryujinx_ThemeChanged;
}
private void ThemeManager_ThemeChanged()
private void Ryujinx_ThemeChanged()
{
Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
}
private const string LogoPathFormat = "resm:Ryujinx.Assets.UIImages.Logo_{0}_{1}.png?assembly=Ryujinx";
private void UpdateLogoTheme(string theme)
{
bool isDarkTheme = theme == "Dark" || (theme == "Auto" && RyujinxApp.DetectSystemTheme() == ThemeVariant.Dark);
string themeName = isDarkTheme ? "Dark" : "Light";
string basePath = "resm:Ryujinx.Assets.UIImages.";
string themeSuffix = isDarkTheme ? "Dark.png" : "Light.png";
GithubLogo = LoadBitmap($"{basePath}Logo_GitHub_{themeSuffix}?assembly=Ryujinx");
DiscordLogo = LoadBitmap($"{basePath}Logo_Discord_{themeSuffix}?assembly=Ryujinx");
GithubLogo = LoadBitmap(LogoPathFormat.Format("GitHub", themeName));
DiscordLogo = LoadBitmap(LogoPathFormat.Format("Discord", themeName));
}
private static Bitmap LoadBitmap(string uri) => new(Avalonia.Platform.AssetLoader.Open(new Uri(uri)));
public void Dispose()
{
ThemeManager.ThemeChanged -= ThemeManager_ThemeChanged;
RyujinxApp.ThemeChanged -= Ryujinx_ThemeChanged;
GithubLogo.Dispose();
DiscordLogo.Dispose();
GC.SuppressFinalize(this);
}
}

View File

@@ -264,7 +264,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
// Neither local or remote files are valid JSON, close window.
ShowInfoDialog();
await ShowInfoDialog();
Close();
}
else if (!remoteIsValid)
@@ -273,7 +273,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// Only the local file is valid, the local one should be used
// but the user should be warned.
ShowInfoDialog();
await ShowInfoDialog();
}
}
@@ -525,7 +525,7 @@ namespace Ryujinx.Ava.UI.ViewModels
AmiiboImage = bitmap;
}
private static async void ShowInfoDialog()
private static async Task ShowInfoDialog()
{
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
LocaleManager.Instance[LocaleKeys.DialogAmiiboApiConnectErrorMessage],

View File

@@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
namespace Ryujinx.Ava.UI.ViewModels
{
public partial class UserSelectorDialogViewModel : BaseModel
public partial class ProfileSelectorDialogViewModel : BaseModel
{
[ObservableProperty] private UserId _selectedUserId;

View File

@@ -126,6 +126,10 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
public bool DisableInputWhenOutOfFocus { get; set; }
public int FocusLostActionType { get; set; }
public VSyncMode VSyncMode
{
get => _vSyncMode;
@@ -479,6 +483,7 @@ namespace Ryujinx.Ava.UI.ViewModels
ShowTitleBar = config.ShowTitleBar;
HideCursor = (int)config.HideCursor.Value;
UpdateCheckerType = (int)config.UpdateCheckerType.Value;
FocusLostActionType = (int)config.FocusLostActionType.Value;
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);
@@ -498,6 +503,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableDockedMode = config.System.EnableDockedMode;
EnableKeyboard = config.Hid.EnableKeyboard;
EnableMouse = config.Hid.EnableMouse;
DisableInputWhenOutOfFocus = config.Hid.DisableInputWhenOutOfFocus;
// Keyboard Hotkeys
KeyboardHotkey = new HotkeyConfig(config.Hid.Hotkeys.Value);
@@ -586,6 +592,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.ShowTitleBar.Value = ShowTitleBar;
config.HideCursor.Value = (HideCursorMode)HideCursor;
config.UpdateCheckerType.Value = (UpdaterType)UpdateCheckerType;
config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType;
if (GameDirectoryChanged)
{
@@ -609,6 +616,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.EnableDockedMode.Value = EnableDockedMode;
config.Hid.EnableKeyboard.Value = EnableKeyboard;
config.Hid.EnableMouse.Value = EnableMouse;
config.Hid.DisableInputWhenOutOfFocus.Value = DisableInputWhenOutOfFocus;
// Keyboard Hotkeys
config.Hid.Hotkeys.Value = KeyboardHotkey.GetConfig();

View File

@@ -290,12 +290,12 @@
<Binding Path="UpdateAvailable" />
</MultiBinding>
</StackPanel.IsVisible>
<Button Margin="0, 0, 5, 0"
<Button Margin="0, 0, 5, -2"
Command="{Binding UpdateCommand}"
Background="{DynamicResource SystemAccentColor}">
<TextBlock
Margin="-5"
Foreground="Black"
Foreground="{StaticResource SystemColorButtonTextColor}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="{ext:Locale UpdaterBackgroundStatusBarButtonText}" />

View File

@@ -40,6 +40,30 @@
<CheckBox IsChecked="{Binding ShowTitleBar}" IsVisible="{x:Static helper:RunningPlatform.IsWindows}">
<TextBlock Text="{ext:Locale SettingsTabGeneralShowTitleBar}" />
</CheckBox>
<StackPanel Margin="0, 15, 0, 0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralFocusLossType}"
Width="150" />
<ComboBox SelectedIndex="{Binding FocusLostActionType}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeDoNothing}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeBlockInput}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeMuteAudio}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypeBlockInputAndMuteAudio}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabGeneralFocusLossTypePauseEmulation}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel Margin="0, 15, 0, 0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
Text="{ext:Locale SettingsTabGeneralCheckUpdatesOnLaunch}"

View File

@@ -142,42 +142,40 @@
<Grid
Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" RowDefinitions="Auto,Auto">
VerticalAlignment="Stretch" RowDefinitions="Auto,Auto,Auto">
<StackPanel
Grid.Row="0"
Margin="0,10,0,0"
Spacing="2">
<TextBlock
FontSize="15"
Classes="h1"
FontWeight="Bold"
Text="{ext:Locale AboutRyujinxAboutTitle}" />
<TextBlock
FontSize="10"
Text="{ext:Locale AboutRyujinxAboutContent}"
TextWrapping="Wrap" />
</StackPanel>
<Separator Grid.Row="1" Margin="0,20" />
<StackPanel
Grid.Row="1"
Margin="0,10,0,0"
Grid.Row="2"
Spacing="2">
<TextBlock
FontSize="15"
Classes="h1"
FontWeight="Bold"
Text="{ext:Locale AboutRyujinxMaintainersTitle}" />
<TextBlock
FontSize="10"
Margin="0, 0, 0, 5"
TextWrapping="Wrap"
Text="{Binding Developers}"/>
<TextBlock
FontSize="15"
Classes="h1"
FontWeight="Bold"
Text="{ext:Locale AboutRyujinxFormerMaintainersTitle}" />
<TextBlock
FontSize="10"
FontSize="11"
Text="{Binding FormerDevelopers}"
TextWrapping="Wrap" />
<Button
Margin="0, 5, 0, 0"
Padding="5"
HorizontalAlignment="Left"
Background="Transparent"

View File

@@ -18,8 +18,6 @@ namespace Ryujinx.Ava.UI.Windows
{
public AboutWindow()
{
DataContext = new AboutWindowViewModel();
InitializeComponent();
GitHubRepoButton.Tag =
@@ -28,12 +26,14 @@ namespace Ryujinx.Ava.UI.Windows
public static async Task Show()
{
using AboutWindowViewModel viewModel = new();
ContentDialog contentDialog = new()
{
PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
Content = new AboutWindow()
Content = new AboutWindow { DataContext = viewModel }
};
Style closeButton = new(x => x.Name("CloseButton"));

View File

@@ -21,7 +21,9 @@
x:DataType="viewModels:MainWindowViewModel"
mc:Ignorable="d"
WindowStartupLocation="Manual"
Focusable="True">
Focusable="True"
GotFocus="InputElement_OnGotFocus"
LostFocus="InputElement_OnLostFocus">
<Window.Styles>
<Style Selector="TitleBar:fullscreen">
<Setter Property="Background" Value="#000000" />

View File

@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Platform;
using Avalonia.Threading;
@@ -761,5 +762,119 @@ namespace Ryujinx.Ava.UI.Windows
_intelMacWarningShown = true;
}
private void InputElement_OnGotFocus(object sender, GotFocusEventArgs e)
{
if (ViewModel.AppHost is null) return;
if (!_focusLoss.Active)
return;
switch (_focusLoss.Type)
{
case FocusLostType.BlockInput:
{
if (!ViewModel.AppHost.NpadManager.InputUpdatesBlocked)
{
_focusLoss = default;
return;
}
ViewModel.AppHost.NpadManager.UnblockInputUpdates();
_focusLoss = default;
break;
}
case FocusLostType.MuteAudio:
{
if (!ViewModel.AppHost.Device.IsAudioMuted())
{
_focusLoss = default;
return;
}
ViewModel.AppHost.Device.SetVolume(ViewModel.VolumeBeforeMute);
_focusLoss = default;
break;
}
case FocusLostType.BlockInputAndMuteAudio:
{
if (!ViewModel.AppHost.Device.IsAudioMuted())
goto case FocusLostType.BlockInput;
ViewModel.AppHost.Device.SetVolume(ViewModel.VolumeBeforeMute);
ViewModel.AppHost.NpadManager.UnblockInputUpdates();
_focusLoss = default;
break;
}
case FocusLostType.PauseEmulation:
{
if (!ViewModel.AppHost.Device.System.IsPaused)
{
_focusLoss = default;
return;
}
ViewModel.AppHost.Resume();
_focusLoss = default;
break;
}
}
}
private (FocusLostType Type, bool Active) _focusLoss;
private void InputElement_OnLostFocus(object sender, RoutedEventArgs e)
{
if (ConfigurationState.Instance.FocusLostActionType.Value is FocusLostType.DoNothing)
return;
if (ViewModel.AppHost is null) return;
switch (ConfigurationState.Instance.FocusLostActionType.Value)
{
case FocusLostType.BlockInput:
{
if (ViewModel.AppHost.NpadManager.InputUpdatesBlocked)
return;
ViewModel.AppHost.NpadManager.BlockInputUpdates();
_focusLoss = (FocusLostType.BlockInput, ViewModel.AppHost.NpadManager.InputUpdatesBlocked);
break;
}
case FocusLostType.MuteAudio:
{
if (ViewModel.AppHost.Device.GetVolume() is 0)
return;
ViewModel.VolumeBeforeMute = ViewModel.AppHost.Device.GetVolume();
ViewModel.AppHost.Device.SetVolume(0);
_focusLoss = (FocusLostType.MuteAudio, ViewModel.AppHost.Device.GetVolume() is 0f);
break;
}
case FocusLostType.BlockInputAndMuteAudio:
{
if (ViewModel.AppHost.Device.GetVolume() is 0)
goto case FocusLostType.BlockInput;
ViewModel.VolumeBeforeMute = ViewModel.AppHost.Device.GetVolume();
ViewModel.AppHost.Device.SetVolume(0);
ViewModel.AppHost.NpadManager.BlockInputUpdates();
_focusLoss = (FocusLostType.BlockInputAndMuteAudio, ViewModel.AppHost.Device.GetVolume() is 0f && ViewModel.AppHost.NpadManager.InputUpdatesBlocked);
break;
}
case FocusLostType.PauseEmulation:
{
if (ViewModel.AppHost.Device.System.IsPaused)
return;
ViewModel.AppHost.Pause();
_focusLoss = (FocusLostType.PauseEmulation, ViewModel.AppHost.Device.System.IsPaused);
break;
}
}
}
}
}

View File

@@ -80,7 +80,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
public string LocalizedStatusTooltip =>
Compatibility.Convert(x =>
#pragma warning disable CS8509 It is exhaustive for all possible values this can contain.
#pragma warning disable CS8509 // It is exhaustive for all possible values this can contain.
LocaleManager.Instance[x.Status switch
#pragma warning restore CS8509
{

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// <summary>
/// The current version of the file format
/// </summary>
public const int CurrentVersion = 65;
public const int CurrentVersion = 67;
/// <summary>
/// Version of the configuration file format
@@ -171,6 +171,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
/// </summary>
public UpdaterType UpdateCheckerType { get; set; }
/// <summary>
/// How the emulator should behave when you click off/on the window.
/// </summary>
public FocusLostType FocusLostActionType { get; set; }
/// <summary>
/// Show "Confirm Exit" Dialog
@@ -383,6 +388,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Enable or disable mouse support (Independent from controllers binding)
/// </summary>
public bool EnableMouse { get; set; }
/// <summary>
/// Enable/disable the ability to control Ryujinx when it's not the currently focused window.
/// </summary>
public bool DisableInputWhenOutOfFocus { get; set; }
/// <summary>
/// Hotkey Keyboard Bindings

View File

@@ -46,6 +46,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart;
UpdateCheckerType.Value = cff.UpdateCheckerType;
FocusLostActionType.Value = cff.FocusLostActionType;
ShowConfirmExit.Value = cff.ShowConfirmExit;
RememberWindowState.Value = cff.RememberWindowState;
ShowTitleBar.Value = cff.ShowTitleBar;
@@ -139,6 +140,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
Hid.EnableKeyboard.Value = cff.EnableKeyboard;
Hid.EnableMouse.Value = cff.EnableMouse;
Hid.DisableInputWhenOutOfFocus.Value = cff.DisableInputWhenOutOfFocus;
Hid.Hotkeys.Value = cff.Hotkeys;
Hid.InputConfig.Value = cff.InputConfig ?? [];
Hid.RainbowSpeed.Value = cff.RainbowSpeed;
@@ -433,7 +435,9 @@ namespace Ryujinx.Ava.Utilities.Configuration
(62, static cff => cff.RainbowSpeed = 1f),
(63, static cff => cff.MatchSystemTime = false),
(64, static cff => cff.LoggingEnableAvalonia = false),
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off)
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
(66, static cff => cff.DisableInputWhenOutOfFocus = false),
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing)
);
}
}

View File

@@ -447,6 +447,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Enable or disable mouse support (Independent from controllers binding)
/// </summary>
public ReactiveObject<bool> EnableMouse { get; private set; }
/// <summary>
/// Enable/disable the ability to control Ryujinx when it's not the currently focused window.
/// </summary>
public ReactiveObject<bool> DisableInputWhenOutOfFocus { get; private set; }
/// <summary>
/// Hotkey Keyboard Bindings
@@ -469,6 +474,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
{
EnableKeyboard = new ReactiveObject<bool>();
EnableMouse = new ReactiveObject<bool>();
DisableInputWhenOutOfFocus = new ReactiveObject<bool>();
Hotkeys = new ReactiveObject<KeyboardHotkeys>();
InputConfig = new ReactiveObject<List<InputConfig>>();
RainbowSpeed = new ReactiveObject<float>();
@@ -773,6 +779,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
/// </summary>
public ReactiveObject<UpdaterType> UpdateCheckerType { get; private set; }
/// <summary>
/// How the emulator should behave when you click off/on the window.
/// </summary>
public ReactiveObject<FocusLostType> FocusLostActionType { get; private set; }
/// <summary>
/// Show "Confirm Exit" Dialog
@@ -811,6 +822,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
EnableDiscordIntegration = new ReactiveObject<bool>();
CheckUpdatesOnStart = new ReactiveObject<bool>();
UpdateCheckerType = new ReactiveObject<UpdaterType>();
FocusLostActionType = new ReactiveObject<FocusLostType>();
ShowConfirmExit = new ReactiveObject<bool>();
RememberWindowState = new ReactiveObject<bool>();
ShowTitleBar = new ReactiveObject<bool>();

View File

@@ -57,6 +57,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart,
UpdateCheckerType = UpdateCheckerType,
FocusLostActionType = FocusLostActionType,
ShowConfirmExit = ShowConfirmExit,
RememberWindowState = RememberWindowState,
ShowTitleBar = ShowTitleBar,
@@ -131,6 +132,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
ShowConsole = UI.ShowConsole,
EnableKeyboard = Hid.EnableKeyboard,
EnableMouse = Hid.EnableMouse,
DisableInputWhenOutOfFocus = Hid.DisableInputWhenOutOfFocus,
Hotkeys = Hid.Hotkeys,
InputConfig = Hid.InputConfig,
RainbowSpeed = Hid.RainbowSpeed,
@@ -177,6 +179,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
System.EnableDockedMode.Value = true;
EnableDiscordIntegration.Value = true;
UpdateCheckerType.Value = UpdaterType.PromptAtStartup;
FocusLostActionType.Value = FocusLostType.DoNothing;
ShowConfirmExit.Value = true;
RememberWindowState.Value = true;
ShowTitleBar.Value = !OperatingSystem.IsWindows();
@@ -245,6 +248,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
UI.WindowStartup.WindowMaximized.Value = false;
Hid.EnableKeyboard.Value = false;
Hid.EnableMouse.Value = false;
Hid.DisableInputWhenOutOfFocus.Value = false;
Hid.Hotkeys.Value = new KeyboardHotkeys
{
ToggleVSyncMode = Key.F1,

View File

@@ -0,0 +1,15 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration.UI
{
[JsonConverter(typeof(TypedStringEnumConverter<FocusLostType>))]
public enum FocusLostType
{
DoNothing,
BlockInput,
MuteAudio,
BlockInputAndMuteAudio,
PauseEmulation
}
}