0
0
Fork 0
mirror of https://github.com/ryujinx-mirror/ryujinx.git synced 2024-12-22 14:45:44 +00:00

Avalonia UI - Part 1 (#3270)

* avalonia part 1

* remove vulkan ui backend

* move ui common files to ui common project

* get name for oading screen from device

* rebase.

* review 1

* review 1.1

* review

* cleanup

* addressed review

* use cancellation token

* review

* review

* rebased

* cancel library loading when closing window

* remove star  image, use fonticon instead

* delete render control frame buffer when game ends. change position of fav star

* addressed @Thog review

* ensure the right ui is downloaded in updates

* fix crash when showing not supported dialog during controller request

* add prefix to artifact names

* Auto-format Avalonia project

* Fix input

* Fix build, simplify app disposal

* remove nv stutter thread

* addressed review

* add missing change

* maintain window size if new size is zero length

* add game, handheld, docked to local

* reverse scale main window

* Update de_DE.json

* Update de_DE.json

* Update de_DE.json

* Update italian json

* Update it_IT.json

* let render timer poll with no wait

* remove unused code

* more unused code

* enabled tiered compilation and trimming

* check if window event is not closed before signaling

* fix atmospher case

* locale fix

* locale fix

* remove explicit tiered compilation declarations

* Remove ) it_IT.json

* Remove ) de_DE.json

* Update it_IT.json

* Update pt_BR locale with latest strings

* Remove ')'

* add more strings to locale

* update locale

* remove extra slash

* remove extra slash

* set firmware version to 0 if key's not found

* fix

* revert timer changes

* lock  on object instead

* Update it_IT.json

* remove unused method

* add load screen text to locale

* drop swap event

* Update de_DE.json

* Update de_DE.json

* do null check when stopping emulator

* Update de_DE.json

* Create tr_TR.json

* Add tr_TR

* Add tr_TR + Turkish

* Update it_IT.json

* Update Ryujinx.Ava/Input/AvaloniaMappingHelper.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* addressed review

* Update Ryujinx.Ava/Ui/Backend/OpenGl/OpenGlRenderTarget.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* use avalonia's inbuilt renderer on linux

* removed whitespace

* workaround for queue render crash with vsync off

* drop custom backend

* format files

* fix not closing issue

* remove warnings

* rebase

* update avalonia library

* Reposition the Text and Button on About Page

* Assign build version

* Remove appveyor text

Co-authored-by: gdk <gab.dark.100@gmail.com>
Co-authored-by: Niwu34 <67392333+Niwu34@users.noreply.github.com>
Co-authored-by: Antonio Brugnolo <36473846+AntoSkate@users.noreply.github.com>
Co-authored-by: aegiff <99728970+aegiff@users.noreply.github.com>
Co-authored-by: Ac_K <Acoustik666@gmail.com>
Co-authored-by: MostlyWhat <78652091+MostlyWhat@users.noreply.github.com>
This commit is contained in:
Emmanuel Hansen 2022-05-15 11:30:15 +00:00 committed by GitHub
parent 9ba73ffbe5
commit deb99d2cae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
161 changed files with 17179 additions and 855 deletions

View file

@ -69,6 +69,9 @@ jobs:
- name: Publish Ryujinx.Headless.SDL2 - name: Publish Ryujinx.Headless.SDL2
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Headless.SDL2 --self-contained run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Headless.SDL2 --self-contained
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
- name: Publish Ryujinx.Ava
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava /p:Version="1.0.0" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava
if: github.event_name == 'pull_request'
- name: Upload Ryujinx artifact - name: Upload Ryujinx artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
@ -78,6 +81,12 @@ jobs:
- name: Upload Ryujinx.Headless.SDL2 artifact - name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: ryujinx-headless-sdl2-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish_sdl2_headless path: publish_sdl2_headless
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
- name: Upload Ryujinx.Ava artifact
uses: actions/upload-artifact@v2
with:
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish_ava
if: github.event_name == 'pull_request'

View file

@ -132,7 +132,7 @@ This software is licensed under the terms of the <a href="https://github.com/Ryu
The Ryujinx.Audio project is licensed under the terms of the <a href="https://github.com/Ryujinx/Ryujinx/blob/master/Ryujinx.Audio/LICENSE.txt The Ryujinx.Audio project is licensed under the terms of the <a href="https://github.com/Ryujinx/Ryujinx/blob/master/Ryujinx.Audio/LICENSE.txt
" target="_blank">LGPLv3 license.</a></i><br /> " target="_blank">LGPLv3 license.</a></i><br />
This project makes use of code authored by the libvpx project, licensed under BSD and the ffmpeg project, licensed under LGPLv3. This project makes use of code authored by the libvpx project, licensed under BSD and the ffmpeg project, licensed under LGPLv3.
See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](Ryujinx/THIRDPARTY.md) for more details. See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY.md) for more details.
## Credits ## Credits
- [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system. - [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system.

9
Ryujinx.Ava/App.axaml Normal file
View file

@ -0,0 +1,9 @@
<Application
x:Class="Ryujinx.Ava.App"
xmlns="https://github.com/avaloniaui"
xmlns:sty="using:FluentAvalonia.Styling"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Styles>
<sty:FluentAvaloniaTheme UseSystemThemeOnWindows="False"/>
</Application.Styles>
</Application>

126
Ryujinx.Ava/App.axaml.cs Normal file
View file

@ -0,0 +1,126 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
using Avalonia.Threading;
using FluentAvalonia.Styling;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Ui.Common.Configuration;
using System;
using System.IO;
namespace Ryujinx.Ava
{
public class App : Avalonia.Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
if (Program.PreviewerDetached)
{
ApplyConfiguredTheme();
ConfigurationState.Instance.Ui.BaseStyle.Event += ThemeChanged_Event;
ConfigurationState.Instance.Ui.CustomThemePath.Event += ThemeChanged_Event;
ConfigurationState.Instance.Ui.EnableCustomTheme.Event += CustomThemeChanged_Event;
}
}
private void CustomThemeChanged_Event(object sender, ReactiveEventArgs<bool> e)
{
ApplyConfiguredTheme();
}
private void ShowRestartDialog()
{
// TODO. Implement Restart Dialog when SettingsWindow is implemented.
}
private void ThemeChanged_Event(object sender, ReactiveEventArgs<string> e)
{
ApplyConfiguredTheme();
}
private void ApplyConfiguredTheme()
{
try
{
string baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
string themePath = ConfigurationState.Instance.Ui.CustomThemePath;
bool enableCustomTheme = ConfigurationState.Instance.Ui.EnableCustomTheme;
const string BaseStyleUrl = "avares://Ryujinx.Ava/Assets/Styles/Base{0}.xaml";
if (string.IsNullOrWhiteSpace(baseStyle))
{
ConfigurationState.Instance.Ui.BaseStyle.Value = "Dark";
baseStyle = ConfigurationState.Instance.Ui.BaseStyle;
}
var theme = AvaloniaLocator.Current.GetService<FluentAvaloniaTheme>();
theme.RequestedTheme = baseStyle;
var currentStyles = this.Styles;
// Remove all styles except the base style.
if (currentStyles.Count > 1)
{
currentStyles.RemoveRange(1, currentStyles.Count - 1);
}
IStyle newStyles = null;
// Load requested style, and fallback to Dark theme if loading failed.
try
{
newStyles = (Styles)AvaloniaXamlLoader.Load(new Uri(string.Format(BaseStyleUrl, baseStyle), UriKind.Absolute));
}
catch (XamlLoadException)
{
newStyles = (Styles)AvaloniaXamlLoader.Load(new Uri(string.Format(BaseStyleUrl, "Dark"), UriKind.Absolute));
}
currentStyles.Add(newStyles);
if (enableCustomTheme)
{
if (!string.IsNullOrWhiteSpace(themePath))
{
try
{
var themeContent = File.ReadAllText(themePath);
var customStyle = AvaloniaRuntimeXamlLoader.Parse<IStyle>(themeContent);
currentStyles.Add(customStyle);
}
catch (Exception ex)
{
Logger.Error?.Print(LogClass.Application, $"Failed to Apply Custom Theme. Error: {ex.Message}");
}
}
}
}
catch (Exception)
{
Logger.Warning?.Print(LogClass.Application, "Failed to Apply Theme. A restart is needed to apply the selected theme");
ShowRestartDialog();
}
}
}
}

1056
Ryujinx.Ava/AppHost.cs Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,549 @@
{
"MenuBarFileOpenApplet": "Applet öffnen",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Öffnet das Mii Editor Applet im Standalone Modus",
"SettingsTabInputDirectMouseAccess": "Direkter Mauszugriff",
"SettingsTabSystemMemoryManagerMode": "Speichermanagermodus:",
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
"SettingsTabSystemMemoryManagerModeHost": "Host (schnell)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host ungeprüft (am schnellsten, unsicher)",
"MenuBarFile": "_Datei",
"MenuBarFileOpenFromFile": "_Datei öffnen",
"MenuBarFileOpenUnpacked": "_Entpacktes Spiel öffnen",
"MenuBarFileOpenEmuFolder": "Ryujinx-Ordner öffnen",
"MenuBarFileOpenLogsFolder": "Logs-Ordner öffnen",
"MenuBarFileExit": "_Beenden",
"MenuBarOptions": "Optionen",
"MenuBarOptionsToggleFullscreen": "Vollbild",
"MenuBarOptionsStartGamesInFullscreen": "Spiele im Vollbildmodus starten",
"MenuBarOptionsStopEmulation": "Emulation beenden",
"MenuBarOptionsSettings": "_Einstellungen",
"MenuBarOptionsManageUserProfiles": "_Profilverwaltung",
"MenuBarActions": "_Aktionen",
"MenuBarOptionsSimulateWakeUpMessage": "Aufwachnachricht",
"MenuBarActionsScanAmiibo": "Amiibo scannen",
"MenuBarTools": "_Werkzeuge",
"MenuBarToolsInstallFirmware": "Firmware installieren",
"MenuBarFileToolsInstallFirmwareFromFile": "Installiere Firmware von einer XCI oder einer ZIP Datei",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Installiere Firmware aus einem Verzeichnis",
"MenuBarHelp": "Hilfe",
"MenuBarHelpCheckForUpdates": "Nach Updates suchen",
"MenuBarHelpAbout": "Über Ryujinx",
"MenuSearch": "Suchen...",
"GameListHeaderFavorite": "Favorit",
"GameListHeaderIcon": "Icon",
"GameListHeaderApplication": "Name",
"GameListHeaderDeveloper": "Entwickler",
"GameListHeaderVersion": "Version",
"GameListHeaderTimePlayed": "Spielzeit",
"GameListHeaderLastPlayed": "Zuletzt gespielt",
"GameListHeaderFileExtension": "Dateiformat",
"GameListHeaderFileSize": "Dateigröße",
"GameListHeaderPath": "Pfad",
"GameListContextMenuOpenUserSaveDirectory": "Spielstand-Verzeichnis öffnen",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Öffnet das Verzeichnis, welches den Benutzer-Spielstand beinhaltet",
"GameListContextMenuOpenUserDeviceDirectory": "Benutzer-Geräte-Verzeichnis öffnen",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Öffnet das Verzeichnis, welches den Geräte-Spielstände beinhaltet",
"GameListContextMenuOpenUserBcatDirectory": "Benutzer-BCAT-Vezeichnis öffnen",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Öffnet das Verzeichnis, welches den BCAT Cache des Spiels beinhaltet",
"GameListContextMenuManageTitleUpdates": "Verwalten von Spiel Updates",
"GameListContextMenuManageTitleUpdatesToolTip": "Öffnet den Spiel-Update-Manager",
"GameListContextMenuManageDlc": "Verwalten von DLC",
"GameListContextMenuManageDlcToolTip": "Öffnet den DLC-Manager",
"GameListContextMenuOpenModsDirectory": "Mod-Verzeichnis öffnen",
"GameListContextMenuOpenModsDirectoryToolTip": "Öffnet das Verzeichnis, welches Mods für die Spiele beinhaltet",
"GameListContextMenuCacheManagement": "Cache Verwaltung",
"GameListContextMenuCacheManagementPurgePptc": "PPTC Cache löschen",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Löscht den PPTC Cache der Anwendung",
"GameListContextMenuCacheManagementPurgeShaderCache": "Shader Cache löschen",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Löscht den Shader Cache der Anwendung",
"GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC Verzeichnis öffnen",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Öffnet das Verzeichnis, das den PPTC Cache der Anwendung beinhaltet",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Shader Cache Verzeichnis öffnen",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Öffnet das Verzeichnis, das den Shader Cache der Anwendung beinhaltet",
"GameListContextMenuExtractData": "Daten extrahieren",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Extrahiert das ExeFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Extrahiert das RomFS aus der aktuellen Anwendungskonfiguration (einschließlich Updates)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Extrahiert das Logo aus der aktuellen Anwendungskonfiguration (einschließlich Updates)",
"StatusBarGamesLoaded": "{0}/{1} Spiele geladen",
"StatusBarSystemVersion": "Systemversion: {0}",
"Settings": "Einstellungen",
"SettingsTabGeneral": "Allgemein",
"SettingsTabGeneralGeneral": "Allgemein",
"SettingsTabGeneralEnableDiscordRichPresence": "Aktiviere Discord Rich Presence",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Beim Start nach Updates suchen",
"SettingsTabGeneralShowConfirmExitDialog": "Zeige den \"Beenden bestätigen\" Dialog",
"SettingsTabGeneralHideCursorOnIdle": "Mauszeiger bei Inaktivität ausblenden",
"SettingsTabGeneralGameDirectories": "Spielverzeichnisse",
"SettingsTabGeneralAdd": "Hinzufügen",
"SettingsTabGeneralRemove": "Entfernen",
"SettingsTabSystem": "System",
"SettingsTabSystemCore": "Kern",
"SettingsTabSystemSystemRegion": "System Region:",
"SettingsTabSystemSystemRegionJapan": "Japan",
"SettingsTabSystemSystemRegionUSA": "USA",
"SettingsTabSystemSystemRegionEurope": "Europa",
"SettingsTabSystemSystemRegionAustralia": "Australien",
"SettingsTabSystemSystemRegionChina": "China",
"SettingsTabSystemSystemRegionKorea": "Korea",
"SettingsTabSystemSystemRegionTaiwan": "Taiwan",
"SettingsTabSystemSystemLanguage": "Systemsprache:",
"SettingsTabSystemSystemLanguageJapanese": "Japanisch",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Amerikanisches Englisch",
"SettingsTabSystemSystemLanguageFrench": "Französisch",
"SettingsTabSystemSystemLanguageGerman": "Deutsch",
"SettingsTabSystemSystemLanguageItalian": "Italienisch",
"SettingsTabSystemSystemLanguageSpanish": "Spanisch",
"SettingsTabSystemSystemLanguageChinese": "Chinesisch",
"SettingsTabSystemSystemLanguageKorean": "Koreanisch",
"SettingsTabSystemSystemLanguageDutch": "Niederländisch",
"SettingsTabSystemSystemLanguagePortuguese": "Portugiesisch",
"SettingsTabSystemSystemLanguageRussian": "Russisch",
"SettingsTabSystemSystemLanguageTaiwanese": "Taiwanesisch",
"SettingsTabSystemSystemLanguageBritishEnglish": "Britisches Englisch",
"SettingsTabSystemSystemLanguageCanadianFrench": "Kanadisches Französisch",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Lateinamerikanisches Spanisch",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Vereinfachtes Chinesisch",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditionelles Chinesisch",
"SettingsTabSystemSystemTimeZone": "System Zeitzone:",
"SettingsTabSystemSystemTime": "System Zeit:",
"SettingsTabSystemEnableVsync": "Aktiviere VSync",
"SettingsTabSystemEnablePptc": "Aktiviere PPTC Cache (Profiled presistent translastion cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Aktiviere die FS Integritätsprüfung",
"SettingsTabSystemAudioBackend": "Audio-Backend:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": " - Können Fehler verursachen",
"SettingsTabSystemExpandDramSize": "Erweitere DRAM Größe auf 6GB",
"SettingsTabSystemIgnoreMissingServices": "Ignoriere fehlende Dienste",
"SettingsTabGraphics": "Grafik",
"SettingsTabGraphicsEnhancements": "Verbesserungen",
"SettingsTabGraphicsEnableShaderCache": "Aktiviere den Shader Cache",
"SettingsTabGraphicsAnisotropicFiltering": "Anisotrope Filterung:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Auflösungsskalierung:",
"SettingsTabGraphicsResolutionScaleCustom": "Benutzerdefiniert (nicht empfohlen)",
"SettingsTabGraphicsResolutionScaleNative": "Nativ (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Bildseitenverhältnis:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Dehnen, um sich an das Fenster anzupassen",
"SettingsTabGraphicsDeveloperOptions": "Optionen für Entwickler",
"SettingsTabGraphicsShaderDumpPath": "Grafik-Shader Dump Pfad:",
"SettingsTabLogging": "Logs",
"SettingsTabLoggingLogging": "Logs",
"SettingsTabLoggingEnableLoggingToFile": "Aktiviere Erstellung von Log-Datei",
"SettingsTabLoggingEnableStubLogs": "Aktiviere Stub-Logs",
"SettingsTabLoggingEnableInfoLogs": "Aktiviere Info-Logs",
"SettingsTabLoggingEnableWarningLogs": "Aktiviere Warn-Logs",
"SettingsTabLoggingEnableErrorLogs": "Aktiviere Fehler-Logs",
"SettingsTabLoggingEnableTraceLogs": "Aktiviere Trace-Logs",
"SettingsTabLoggingEnableGuestLogs": "Aktiviere Gast-Logs",
"SettingsTabLoggingEnableFsAccessLogs": "Aktiviere Fs Zugriff-Logs",
"SettingsTabLoggingFsGlobalAccessLogMode": "Fs Globaler Zugriff-Log-Modus:",
"SettingsTabLoggingDeveloperOptions": "Entwickleroptionen (WARNUNG: Beeinträchtigt die Leistung)",
"SettingsTabLoggingOpenglLogLevel": "OpenGL Logstufe:",
"SettingsTabLoggingOpenglLogLevelNone": "Keine",
"SettingsTabLoggingOpenglLogLevelError": "Fehler",
"SettingsTabLoggingOpenglLogLevelPerformance": "Verlangsamungen",
"SettingsTabLoggingOpenglLogLevelAll": "Alle",
"SettingsTabLoggingEnableDebugLogs": "Aktiviere Debug-Log",
"SettingsTabInput": "Eingabe",
"SettingsTabInputEnableDockedMode": "Docked Modus",
"SettingsTabInputDirectKeyboardAccess": "Direkter Tastaturzugriff",
"SettingsButtonSave": "Speichern",
"SettingsButtonClose": "Schließen",
"SettingsButtonApply": "Übernehmen",
"ControllerSettingsPlayer": "Spieler",
"ControllerSettingsPlayer1": "Spieler 1",
"ControllerSettingsPlayer2": "Spieler 2",
"ControllerSettingsPlayer3": "Spieler 3",
"ControllerSettingsPlayer4": "Spieler 4",
"ControllerSettingsPlayer5": "Spieler 5",
"ControllerSettingsPlayer6": "Spieler 6",
"ControllerSettingsPlayer7": "Spieler 7",
"ControllerSettingsPlayer8": "Spieler 8",
"ControllerSettingsHandheld": "Handheld",
"ControllerSettingsInputDevice": "Eingabegerät",
"ControllerSettingsRefresh": "Aktualisieren",
"ControllerSettingsDeviceDisabled": "Deaktiviert",
"ControllerSettingsControllerType": "Controller Typ",
"ControllerSettingsControllerTypeHandheld": "Handheld",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "JoyCon Paar",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Links",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon Rechts",
"ControllerSettingsProfile": "Profil",
"ControllerSettingsProfileDefault": "Default",
"ControllerSettingsLoad": "Laden",
"ControllerSettingsAdd": "Hinzufügen",
"ControllerSettingsRemove": "Entfernen",
"ControllerSettingsButtons": "Aktionstasten",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Steuerkreuz",
"ControllerSettingsDPadUp": "Hoch",
"ControllerSettingsDPadDown": "Runter",
"ControllerSettingsDPadLeft": "Links",
"ControllerSettingsDPadRight": "Rechts",
"ControllerSettingsLStick": "Linker Analogstick",
"ControllerSettingsLStickButton": "L3",
"ControllerSettingsLStickUp": "Hoch",
"ControllerSettingsLStickDown": "Runter",
"ControllerSettingsLStickLeft": "Links",
"ControllerSettingsLStickRight": "Rechts",
"ControllerSettingsLStickStick": "Analogstick",
"ControllerSettingsLStickInvertXAxis": "Invertiert X-Achse",
"ControllerSettingsLStickInvertYAxis": "Invertiert Y-Achse",
"ControllerSettingsLStickDeadzone": "Deadzone:",
"ControllerSettingsRStick": "Rechter Analogstick",
"ControllerSettingsRStickButton": "R3",
"ControllerSettingsRStickUp": "Hoch",
"ControllerSettingsRStickDown": "Runter",
"ControllerSettingsRStickLeft": "Links",
"ControllerSettingsRStickRight": "Rechts",
"ControllerSettingsRStickStick": "Analogstick",
"ControllerSettingsRStickInvertXAxis": "Invertiert X-Achse",
"ControllerSettingsRStickInvertYAxis": "Invertiert Y-Achse",
"ControllerSettingsRStickDeadzone": "Deadzone:",
"ControllerSettingsTriggersLeft": "Linker Trigger",
"ControllerSettingsTriggersRight": "Rechter Trigger",
"ControllerSettingsTriggersButtonsLeft": "Linke Schultertaste",
"ControllerSettingsTriggersButtonsRight": "Rechte Schultertaste",
"ControllerSettingsTriggers": "Triggers",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Linke Aktionstasten",
"ControllerSettingsExtraButtonsRight": "Rechte Aktionstasten",
"ControllerSettingsMisc": "Verschiedenes",
"ControllerSettingsTriggerThreshold": "Empfindlichkeit:",
"ControllerSettingsMotion": "Bewegungssteuerung",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Aktiviere Bewegungssteuerung",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook kompatible Bewegungssteuerung",
"ControllerSettingsMotionControllerSlot": "Controller Slot:",
"ControllerSettingsMotionMirrorInput": "Spiegele Eingabe",
"ControllerSettingsMotionRightJoyConSlot": "Rechter JoyCon Slot:",
"ControllerSettingsMotionServerHost": "Server Host:",
"ControllerSettingsMotionGyroSensitivity": "Gyro Empfindlichkeit:",
"ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:",
"ControllerSettingsSave": "Speichern",
"ControllerSettingsClose": "Schließen",
"UserProfilesSelectedUserProfile": "Ausgewähltes Profil:",
"UserProfilesSaveProfileName": "Profilname speichern",
"UserProfilesChangeProfileImage": "Profilbild ändern",
"UserProfilesAvailableUserProfiles": "Verfügbare Profile:",
"UserProfilesAddNewProfile": "Neues Profil hinzufügen",
"UserProfilesDeleteSelectedProfile": "Ausgewähltes Profil löschen",
"UserProfilesClose": "Schließen",
"ProfileImageSelectionTitle": "Auswahl des Profilbildes",
"ProfileImageSelectionHeader": "Wähle ein Profilbild aus",
"ProfileImageSelectionNote": "Es kann ein eigenes Profilbild importiert werden oder ein Avatar aus der System-Firmware",
"ProfileImageSelectionImportImage": "Bilddatei importieren",
"ProfileImageSelectionSelectAvatar": "Firmware Avatar auswählen",
"InputDialogTitle": "Eingabe Dialog",
"InputDialogOk": "OK",
"InputDialogCancel": "Abbrechen",
"InputDialogAddNewProfileTitle": "Wähle den Profilnamen",
"InputDialogAddNewProfileHeader": "Bitte gebe einen Profilnamen ein",
"InputDialogAddNewProfileSubtext": "(Maximale Länge: {0})",
"AvatarChoose": "Bestätigen",
"AvatarSetBackgroundColor": "Hintergrundfarbe einstellen",
"AvatarClose": "Schließen",
"ControllerSettingsLoadProfileToolTip": "Lädt ein Profil",
"ControllerSettingsAddProfileToolTip": "Fügt ein Profil hinzu",
"ControllerSettingsRemoveProfileToolTip": "Entfernt ein Profil",
"ControllerSettingsSaveProfileToolTip": "Speichert ein Profil",
"MenuBarFileToolsTakeScreenshot": "Screenshot aufnehmen",
"MenuBarFileToolsHideUi": "Verstecke UI",
"GameListContextMenuToggleFavorite": "Als Favoriten hinzufügen/entfernen",
"GameListContextMenuToggleFavoriteToolTip": "Aktiviert den Favoriten-Status des Spiels",
"SettingsTabGeneralTheme": "Thema",
"SettingsTabGeneralThemeCustomTheme": "Verzeichnis für benutzerdefiniertes Thema",
"SettingsTabGeneralThemeBaseStyle": "Farbschema",
"SettingsTabGeneralThemeBaseStyleDark": "Dunkel",
"SettingsTabGeneralThemeBaseStyleLight": "Hell",
"SettingsTabGeneralThemeEnableCustomTheme": "Benutzerdefiniertes Thema",
"ButtonBrowse": "Durchsuchen",
"ControllerSettingsMotionConfigureCemuHookSettings": "CemuHook Motion konfigurieren",
"ControllerSettingsRumble": "Vibration",
"ControllerSettingsRumbleEnable": "Aktiviere Vibration",
"ControllerSettingsRumbleStrongMultiplier": "Starke Vibration - Multiplikator",
"ControllerSettingsRumbleWeakMultiplier": "Schwache Vibration - Multiplikator",
"DialogMessageSaveNotAvailableMessage": "Es existieren keine Speicherdaten für {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Soll Ryujinx Speicherdaten für dieses Spiel erstellen?",
"DialogConfirmationTitle": "Ryujinx - Bestätigung",
"DialogUpdaterTitle": "Ryujinx - Updater",
"DialogErrorTitle": "Ryujinx - Fehler",
"DialogWarningTitle": "Ryujinx - Warnung",
"DialogExitTitle": "Ryujinx - Beenden",
"DialogErrorMessage": "Ein Fehler ist aufgetreten",
"DialogExitMessage": "Ryujinx wirklich schließen?",
"DialogExitSubMessage": "Alle nicht gespeicherten Daten gehen verloren!",
"DialogMessageCreateSaveErrorMessage": "Es ist ein Fehler bei der Erstellung der angegebenen Speicherdaten aufgetreten: {0}",
"DialogMessageFindSaveErrorMessage": "Es ist ein Fehler beim Auffinden der angegebenen Speicherdaten aufgetreten: {0}",
"FolderDialogExtractTitle": "Wähle den Ordner, in welchen die Dateien entpackt werden sollen",
"DialogNcaExtractionMessage": "Extrahiert {0} abschnitt von {1}...",
"DialogNcaExtractionTitle": "Ryujinx - NCA-Abschnitt-Extraktor",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Extraktion fehlgeschlagen. Der Hauptheader der NCA war in der ausgewählten Datei nicht vorhanden.",
"DialogNcaExtractionCheckLogErrorMessage": "Extraktion fehlgeschlagen. Überprüfe die Logs für weitere Informationen.",
"DialogNcaExtractionSuccessMessage": "Extraktion erfolgreich abgeschlossen.",
"DialogUpdaterConvertFailedMessage": "Die Konvertierung der aktuellen Ryujinx Version ist fehlgeschlagen.",
"DialogUpdaterCancelUpdateMessage": "Download wird abgebrochen!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "Es wird bereits die aktuellste Version von Ryujinx benutzt",
"DialogUpdaterFailedToGetVersionMessage": "Bei dem Versuch Versionsinformationen von AppVeyor zu erhalten, ist ein Fehler aufgetreten ",
"DialogUpdaterConvertFailedAppveyorMessage": "Die von AppVeyor erhaltene Ryujinx Version konnte nicht konvertiert werden.",
"DialogUpdaterDownloadingMessage": "Update wird Heruntergeladen...",
"DialogUpdaterExtractionMessage": "Update wird entpackt...",
"DialogUpdaterRenamingMessage": "Update wird umbenannt...",
"DialogUpdaterAddingFilesMessage": "Update wird hinzugefügt...",
"DialogUpdaterCompleteMessage": "Update abgeschlossen!",
"DialogUpdaterRestartMessage": "Ryujinx jetzt neu starten?",
"DialogUpdaterArchNotSupportedMessage": "Eine nicht unterstützte Systemarchitektur wird benutzt!",
"DialogUpdaterArchNotSupportedSubMessage": "Nur x64 Systeme werden unterstützt!",
"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": "Für eine unterstütze Version: Ryujinx bitte von hier herunterladen https://ryujinx.org/",
"DialogRestartRequiredMessage": "Neustart erforderlich",
"DialogThemeRestartMessage": "Das Thema wurde gespeichert. Ein Neustart ist erforderlich, um das Thema anzuwenden.",
"DialogThemeRestartSubMessage": "Jetzt neu starten?",
"DialogFirmwareInstallEmbeddedMessage": "Die in diesem Spiel enthaltene Firmware installieren? (Firmware {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "Es wurde keine installierte Firmware gefunden, aber Ryujinx konnte die Firmware {0} aus dem bereitgestellten Spiel installieren.\nRyujinx wird nun gestartet.",
"DialogFirmwareNoFirmwareInstalledMessage": "Keine Firmware installiert",
"DialogFirmwareInstalledMessage": "Firmware {0} wurde installiert",
"DialogOpenSettingsWindowLabel": "Fenster-Einstellungen öffnen",
"DialogControllerAppletTitle": "Controller-Applet",
"DialogMessageDialogErrorExceptionMessage": "Fehler bei der Anzeige des Meldungs-Dialogs: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Fehler bei der Anzeige der Software-Tastatur: {0}",
"DialogErrorAppletErrorExceptionMessage": "Fehler beim Anzeigen des ErrorApplet-Dialogs: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nWeitere Informationen zur Behebung dieses Fehlers können in unserem Setup-Guide gefunden werden.",
"DialogUserErrorDialogTitle": "Ryujinx Fehler ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "Beim Abrufen von Informationen aus der API ist ein Fehler aufgetreten.",
"DialogAmiiboApiConnectErrorMessage": "Verbindung zum Amiibo API Server kann nicht hergestellt werden. Der Dienst ist möglicherweise nicht verfügbar oder es existiert keine Internetverbindung.",
"DialogProfileInvalidProfileErrorMessage": "Das Profil {0} ist mit dem aktuellen Eingabekonfigurationssystem nicht kompatibel.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "Das Standardprofil kann nicht überschrieben werden",
"DialogProfileDeleteProfileTitle": "Profil löschen",
"DialogProfileDeleteProfileMessage": "Diese Aktion kann nicht rückgängig gemacht werden. Wirklich fortfahren?",
"DialogWarning": "Warnung",
"DialogPPTCDeletionMessage": "Du bist dabei, den PPTC Cache zu löschen für :\n\n{0}\n\nWirklich fortfahren?",
"DialogPPTCDeletionErrorMessage": "Fehler bei der Löschung des PPTC Caches bei {0}: {1}",
"DialogShaderDeletionMessage": "Du bist dabei, den Shader Cache zu löschen für :\n\n{0}\n\nWirklich fortfahren?",
"DialogShaderDeletionErrorMessage": "Es ist ein Fehler bei der Löschung des Shader Caches bei {0}: {1} aufgetreten",
"DialogRyujinxErrorMessage": "Ein Fehler ist aufgetreten",
"DialogInvalidTitleIdErrorMessage": "UI Fehler: Das ausgewählte Spiel hat keine gültige Titel-ID",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Es wurde keine gültige System-Firmware gefunden in {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Installiere Firmware {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "Systemversion {0} wird jetzt installiert.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nDies wird die aktuelle Systemversion {0} ersetzen.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nMöchtest du fortfahren?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Firmware wird installiert...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Systemversion {0} wurde erfolgreich installiert.",
"DialogUserProfileDeletionWarningMessage": "Es können keine anderen Profile geöffnet werden, wenn das ausgewählte Profil gelöscht wird.",
"DialogUserProfileDeletionConfirmMessage": "Möchtest du das ausgewählte Profil löschen?",
"DialogControllerSettingsModifiedConfirmMessage": "Die aktuellen Controller-Einstellungen wurden aktualisiert.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Controller-Einstellungen speichern?",
"DialogDlcLoadNcaErrorMessage": "{0}. Fehlerhafte Datei: {1}",
"DialogDlcNoDlcErrorMessage": "Die angegebene Datei enthält keinen DLC für den ausgewählten Titel!",
"DialogPerformanceCheckLoggingEnabledMessage": "Es wurde die Debug Protokollierung aktiviert",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Um eine optimale Leistung zu erzielen, wird empfohlen, die Debug Protokollierung zu deaktivieren. Debug Protokollierung jetzt deaktivieren?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "Es wurde das Shader Dumping aktiviert, das nur von Entwicklern verwendet werden soll.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Für eine optimale Leistung wird empfohlen, das Shader Dumping zu deaktivieren. Shader Dumping jetzt deaktivieren?",
"DialogLoadAppGameAlreadyLoadedMessage": "Es wurde bereits ein Spiel gestartet",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Bitte beende die Emulation oder schließe den Emulator, vor dem Starten eines neuen Spiels",
"DialogUpdateAddUpdateErrorMessage": "Die angegebene Datei enthält keine Updates für den ausgewählten Titel!",
"DialogSettingsBackendThreadingWarningTitle": "Warnung - Render Threading",
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx muss muss neu gestartet werden, damit die Änderungen wirksam werden. Abhängig von dem Betriebssystem muss möglicherweise das Multithreading des Treibers manuell deaktiviert werden, wenn Ryujinx verwendet wird.",
"SettingsTabGraphicsFeaturesOptions": "Erweiterungen",
"SettingsTabGraphicsBackendMultithreading": "Grafikbackend Multithreading:",
"CommonAuto": "Auto",
"CommonOff": "Aus",
"CommonOn": "An",
"InputDialogYes": "Ja",
"InputDialogNo": "Nein",
"DialogProfileInvalidProfileNameErrorMessage": "Der Dateiname enthält ungültige Zeichen. Bitte erneut versuchen.",
"MenuBarOptionsPauseEmulation": "Pause",
"MenuBarOptionsResumeEmulation": "Fortsetzen",
"AboutUrlTooltipMessage": "Klicke hier, um die Ryujinx Website im Standardbrowser zu öffnen.",
"AboutDisclaimerMessage": "Ryujinx ist in keinster Weise weder mit Nintendo™, \nnoch mit deren Partnern verbunden.",
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) wird in unserer Amiibo \nEmulation benutzt.",
"AboutPatreonUrlTooltipMessage": "Klicke hier, um die Ryujinx Patreon Seite im Standardbrowser zu öffnen.",
"AboutGithubUrlTooltipMessage": "Klicke hier, um die Ryujinx GitHub Seite im Standardbrowser zu öffnen.",
"AboutDiscordUrlTooltipMessage": "Klicke hier, um eine Einladung zum Ryujinx Discord Server im Standardbrowser zu öffnen.",
"AboutTwitterUrlTooltipMessage": "Klicke hier, um die Ryujinx Twitter Seite im Standardbrowser zu öffnen.",
"AboutRyujinxAboutTitle": "Über:",
"AboutRyujinxAboutContent": "Ryujinx ist ein Nintendo Switch™ Emulator.\nBitte unterstütze uns auf Patreon.\nAuf Twitter oder Discord erfährst du alle Neuigkeiten.\nEntwickler, die an einer Mitarbeit interessiert sind, können auf GitHub oder Discord mehr erfahren.",
"AboutRyujinxMaintainersTitle": "Entwickelt von:",
"AboutRyujinxMaintainersContentTooltipMessage": "Klicke hier, um die Liste der Mitwirkenden im Standardbrowser zu öffnen.",
"AboutRyujinxSupprtersTitle": "Unterstützt auf Patreon von:",
"AmiiboSeriesLabel": "Amiibo Serie",
"AmiiboCharacterLabel": "Charakter",
"AmiiboScanButtonLabel": "Einscannen",
"AmiiboOptionsShowAllLabel": "Zeige alle Amiibos",
"AmiiboOptionsUsRandomTagLabel": "Hack: Benutze zufällige Tag-UUID",
"DlcManagerTableHeadingEnabledLabel": "Aktiviert",
"DlcManagerTableHeadingTitleIdLabel": "Title-ID",
"DlcManagerTableHeadingContainerPathLabel": "Container-Pfad",
"DlcManagerTableHeadingFullPathLabel": "Vollständiger-Pfad",
"DlcManagerRemoveAllButton": "Entferne alle",
"MenuBarOptionsChangeLanguage": "Sprache ändern",
"CommonSort": "Sortieren",
"CommonShowNames": "Spiel-Namen anzeigen",
"CommonFavorite": "Favoriten",
"OrderAscending": "Aufsteigend",
"OrderDescending": "Absteigend",
"SettingsTabGraphicsFeatures": "Erweiterungen",
"ErrorWindowTitle": "Fehler-Fenster",
"ToggleDiscordTooltip": "Aktiviert/Deaktiviert Discord Rich Presence",
"AddGameDirBoxTooltip": "Gibt das Spielverzeichnis an, das der Liste hinzuzufügt wird",
"AddGameDirTooltip": "Fügt ein neues Spielverzeichnis hinzu",
"RemoveGameDirTooltip": "Entfernt das ausgewähltes Spielverzeichnis",
"CustomThemeCheckTooltip": "Aktiviert/Deaktiviert die benutzerdefinierten Thema in dem GUI",
"CustomThemePathTooltip": " Gibt das Verzeichnis zum benutzerdefinierten GUI Thema an",
"CustomThemeBrowseTooltip": "Ermöglicht die Suche nach benutzerdefinierten GUI Thema",
"DockModeToggleTooltip": "Aktiviert/Deaktiviert den Docked Mode",
"DirectKeyboardTooltip": "Aktiviert/Deaktiviert den \"Direkter Tastaturzugriff (HID) Unterstützung\" (Ermöglicht die Benutzung der Tastaur als Eingabegerät in Spielen)",
"DirectMouseTooltip": "Aktiviert/Deaktiviert den \"Direkten Mauszugriff (HID) Unterstützung\" (Ermöglicht die Benutzung der Maus als Eingabegerät in Spielen)",
"RegionTooltip": "Ändert die Systemregion",
"LanguageTooltip": "Ändert die Systemsprache",
"TimezoneTooltip": "Ändert die Systemzeitzone",
"TimeTooltip": "Ändert die Systemzeit",
"VSyncToggleTooltip": "Aktiviert/Deaktiviert die Vertikale Synchronisierung",
"PptcToggleTooltip": "Aktiviert/Deaktiviert den PPTC",
"FsIntegrityToggleTooltip": "Aktiviert/Deaktiviert die Integritätsprüfung der Spieldateien",
"AudioBackendTooltip": "Ändert das Audio-Backend",
"MemoryManagerTooltip": "Ändert wie der Gastspeicher abgebildet wird und wie auf ihn zugegriffen wird. Beinflusst die Leistung der emulierten CPU erheblich.",
"MemoryManagerSoftwareTooltip": "Verwendung einer Software-Seitentabelle für die Adressumsetzung. Höchste Genauigkeit, aber langsamste Leistung.",
"MemoryManagerHostTooltip": "Direkte Zuordnung von Speicher im Host-Adressraum. Viel schnellere JIT-Kompilierung und Ausführung.",
"MemoryManagerUnsafeTooltip": "Direkte Zuordnung des Speichers, aber keine Maskierung der Adresse innerhalb des Gastadressraums vor dem Zugriff. Schneller, aber auf Kosten der Sicherheit. Die Gastanwendung kann von überall in Ryujinx auf den Speicher zugreifen, daher sollte in diesem Modus nur Programme ausgeführt werden denen vertraut wird.",
"DRamTooltip": "Erweitert den Speicher des emulierten Systems von 4 GB auf 6 GB",
"IgnoreMissingServicesTooltip": "Aktiviert/Deaktiviert die 'Ignoriere fehlende Dienste' Option",
"GraphicsBackendThreadingTooltip": "Aktiviert das Grafikbackend Multithreading",
"GalThreadingTooltip": "Führt Grafikbackendbefehle auf einem zweiten Thread aus. Ermöglicht Multithreading bei der Shader Kompilierung zur Laufzeit, reduziert Stottern und verbessert die Leistung bei Treibern ohne eigene Multithreading Unterstützung. Geringfügig abweichende Spitzenleistung bei Treibern mit Multithreading. Ryujinx muss möglicherweise neu gestartet werden, um das in den Treiber integrierte Multithreading korrekt zu deaktivieren, oder es muss manuell getan werden, um die beste Leistung zu erzielen.",
"ShaderCacheToggleTooltip": "Aktiviert/Deaktiviert Shader Cache",
"ResolutionScaleTooltip": "Wendet die Auflösungsskalierung auf anwendbare Render Ziele",
"ResolutionScaleEntryTooltip": "Fließkomma Auflösungsskalierung, wie 1,5.\n Bei nicht ganzzahligen Werten ist die Wahrscheinlichkeit größer, dass Probleme entstehen, die auch zum Absturz führen können.",
"AnisotropyTooltip": "Stufe der Anisotropen Filterung (Auf Auto setzen, um den vom Spiel geforderten Wert zu verwenden)",
"AspectRatioTooltip": "Auf das Renderer-Fenster angewandtes Seitenverhältnis.",
"ShaderDumpPathTooltip": "Grafik-Shader-Dump-Pfad",
"FileLogTooltip": "Aktiviert/Deaktiviert die Erstellung und Speicherung eines Logs",
"StubLogTooltip": "Aktiviert die Ausgabe von Stub-Logs in der Konsole",
"InfoLogTooltip": "Aktiviert die Ausgabe von Info-Logs in der Konsole",
"WarnLogTooltip": "Aktiviert die Ausgabe von Warn-Logs in der Konsole",
"TraceLogTooltip": "Aktiviert die Ausgabe von Trace-Log in der Konsole",
"ErrorLogTooltip": "Aktiviert die Ausgabe von Fehler-Logs in der Konsole",
"GuestLogTooltip": "Aktiviert die Ausgabe von Gast-Logs in der Konsole",
"FileAccessLogTooltip": "Aktiviert die Ausgabe von FS-Zugriff-Logs in der Konsole",
"FSAccessLogModeTooltip": "Aktiviert die Ausgabe des FS-Zugriff-Logs in der Konsole. Mögliche Modi sind 0-3",
"DeveloperOptionTooltip": "Mit Vorsicht verwenden",
"OpenGlLogLevel": "Erfordert die Aktivierung der entsprechenden Log-Level",
"DebugLogTooltip": "Aktiviert das Dokumentierern von Debug-Protokollmeldungen",
"LoadApplicationFileTooltip": "Öffnet die Dateiauswahl um Datei zu laden, welche mit der Switch kompatibel ist",
"LoadApplicationFolderTooltip": "Öffnet die Dateiauswahl um ein Spiel zu laden, welches mit der Switch kompatibel ist",
"OpenRyujinxFolderTooltip": "Öffnet den Ordner, der das Ryujinx Dateisystem enthält",
"OpenRyujinxLogsTooltip": "Öffnet den Ordner, in welchem die Logs gespeichert werden",
"ExitTooltip": "Beendet Ryujinx",
"OpenSettingsTooltip": "Öffnet das Einstellungsfenster",
"OpenProfileManagerTooltip": "Öffnet das Profilverwaltungsfenster",
"StopEmulationTooltip": "Beendet die Emulation des derzeitigen Spiels und kehrt zu der Spielauswahl zurück",
"CheckUpdatesTooltip": "Sucht nach Updates für Ryujinx",
"OpenAboutTooltip": "Öffnet das 'Über Ryujinx'-Fenster",
"GridSize": "Rastergröße",
"GridSizeTooltip": "Ändert die Größe der Rasterelemente",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Brasilianisches Portugiesisch",
"AboutRyujinxContributorsButtonHeader": "Alle Mitwirkenden anzeigen",
"SettingsTabSystemAudioVolume" : "Lautstärke: ",
"AudioVolumeTooltip": "Ändert die Lautstärke",
"SettingsTabSystemEnableInternetAccess": "Aktiviert den Gast-Internet-Zugang",
"EnableInternetAccessTooltip": "Aktiviert den Gast-Internet-Zugang. Die Anwendung verhält sich so, als ob die emulierte Switch-Konsole mit dem Internet verbunden wäre. Beachte, dass in einigen Fällen Anwendungen auch bei deaktivierter Option auf das Internet zugreifen können",
"GameListContextMenuManageCheatToolTip": "Öffnet den Cheat-Manager",
"GameListContextMenuManageCheat": "Cheats verwalten",
"ControllerSettingsStickRange": "Bereich",
"DialogStopEmulationTitle": "Ryujinx - Beende Emulation",
"DialogStopEmulationMessage": "Emulation wirklich beenden?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "Audio",
"SettingsTabNetwork": "Netzwerk",
"SettingsTabNetworkConnection": "Netwerkverbindung",
"SettingsTabGraphicsFrameRate": "Host Aktualisierungsrate:",
"SettingsTabGraphicsFrameRateTooltip": "Aktiviert die Host Aktualisierungsrate. Auf 0 setzen, um den Grenzwert aufzuheben.",
"SettingsTabCpuCache": "CPU-Cache",
"SettingsTabCpuMemory": "CPU-Speicher",
"DialogUpdaterFlatpakNotSupportedMessage": "Bitte Aktualisiere Ryujinx mit FlatHub",
"UpdaterDisabledWarningTitle": "Updater deaktiviert!",
"GameListContextMenuOpenSdModsDirectory": "Atmosphere-Mod-Verzeichnis öffnen",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Öffnet das alternative SD-Karten-Atmosphere-Verzeichnis, das die Mods der Anwendung enthält",
"ControllerSettingsRotate90": "Rotiert um 90°",
"IconSize": "Cover Größe",
"IconSizeTooltip": "Ändert die Größe der Spiel-Cover",
"MenuBarOptionsShowConsole": "Zeige Konsole",
"ShaderCachePurgeError": "Es ist ein Fehler beim löschen des Shader Caches aufgetreten bei {0}: {1}",
"UserErrorNoKeys": "Keys nicht gefunden",
"UserErrorNoFirmware": "Firmware nicht gefunden",
"UserErrorFirmwareParsingFailed": "Firmware-Analysierung-Fehler",
"UserErrorApplicationNotFound": "Anwendung nicht gefunden",
"UserErrorUnknown": "Unbekannter Fehler",
"UserErrorUndefined": "Undefinierter Fehler",
"UserErrorNoKeysDescription": "Ryujinx konnte deine 'prod.keys' Datei nicht finden",
"UserErrorNoFirmwareDescription": "Ryujinx konnte keine installierte Firmware finden!",
"UserErrorFirmwareParsingFailedDescription": "Ryujinx konnte die zu verfügung gestellte Firmware nicht analysieren. Ein möglicher Grund dafür sind veraltete keys.",
"UserErrorApplicationNotFoundDescription": "Ryujinx konnte keine valide Anwendung an dem gegeben Pfad finden.",
"UserErrorUnknownDescription": "Ein unbekannter Fehler ist aufgetreten!",
"UserErrorUndefinedDescription": "Ein undefinierter Fehler ist aufgetreten! Dies sollte nicht passieren. Bitte kontaktiere einen Entwickler!",
"OpenSetupGuideMessage": "Öffne den 'Setup Guide'",
"NoUpdate": "Kein Update",
"TitleUpdateVersionLabel": "Version {0} - {1}",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Bestätigung",
"FileDialogAllTypes": "Alle Typen",
"Never": "Niemals",
"SwkbdMinCharacters": "Muss mindestens {0} Zeichen lang sein",
"SwkbdMinRangeCharacters": "Muss {0}-{1} Zeichen lang sein",
"SoftwareKeyboard": "Software-Tastatur",
"DialogControllerAppletMessagePlayerRange": "Die Anwendung benötigt {0} Spieler mit:\n\nTYPEN: {1}\n\nSPIELER: {2}\n\n{3}Bitte öffne die Einstellungen und rekonfiguriere die Controller Einstellungen oder drücke auf schließen.",
"DialogControllerAppletMessage": "Die Anwendung benötigt genau {0} Speieler mit:\n\nTYPEN: {1}\n\nSPIELER: {2}\n\n{3}Bitte öffne die Einstellungen und rekonfiguriere die Controller Einstellungen oder drücke auf schließen.",
"DialogControllerAppletDockModeSet": "Der 'Docked Modus' ist ausgewählt. Handheld ist ebenfalls ungültig.\n\n",
"UpdaterRenaming": "Alte Dateien umbenennen...",
"UpdaterRenameFailed": "Der Updater konnte die folgende Datei nicht umbenennen: {0}",
"UpdaterAddingFiles": "Neue Dateien hinzufügen...",
"UpdaterExtracting": "Update extrahieren...",
"UpdaterDownloading": "Update herunterladen...",
"Game": "Spiel",
"Docked": "Docked",
"Handheld": "Handheld",
"ConnectionError": "Verbindungsfehler.",
"AboutPageDeveloperListMore": "{0} und mehr...",
"ApiError": "API Fehler.",
"LoadingHeading": "{0} wird gestartet",
"CompilingPPTC": "PTC wird kompiliert",
"CompilingShaders": "Shader werden kompiliert",
"SettingsTabGraphicsBackend" : "Grafik-Backend",
"GraphicsBackendTooltip" : "Ändert das Grafik-Backend"
}

View file

@ -0,0 +1,499 @@
{
"MenuBarFileOpenApplet": "Άνοιγμα Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Άνοιγμα του Mii Editor Applet σε Αυτόνομη λειτουργία",
"SettingsTabInputDirectMouseAccess": "Άμεση Πρόσβαση Ποντικιού",
"SettingsTabSystemMemoryManagerMode": "Λειτουργία Διαχείρισης Μνήμης:",
"SettingsTabSystemMemoryManagerModeSoftware": "Λογισμικό",
"SettingsTabSystemMemoryManagerModeHost": "Υπολογιστής (γρήγορο)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Χωρίς Ελέγχους (γρηγορότερο, μη ασφαλές)",
"MenuBarFile": "_Αρχείο",
"MenuBarFileOpenFromFile": "_Φόρτωση Αρχείου Εφαρμογής",
"MenuBarFileOpenUnpacked": "Φόρτωση Απακετάριστου _Παιχνιδιού",
"MenuBarFileOpenEmuFolder": "Άνοιγμα Φακέλου Ryujinx",
"MenuBarFileOpenLogsFolder": "Άνοιγμα Φακέλου Καταγραφής",
"MenuBarFileExit": "_Έξοδος",
"MenuBarOptions": "Επιλογές",
"MenuBarOptionsToggleFullscreen": "Λειτουργία Πλήρους Οθόνης",
"MenuBarOptionsStartGamesInFullscreen": "Εκκίνηση Παιχνιδιών σε Πλήρη Οθόνη",
"MenuBarOptionsStopEmulation": "Διακοπή Εξομοίωσης",
"MenuBarOptionsSettings": "_Ρυθμίσεις",
"MenuBarOptionsManageUserProfiles": "Διαχείριση Προφίλ _Χρηστών",
"MenuBarActions": "_Δράσεις",
"MenuBarOptionsSimulateWakeUpMessage": "Προσομοίωση Μηνύματος Αφύπνισης",
"MenuBarActionsScanAmiibo": "Σάρωση Amiibo",
"MenuBarTools": "Εργα_λεία",
"MenuBarToolsInstallFirmware": "Εγκατάσταση Firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Εγκατάσταση Firmware από XCI ή ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Εγκατάσταση Firmware από τοποθεσία",
"MenuBarHelp": "Βοήθεια",
"MenuBarHelpCheckForUpdates": "Έλεγχος για Ενημερώσεις",
"MenuBarHelpAbout": "Σχετικά με",
"MenuSearch": "Αναζήτηση...",
"GameListHeaderFavorite": "Αγαπημένο",
"GameListHeaderIcon": "Εικονίδιο",
"GameListHeaderApplication": "Όνομα",
"GameListHeaderDeveloper": "Προγραμματιστής",
"GameListHeaderVersion": "Έκδοση",
"GameListHeaderTimePlayed": "Χρόνος",
"GameListHeaderLastPlayed": "Παίχτηκε",
"GameListHeaderFileExtension": "Κατάληξη",
"GameListHeaderFileSize": "Μέγεθος",
"GameListHeaderPath": "Τοποθεσία",
"GameListContextMenuOpenUserSaveDirectory": "Άνοιγμα Τοποθεσίας Αποθήκευσης Χρήστη",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει την Αποθήκευση Χρήστη της εφαρμογής",
"GameListContextMenuOpenUserDeviceDirectory": "Άνοιγμα Τοποθεσίας Συσκευής Χρήστη",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει την Αποθήκευση Συσκευής της εφαρμογής",
"GameListContextMenuOpenUserBcatDirectory": "Άνοιγμα Τοποθεσίας BCAT",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει την Αποθήκευση BCAT της εφαρμογής",
"GameListContextMenuManageTitleUpdates": "Διαχείριση Ενημερώσεων Παιχνιδιού",
"GameListContextMenuManageTitleUpdatesToolTip": "Ανοίγει το παράθυρο διαχείρισης Ενημερώσεων Παιχνιδιού",
"GameListContextMenuManageDlc": "Διαχείριση DLC",
"GameListContextMenuManageDlcToolTip": "Ανοίγει το παράθυρο διαχείρισης DLC",
"GameListContextMenuOpenModsDirectory": "Άνοιγμα Τοποθεσίας Τροποποιήσεων",
"GameListContextMenuOpenModsDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει τις Τροποποιήσεις της εφαρμογής",
"GameListContextMenuCacheManagement": "Διαχείριση Προσωρινής Μνήμης",
"GameListContextMenuCacheManagementPurgePptc": "Εκκαθάριση Προσωρινής Μνήμης PPTC",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Διαγράφει την προσωρινή μνήμη PPTC της εφαρμογής",
"GameListContextMenuCacheManagementPurgeShaderCache": "Εκκαθάριση Προσωρινής Μνήμης Shader",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Διαγράφει την προσωρινή μνήμη Shader της εφαρμογής",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Άνοιγμα Τοποθεσίας PPTC",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει τη προσωρινή μνήμη PPTC της εφαρμογής",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Άνοιγμα τοποθεσίας προσωρινής μνήμης Shader",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Ανοίγει την τοποθεσία που περιέχει την προσωρινή μνήμη Shader της εφαρμογής",
"GameListContextMenuExtractData": "Εξαγωγή Δεδομένων",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Εξαγωγή της ενότητας ExeFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Εξαγωγή της ενότητας RomFS από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Εξαγωγή της ενότητας Logo από την τρέχουσα διαμόρφωση της εφαρμογής (συμπεριλαμβανομένου ενημερώσεων)",
"StatusBarGamesLoaded": "{0}/{1} Φορτωμένα Παιχνίδια",
"StatusBarSystemVersion": "Έκδοση Συστήματος: {0}",
"Settings": "Ρυθμίσεις",
"SettingsTabGeneral": "Εμφάνιση",
"SettingsTabGeneralGeneral": "Γενικά",
"SettingsTabGeneralEnableDiscordRichPresence": "Ενεργοποίηση Εμπλουτισμένης Παρουσίας Discord",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Έλεγχος για Ενημερώσεις στην Εκκίνηση",
"SettingsTabGeneralShowConfirmExitDialog": "Εμφάνιση διαλόγου \"Επιβεβαίωση Εξόδου\".",
"SettingsTabGeneralHideCursorOnIdle": "Απόκρυψη Δρομέα στην Αδράνεια",
"SettingsTabGeneralGameDirectories": "Τοποθεσίες παιχνιδιών",
"SettingsTabGeneralAdd": "Προσθήκη",
"SettingsTabGeneralRemove": "Αφαίρεση",
"SettingsTabSystem": "Σύστημα",
"SettingsTabSystemCore": "Πυρήνας",
"SettingsTabSystemSystemRegion": "Περιοχή Συστήματος:",
"SettingsTabSystemSystemRegionJapan": "Ιαπωνία",
"SettingsTabSystemSystemRegionUSA": "ΗΠΑ",
"SettingsTabSystemSystemRegionEurope": "Ευρώπη",
"SettingsTabSystemSystemRegionAustralia": "Αυστραλία",
"SettingsTabSystemSystemRegionChina": "Κίνα",
"SettingsTabSystemSystemRegionKorea": "Κορέα",
"SettingsTabSystemSystemRegionTaiwan": "Ταϊβάν",
"SettingsTabSystemSystemLanguage": "Γλώσσα Συστήματος:",
"SettingsTabSystemSystemLanguageJapanese": "Ιαπωνικά",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Αμερικάνικα Αγγλικά",
"SettingsTabSystemSystemLanguageFrench": "Γαλλικά",
"SettingsTabSystemSystemLanguageGerman": "Γερμανικά",
"SettingsTabSystemSystemLanguageItalian": "Ιταλικά",
"SettingsTabSystemSystemLanguageSpanish": "Ισπανικά",
"SettingsTabSystemSystemLanguageChinese": "Κινέζικα",
"SettingsTabSystemSystemLanguageKorean": "Κορεάτικα",
"SettingsTabSystemSystemLanguageDutch": "Ολλανδικά",
"SettingsTabSystemSystemLanguagePortuguese": "Πορτογαλικά",
"SettingsTabSystemSystemLanguageRussian": "Ρώσικα",
"SettingsTabSystemSystemLanguageTaiwanese": "Ταϊβανέζικα",
"SettingsTabSystemSystemLanguageBritishEnglish": "Βρετανικά Αγγλικά",
"SettingsTabSystemSystemLanguageCanadianFrench": "Καναδικά Γαλλικά",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Λατινοαμερικάνικα Ισπανικά",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Απλοποιημένα Κινέζικα",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Παραδοσιακά Κινεζικά",
"SettingsTabSystemSystemTimeZone": "Ζώνη Ώρας Συστήματος:",
"SettingsTabSystemSystemTime": "Ώρα Συστήματος:",
"SettingsTabSystemEnableVsync": "Ενεργοποίηση Κατακόρυφου Συγχρονισμού",
"SettingsTabSystemEnablePptc": "Ενεργοποίηση PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Ενεργοποίηση Ελέγχων Ακεραιότητας FS",
"SettingsTabSystemAudioBackend": "Backend Ήχου:",
"SettingsTabSystemAudioBackendDummy": "Απενεργοποιημένο",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Μικροδιορθώσεις",
"SettingsTabSystemHacksNote": " - Μπορεί να προκαλέσουν αστάθεια",
"SettingsTabSystemExpandDramSize": "Επέκταση μεγέθους DRAM στα 6GB",
"SettingsTabSystemIgnoreMissingServices": "Αγνόηση υπηρεσιών που λείπουν",
"SettingsTabGraphics": "Γραφικά",
"SettingsTabGraphicsEnhancements": "Βελτιώσεις",
"SettingsTabGraphicsEnableShaderCache": "Ενεργοποίηση Προσωρινής Μνήμης Shader",
"SettingsTabGraphicsAnisotropicFiltering": "Ανισότροπο Φιλτράρισμα:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Αυτόματο",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Κλίμακα Ανάλυσης:",
"SettingsTabGraphicsResolutionScaleCustom": "Προσαρμοσμένο (Δεν συνιστάται)",
"SettingsTabGraphicsResolutionScaleNative": "Εγγενής (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Αναλογία Απεικόνισης:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Έκταση σε όλο το παράθυρο",
"SettingsTabGraphicsDeveloperOptions": "Επιλογές Προγραμματιστή",
"SettingsTabGraphicsShaderDumpPath": "Τοποθεσία Shaders Γραφικών:",
"SettingsTabLogging": "Καταγραφή",
"SettingsTabLoggingLogging": "Καταγραφή",
"SettingsTabLoggingEnableLoggingToFile": "Ενεργοποίηση Καταγραφής Αρχείου",
"SettingsTabLoggingEnableStubLogs": "Ενεργοποίηση Καταγραφής Stub",
"SettingsTabLoggingEnableInfoLogs": "Ενεργοποίηση Καταγραφής Πληροφοριών",
"SettingsTabLoggingEnableWarningLogs": "Ενεργοποίηση Καταγραφής Προειδοποίησης",
"SettingsTabLoggingEnableErrorLogs": "Ενεργοποίηση Καταγραφής Σφαλμάτων",
"SettingsTabLoggingEnableTraceLogs": "Ενεργοποίηση Καταγραφής Ιχνών",
"SettingsTabLoggingEnableGuestLogs": "Ενεργοποίηση Καταγραφής Επισκεπτών",
"SettingsTabLoggingEnableFsAccessLogs": "Ενεργοποίηση Καταγραφής Πρόσβασης FS",
"SettingsTabLoggingFsGlobalAccessLogMode": "Λειτουργία Καταγραφής Καθολικής Πρόσβασης FS:",
"SettingsTabLoggingDeveloperOptions": "Επιλογές Προγραμματιστή (ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η απόδοση Θα μειωθεί)",
"SettingsTabLoggingOpenglLogLevel": "Επίπεδο Καταγραφής OpenGL:",
"SettingsTabLoggingOpenglLogLevelNone": "Κανένα",
"SettingsTabLoggingOpenglLogLevelError": "Σφάλμα",
"SettingsTabLoggingOpenglLogLevelPerformance": "Επιβραδύνσεις",
"SettingsTabLoggingOpenglLogLevelAll": "Όλα",
"SettingsTabLoggingEnableDebugLogs": "Ενεργοποίηση Αρχείων Καταγραφής Εντοπισμού Σφαλμάτων",
"SettingsTabInput": "Χειρισμός",
"SettingsTabInputEnableDockedMode": "Ενεργοποίηση Docked Mode",
"SettingsTabInputDirectKeyboardAccess": "Άμεση Πρόσβαση στο Πληκτρολόγιο",
"SettingsButtonSave": "Αποθήκευση",
"SettingsButtonClose": "Κλείσιμο",
"SettingsButtonApply": "Εφαρμογή",
"ControllerSettingsPlayer": "Παίχτης",
"ControllerSettingsPlayer1": "Παίχτης 1",
"ControllerSettingsPlayer2": "Παίχτης 2",
"ControllerSettingsPlayer3": "Παίχτης 3",
"ControllerSettingsPlayer4": "Παίχτης 4",
"ControllerSettingsPlayer5": "Παίχτης 5",
"ControllerSettingsPlayer6": "Παίχτης 6",
"ControllerSettingsPlayer7": "Παίχτης 7",
"ControllerSettingsPlayer8": "Παίχτης 8",
"ControllerSettingsHandheld": "Χειροκίνητο",
"ControllerSettingsInputDevice": "Συσκευή Χειρισμού",
"ControllerSettingsRefresh": "Ανανέωση",
"ControllerSettingsDeviceDisabled": "Απενεργοποιημένο",
"ControllerSettingsControllerType": "Τύπος Χειριστηρίου",
"ControllerSettingsControllerTypeHandheld": "Handheld",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "Ζεύγος JoyCon",
"ControllerSettingsControllerTypeJoyConLeft": "Αριστερό JoyCon",
"ControllerSettingsControllerTypeJoyConRight": "Δεξί JoyCon",
"ControllerSettingsProfile": "Προφίλ",
"ControllerSettingsProfileDefault": "Προκαθορισμένο",
"ControllerSettingsLoad": "Φόρτωση",
"ControllerSettingsAdd": "Προσθήκη",
"ControllerSettingsRemove": "Αφαίρεση",
"ControllerSettingsButtons": "Κουμπιά",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Κατευθυντικό Pad",
"ControllerSettingsDPadUp": "Πάνω",
"ControllerSettingsDPadDown": "Κάτω",
"ControllerSettingsDPadLeft": "Αριστερά",
"ControllerSettingsDPadRight": "Δεξιά",
"ControllerSettingsLStick": "Αριστερός Μοχλός",
"ControllerSettingsLStickButton": "Κουμπί",
"ControllerSettingsLStickUp": "Πάνω",
"ControllerSettingsLStickDown": "Κάτω",
"ControllerSettingsLStickLeft": "Αριστερά",
"ControllerSettingsLStickRight": "Δεξιά",
"ControllerSettingsLStickStick": "Stick",
"ControllerSettingsLStickInvertXAxis": "Αντιστροφή Μοχλού X",
"ControllerSettingsLStickInvertYAxis": "Αντιστροφή Μοχλού Y",
"ControllerSettingsLStickDeadzone": "Νεκρή Ζώνη:",
"ControllerSettingsRStick": "Δεξιός Μοχλός",
"ControllerSettingsRStickButton": "Κουμπί",
"ControllerSettingsRStickUp": "Πάνω",
"ControllerSettingsRStickDown": "Κάτω",
"ControllerSettingsRStickLeft": "Αριστερά",
"ControllerSettingsRStickRight": "Δεξιά",
"ControllerSettingsRStickStick": "Stick",
"ControllerSettingsRStickInvertXAxis": "Αντιστροφή Μοχλού X",
"ControllerSettingsRStickInvertYAxis": "Αντιστροφή Μοχλού Y",
"ControllerSettingsRStickDeadzone": "Νεκρή Ζώνη:",
"ControllerSettingsTriggersLeft": "Αριστερή Σκανδάλη",
"ControllerSettingsTriggersRight": "Δεξιά Σκανδάλη",
"ControllerSettingsTriggersButtonsLeft": "Αριστερά Κουμπιά Σκανδάλης",
"ControllerSettingsTriggersButtonsRight": "Δεξιά Κουμπιά Σκανδάλης",
"ControllerSettingsTriggers": "Σκανδάλες",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Αριστερά Κουμπιά",
"ControllerSettingsExtraButtonsRight": "Δεξιά Κουμπιά",
"ControllerSettingsMisc": "Διάφορα",
"ControllerSettingsTriggerThreshold": "Κατώφλι Σκανδάλης:",
"ControllerSettingsMotion": "Κίνηση",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Ενεργοποίηση Κίνησης",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Κίνηση συμβατή με CemuHook",
"ControllerSettingsMotionControllerSlot": "Υποδοχή Χειριστηρίου:",
"ControllerSettingsMotionMirrorInput": "Καθρεπτισμός Χειρισμού",
"ControllerSettingsMotionRightJoyConSlot": "Δεξιά Υποδοχή JoyCon:",
"ControllerSettingsMotionServerHost": "Κεντρικός Υπολογιστής Διακομιστή:",
"ControllerSettingsMotionGyroSensitivity": "Ευαισθησία Γυροσκοπίου:",
"ControllerSettingsMotionGyroDeadzone": "Νεκρή Ζώνη Γυροσκοπίου:",
"ControllerSettingsSave": "Αποθήκευση",
"ControllerSettingsClose": "Κλείσιμο",
"UserProfilesSelectedUserProfile": "Επιλεγμένο Προφίλ Χρήστη:",
"UserProfilesSaveProfileName": "Αποθήκευση Ονόματος Προφίλ",
"UserProfilesChangeProfileImage": "Αλλαγή Εικόνας Προφίλ",
"UserProfilesAvailableUserProfiles": "Διαθέσιμα Προφίλ Χρηστών:",
"UserProfilesAddNewProfile": "Προσθήκη Νέου Προφίλ",
"UserProfilesDeleteSelectedProfile": "Διαγραφή Επιλεγμένου Προφίλ",
"UserProfilesClose": "Κλείσιμο",
"ProfileImageSelectionTitle": "Επιλογή Εικόνας Προφίλ",
"ProfileImageSelectionHeader": "Επιλέξτε μία Εικόνα Προφίλ",
"ProfileImageSelectionNote": "Μπορείτε να εισαγάγετε μία προσαρμοσμένη εικόνα προφίλ ή να επιλέξετε ένα avatar από το Firmware",
"ProfileImageSelectionImportImage": "Εισαγωγή Αρχείου Εικόνας",
"ProfileImageSelectionSelectAvatar": "Επιλέξτε Avatar από Firmware",
"InputDialogTitle": "Διάλογος Εισαγωγής",
"InputDialogOk": "OK",
"InputDialogCancel": "Ακύρωση",
"InputDialogAddNewProfileTitle": "Επιλογή Ονόματος Προφίλ",
"InputDialogAddNewProfileHeader": "Εισαγωγή Ονόματος Προφίλ",
"InputDialogAddNewProfileSubtext": "(Σύνολο Χαρακτήρων: {0})",
"AvatarChoose": "Επιλογή",
"AvatarSetBackgroundColor": "Ορισμός Χρώματος Φόντου",
"AvatarClose": "Κλείσιμο",
"ControllerSettingsLoadProfileToolTip": "Φόρτωση Προφίλ",
"ControllerSettingsAddProfileToolTip": "Προσθήκη Προφίλ",
"ControllerSettingsRemoveProfileToolTip": "Κατάργηση Προφίλ",
"ControllerSettingsSaveProfileToolTip": "Αποθήκευση Προφίλ",
"MenuBarFileToolsTakeScreenshot": "Λήψη Στιγμιότυπου",
"MenuBarFileToolsHideUi": "Απόκρυψη UI",
"GameListContextMenuToggleFavorite": "Εναλλαγή Αγαπημένου",
"GameListContextMenuToggleFavoriteToolTip": "Εναλλαγή της Κατάστασης Αγαπημένο του Παιχνιδιού",
"SettingsTabGeneralTheme": "Θέμα",
"SettingsTabGeneralThemeCustomTheme": "Προσαρμοσμένη Τοποθεσία Θέματος",
"SettingsTabGeneralThemeBaseStyle": "Βασικό Στυλ",
"SettingsTabGeneralThemeBaseStyleDark": "Σκούρο",
"SettingsTabGeneralThemeBaseStyleLight": "Ανοιχτό",
"SettingsTabGeneralThemeEnableCustomTheme": "Ενεργοποίηση Προσαρμοσμένου Θέματος",
"ButtonBrowse": "Αναζήτηση",
"ControllerSettingsMotionConfigureCemuHookSettings": "Ρύθμιση Παραμέτρων Κίνησης CemuHook",
"ControllerSettingsRumble": "Δόνηση",
"ControllerSettingsRumbleEnable": "Ενεργοποίηση Δόνησης",
"ControllerSettingsRumbleStrongMultiplier": "Ισχυρός Πολλαπλασιαστής Δόνησης",
"ControllerSettingsRumbleWeakMultiplier": "Αδύναμος Πολλαπλασιαστής Δόνησης",
"DialogMessageSaveNotAvailableMessage": "Δεν υπάρχουν αποθηκευμένα δεδομένα για το {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Θέλετε να αποθηκεύσετε δεδομένα για αυτό το παιχνίδι;",
"DialogConfirmationTitle": "Ryujinx - Επιβεβαίωση",
"DialogUpdaterTitle": "Ryujinx - Ενημερωτής",
"DialogErrorTitle": "Ryujinx - Σφάλμα",
"DialogWarningTitle": "Ryujinx - Προειδοποίηση",
"DialogExitTitle": "Ryujinx - Έξοδος",
"DialogErrorMessage": "Το Ryujinx αντιμετώπισε σφάλμα",
"DialogExitMessage": "Είστε βέβαιοι ότι θέλετε να κλείσετε το Ryujinx;",
"DialogExitSubMessage": "Όλα τα μη αποθηκευμένα δεδομένα θα χαθούν!",
"DialogMessageCreateSaveErrorMessage": "Σφάλμα κατά τη δημιουργία των αποθηκευμένων δεδομένων: {0}",
"DialogMessageFindSaveErrorMessage": "Σφάλμα κατά την εύρεση των αποθηκευμένων δεδομένων: {0}",
"FolderDialogExtractTitle": "Επιλέξτε τον φάκελο στον οποίο θέλετε να εξαγάγετε",
"DialogNcaExtractionMessage": "Εξαγωγή ενότητας {0} από {1}...",
"DialogNcaExtractionTitle": "Ryujinx - NCA Εξαγωγέας Τμημάτων",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Αποτυχία εξαγωγής. Η κύρια NCA δεν υπήρχε στο επιλεγμένο αρχείο.",
"DialogNcaExtractionCheckLogErrorMessage": "Αποτυχία εξαγωγής. Διαβάστε το αρχείο καταγραφής για περισσότερες πληροφορίες.",
"DialogNcaExtractionSuccessMessage": "Η εξαγωγή ολοκληρώθηκε με επιτυχία.",
"DialogUpdaterConvertFailedMessage": "Αποτυχία μετατροπής της τρέχουσας έκδοσης Ryujinx.",
"DialogUpdaterCancelUpdateMessage": "Ακύρωση Ενημέρωσης!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "Χρησιμοποιείτε ήδη την πιο ενημερωμένη έκδοση του Ryujinx!",
"DialogUpdaterFailedToGetVersionMessage": "Σφάλμα κατά την προσπάθεια λήψης έκδοσης από το GitHub Release. Αυτό μπορεί να προκληθεί εάν μία νέα έκδοση συντάσσεται από το GitHub Actions. Δοκιμάστε ξανά σε λίγα λεπτά.",
"DialogUpdaterConvertFailedGithubMessage": "Αποτυχία μετατροπής της ληφθείσας έκδοσης Ryujinx από την έκδοση GitHub.",
"DialogUpdaterDownloadingMessage": "Λήψη Ενημέρωσης...",
"DialogUpdaterExtractionMessage": "Εξαγωγή Ενημέρωσης...",
"DialogUpdaterRenamingMessage": "Μετονομασία Ενημέρωσης...",
"DialogUpdaterAddingFilesMessage": "Προσθήκη Νέας Ενημέρωσης...",
"DialogUpdaterCompleteMessage": "Η Ενημέρωση Ολοκληρώθηκε!",
"DialogUpdaterRestartMessage": "Θέλετε να επανεκκινήσετε το Ryujinx τώρα;",
"DialogUpdaterArchNotSupportedMessage": "Δεν υπάρχει υποστηριζόμενη αρχιτεκτονική συστήματος!",
"DialogUpdaterArchNotSupportedSubMessage": "(Υποστηρίζονται μόνο συστήματα x64!)",
"DialogUpdaterNoInternetMessage": "Δεν είστε συνδεδεμένοι στο Διαδίκτυο!",
"DialogUpdaterNoInternetSubMessage": "Επαληθεύστε ότι έχετε σύνδεση στο Διαδίκτυο που λειτουργεί!",
"DialogUpdaterDirtyBuildMessage": "Δεν μπορείτε να ενημερώσετε μία Πρόχειρη Έκδοση του Ryujinx!",
"DialogUpdaterDirtyBuildSubMessage": "Κάντε λήψη του Ryujinx στη διεύθυνση https://ryujinx.org/ εάν αναζητάτε μία υποστηριζόμενη έκδοση.",
"DialogRestartRequiredMessage": "Απαιτείται Επανεκκίνηση",
"DialogThemeRestartMessage": "Το θέμα έχει αποθηκευτεί. Απαιτείται επανεκκίνηση για την εφαρμογή του θέματος.",
"DialogThemeRestartSubMessage": "Θέλετε να κάνετε επανεκκίνηση",
"DialogFirmwareInstallEmbeddedMessage": "Θα θέλατε να εγκαταστήσετε το Firmware που είναι ενσωματωμένο σε αυτό το παιχνίδι; (Firmware {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "Δεν βρέθηκε εγκατεστημένο Firmware, αλλά το Ryujinx μπόρεσε να εγκαταστήσει το Firmware {0} από το παρεχόμενο παιχνίδι.\nΟ εξομοιωτής θα ξεκινήσει τώρα.",
"DialogFirmwareNoFirmwareInstalledMessage": "Δεν έχει εγκατασταθεί Firmware",
"DialogFirmwareInstalledMessage": "Το Firmware {0} εγκαταστάθηκε",
"DialogOpenSettingsWindowLabel": "Άνοιγμα Παραθύρου Ρυθμίσεων",
"DialogControllerAppletTitle": "Applet Χειρισμού",
"DialogMessageDialogErrorExceptionMessage": "Σφάλμα εμφάνισης του διαλόγου Μηνυμάτων: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Σφάλμα εμφάνισης Λογισμικού Πληκτρολογίου: {0}",
"DialogErrorAppletErrorExceptionMessage": "Σφάλμα εμφάνισης του διαλόγου ErrorApplet: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nΓια πληροφορίες σχετικά με τον τρόπο διόρθωσης του σφάλματος, ακολουθήστε τον Οδηγό Εγκατάστασης.",
"DialogUserErrorDialogTitle": "Σφάλμα Ryujinx ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "Παρουσιάστηκε σφάλμα κατά την ανάκτηση πληροφοριών από το API.",
"DialogAmiiboApiConnectErrorMessage": "Δεν είναι δυνατή η σύνδεση με τον διακομιστή Amiibo API. Η υπηρεσία μπορεί να είναι εκτός λειτουργίας ή μπορεί να χρειαστεί να επαληθεύσετε ότι έχετε ενεργή σύνδεσή στο Διαδίκτυο.",
"DialogProfileInvalidProfileErrorMessage": "Το προφίλ {0} δεν είναι συμβατό με το τρέχον σύστημα χειρισμού.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "Το προεπιλεγμένο προφίλ δεν μπορεί να αντικατασταθεί",
"DialogProfileDeleteProfileTitle": "Διαγραφή Προφίλ",
"DialogProfileDeleteProfileMessage": "Αυτή η ενέργεια είναι μη αναστρέψιμη, είστε βέβαιοι ότι θέλετε να συνεχίσετε;",
"DialogWarning": "Προειδοποίηση",
"DialogPPTCDeletionMessage": "Πρόκειται να διαγράψετε την προσωρινή μνήμη PPTC για :\n\n{0}\n\nΕίστε βέβαιοι ότι θέλετε να συνεχίσετε;",
"DialogPPTCDeletionErrorMessage": "Σφάλμα κατά την εκκαθάριση προσωρινής μνήμης PPTC στο {0}: {1}",
"DialogShaderDeletionMessage": "Πρόκειται να διαγράψετε την προσωρινή μνήμη Shader για :\n\n{0}\n\nΕίστε βέβαιοι ότι θέλετε να συνεχίσετε;",
"DialogShaderDeletionErrorMessage": "Σφάλμα κατά την εκκαθάριση προσωρινής μνήμης Shader στο {0}: {1}",
"DialogRyujinxErrorMessage": "Το Ryujinx αντιμετώπισε σφάλμα",
"DialogInvalidTitleIdErrorMessage": "Σφάλμα UI: Το επιλεγμένο παιχνίδι δεν έχει έγκυρο αναγνωριστικό τίτλου",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Δεν βρέθηκε έγκυρο Firmware συστήματος στο {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Εγκατάσταση Firmware {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "Θα εγκατασταθεί η έκδοση συστήματος {0}.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nΑυτό θα αντικαταστήσει την τρέχουσα έκδοση συστήματος {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nΘέλετε να συνεχίσετε;",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Εγκατάσταση Firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Η έκδοση συστήματος {0} εγκαταστάθηκε με επιτυχία.",
"DialogUserProfileDeletionWarningMessage": "Δεν θα υπάρχουν άλλα προφίλ εάν διαγραφεί το επιλεγμένο",
"DialogUserProfileDeletionConfirmMessage": "Θέλετε να διαγράψετε το επιλεγμένο προφίλ",
"DialogControllerSettingsModifiedConfirmMessage": "Οι τρέχουσες ρυθμίσεις χειρισμού έχουν ενημερωθεί.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Θέλετε να αποθηκεύσετε;",
"DialogDlcLoadNcaErrorMessage": "{0}. Σφάλμα Αρχείου: {1}",
"DialogDlcNoDlcErrorMessage": "Το αρχείο δεν περιέχει DLC για τον επιλεγμένο τίτλο!",
"DialogPerformanceCheckLoggingEnabledMessage": "Έχετε ενεργοποιημένη την καταγραφή εντοπισμού σφαλμάτων, η οποία έχει σχεδιαστεί για χρήση μόνο από προγραμματιστές.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Για βέλτιστη απόδοση, συνιστάται η απενεργοποίηση καταγραφής εντοπισμού σφαλμάτων. Θέλετε να απενεργοποιήσετε την καταγραφή τώρα;",
"DialogPerformanceCheckShaderDumpEnabledMessage": "Έχετε ενεργοποιήσει το Shader Dumping, το οποίο έχει σχεδιαστεί για χρήση μόνο από προγραμματιστές.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Για βέλτιστη απόδοση, συνιστάται να απενεργοποιήσετε το Shader Dumping. Θέλετε να απενεργοποιήσετε τώρα το Shader Dumping;",
"DialogLoadAppGameAlreadyLoadedMessage": "Ένα παιχνίδι έχει ήδη φορτωθεί",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Σταματήστε την εξομοίωση ή κλείστε τον εξομοιωτή πριν ξεκινήσετε ένα άλλο παιχνίδι.",
"DialogUpdateAddUpdateErrorMessage": "Το αρχείο δεν περιέχει ενημέρωση για τον επιλεγμένο τίτλο!",
"DialogSettingsBackendThreadingWarningTitle": "Προειδοποίηση - Backend Threading",
"DialogSettingsBackendThreadingWarningMessage": "Το Ryujinx πρέπει να επανεκκινηθεί αφού αλλάξει αυτή η επιλογή για να εφαρμοστεί πλήρως. Ανάλογα με την πλατφόρμα σας, μπορεί να χρειαστεί να απενεργοποιήσετε με μη αυτόματο τρόπο το multithreading του ίδιου του προγράμματος οδήγησης όταν χρησιμοποιείτε το Ryujinx.",
"SettingsTabGraphicsFeaturesOptions": "Χαρακτηριστικά",
"SettingsTabGraphicsBackendMultithreading": "Πολυνηματική Επεξεργασία Γραφικών:",
"CommonAuto": "Αυτόματο",
"CommonOff": "Ανενεργό",
"CommonOn": "Ενεργό",
"InputDialogYes": "Ναί",
"InputDialogNo": "Όχι",
"DialogProfileInvalidProfileNameErrorMessage": "Το όνομα αρχείου περιέχει μη έγκυρους χαρακτήρες. Παρακαλώ προσπαθήστε ξανά.",
"MenuBarOptionsPauseEmulation": "Παύση",
"MenuBarOptionsResumeEmulation": "Συνέχιση",
"AboutUrlTooltipMessage": "Κάντε κλικ για να ανοίξετε τον ιστότοπο Ryujinx στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"AboutDisclaimerMessage": "Το Ryujinx δεν είναι συνδεδεμένο με τη Nintendo™,\nούτε με κανέναν από τους συνεργάτες της, με οποιονδήποτε τρόπο.",
"AboutAmiiboDisclaimerMessage": "Το AmiiboAPI (www.amiiboapi.com) χρησιμοποιείται\nστην προσομοίωση Amiibo.",
"AboutPatreonUrlTooltipMessage": "Κάντε κλικ για να ανοίξετε τη σελίδα Ryujinx Patreon στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"AboutGithubUrlTooltipMessage": "Κάντε κλικ για να ανοίξετε τη σελίδα Ryujinx GitHub στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"AboutDiscordUrlTooltipMessage": "Κάντε κλικ για να ανοίξετε μία πρόσκληση στον διακομιστή Ryujinx Discord στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"AboutTwitterUrlTooltipMessage": "Κάντε κλικ για να ανοίξετε τη σελίδα Ryujinx Twitter στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"AboutRyujinxAboutTitle": "Σχετικά με:",
"AboutRyujinxAboutContent": "Το Ryujinx είναι ένας εξομοιωτής για το Nintendo Switch™.\nΥποστηρίξτε μας στο Patreon.\nΛάβετε όλα τα τελευταία νέα στο Twitter ή στο Discord.\nΟι προγραμματιστές που ενδιαφέρονται να συνεισφέρουν μπορούν να μάθουν περισσότερα στο GitHub ή στο Discord μας.",
"AboutRyujinxMaintainersTitle": "Συντηρείται από:",
"AboutRyujinxMaintainersContentTooltipMessage": "Κάντε κλικ για να ανοίξετε τη σελίδα Συνεισφέροντες στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"AboutRyujinxSupprtersTitle": "Υποστηρίζεται στο Patreon από:",
"AmiiboSeriesLabel": "Σειρά Amiibo",
"AmiiboCharacterLabel": "Χαρακτήρας",
"AmiiboScanButtonLabel": "Σαρώστε το",
"AmiiboOptionsShowAllLabel": "Εμφάνιση όλων των Amiibo",
"AmiiboOptionsUsRandomTagLabel": "Hack: Χρησιμοποιήστε τυχαίο αναγνωριστικό UUID",
"DlcManagerTableHeadingEnabledLabel": "Ενεργοποιήθηκε",
"DlcManagerTableHeadingTitleIdLabel": "Αναγνωριστικό τίτλου",
"DlcManagerTableHeadingContainerPathLabel": "Τοποθεσία DLC",
"DlcManagerTableHeadingFullPathLabel": "Πλήρης τοποθεσία",
"DlcManagerRemoveAllButton": "Αφαίρεση όλων",
"MenuBarOptionsChangeLanguage": "Αλλαξε γλώσσα",
"CommonSort": "Κατάταξη",
"CommonShowNames": "Εμφάνιση ονομάτων",
"CommonFavorite": "Αγαπημένα",
"OrderAscending": "Αύξουσα",
"OrderDescending": "Φθίνουσα",
"SettingsTabGraphicsFeatures": "Χαρακτηριστικά",
"ErrorWindowTitle": "Παράθυρο σφάλματος",
"ToggleDiscordTooltip": "Ενεργοποιεί ή απενεργοποιεί την Εμπλουτισμένη Παρουσία σας στο Discord",
"AddGameDirBoxTooltip": "Εισαγάγετε μία τοποθεσία παιχνιδιών για προσθήκη στη λίστα",
"AddGameDirTooltip": "Προσθέστε μία τοποθεσία παιχνιδιών στη λίστα",
"RemoveGameDirTooltip": "Αφαιρέστε την επιλεγμένη τοποθεσία παιχνιδιών",
"CustomThemeCheckTooltip": "Ενεργοποίηση ή απενεργοποίηση προσαρμοσμένων θεμάτων στο GUI",
"CustomThemePathTooltip": "Διαδρομή προς το προσαρμοσμένο θέμα GUI",
"CustomThemeBrowseTooltip": "Αναζητήστε ένα προσαρμοσμένο θέμα GUI",
"DockModeToggleTooltip": "Ενεργοποιήστε ή απενεργοποιήστε τη λειτουργία σύνδεσης",
"DirectKeyboardTooltip": "Ενεργοποίηση ή απενεργοποίηση της \"υποστήριξης άμεσης πρόσβασης πληκτρολογίου (HID)\" (Παρέχει πρόσβαση στα παιχνίδια στο πληκτρολόγιό σας ως συσκευή εισαγωγής κειμένου)",
"DirectMouseTooltip": "Ενεργοποίηση ή απενεργοποίηση της \"υποστήριξης άμεσης πρόσβασης ποντικιού (HID)\" (Παρέχει πρόσβαση στα παιχνίδια στο ποντίκι σας ως συσκευή κατάδειξης)",
"RegionTooltip": "Αλλαγή Περιοχής Συστήματος",
"LanguageTooltip": "Αλλαγή Γλώσσας Συστήματος",
"TimezoneTooltip": "Αλλαγή Ζώνης Ώρας Συστήματος",
"TimeTooltip": "Αλλαγή Ώρας Συστήματος",
"VSyncToggleTooltip": "Ενεργοποιεί ή απενεργοποιεί τον κατακόρυφο συγχρονισμό",
"PptcToggleTooltip": "Ενεργοποιεί ή απενεργοποιεί το PPTC",
"FsIntegrityToggleTooltip": "Ενεργοποιεί τους ελέγχους ακεραιότητας σε αρχεία περιεχομένου παιχνιδιού",
"AudioBackendTooltip": "Αλλαγή ήχου υποστήριξης",
"MemoryManagerTooltip": "Αλλάξτε τον τρόπο αντιστοίχισης και πρόσβασης στη μνήμη επισκέπτη. Επηρεάζει σε μεγάλο βαθμό την απόδοση της προσομοίωσης της CPU.",
"MemoryManagerSoftwareTooltip": "Χρησιμοποιήστε έναν πίνακα σελίδων λογισμικού για τη μετάφραση διευθύνσεων. Υψηλότερη ακρίβεια αλλά πιο αργή απόδοση.",
"MemoryManagerHostTooltip": "Απευθείας αντιστοίχιση της μνήμης στον χώρο διευθύνσεων υπολογιστή υποδοχής. Πολύ πιο γρήγορη μεταγλώττιση και εκτέλεση JIT.",
"MemoryManagerUnsafeTooltip": "Απευθείας χαρτογράφηση της μνήμης, αλλά μην καλύπτετε τη διεύθυνση εντός του χώρου διευθύνσεων επισκέπτη πριν από την πρόσβαση. Πιο γρήγορα, αλλά με κόστος ασφάλειας. Η εφαρμογή μπορεί να έχει πρόσβαση στη μνήμη από οπουδήποτε στο Ryujinx, επομένως εκτελείτε μόνο προγράμματα που εμπιστεύεστε με αυτήν τη λειτουργία.",
"DRamTooltip": "Επεκτείνει την ποσότητα της μνήμης στο εξομοιούμενο σύστημα από 4 GB σε 6 GB",
"IgnoreMissingServicesTooltip": "Ενεργοποίηση ή απενεργοποίηση της αγνοώησης για υπηρεσίες που λείπουν",
"GraphicsBackendThreadingTooltip": "Ενεργοποίηση Πολυνηματικής Επεξεργασίας Γραφικών",
"GalThreadingTooltip": "Εκτελεί εντολές γραφικών σε ένα δεύτερο νήμα. Επιτρέπει την πολυνηματική μεταγλώττιση Shader σε χρόνο εκτέλεσης, μειώνει το τρεμόπαιγμα και βελτιώνει την απόδοση των προγραμμάτων οδήγησης χωρίς τη δική τους υποστήριξη πολλαπλών νημάτων. Ποικίλες κορυφαίες επιδόσεις σε προγράμματα οδήγησης με multithreading. Μπορεί να χρειαστεί επανεκκίνηση του Ryujinx για να απενεργοποιήσετε σωστά την ενσωματωμένη λειτουργία πολλαπλών νημάτων του προγράμματος οδήγησης ή ίσως χρειαστεί να το κάνετε χειροκίνητα για να έχετε την καλύτερη απόδοση.",
"ShaderCacheToggleTooltip": "Ενεργοποιεί ή απενεργοποιεί την Προσωρινή Μνήμη Shader",
"ResolutionScaleTooltip": "Κλίμακα ανάλυσης που εφαρμόστηκε σε ισχύοντες στόχους απόδοσης",
"ResolutionScaleEntryTooltip": "Κλίμακα ανάλυσης κινητής υποδιαστολής, όπως 1,5. Οι μη αναπόσπαστες τιμές είναι πιθανό να προκαλέσουν προβλήματα ή σφάλματα.",
"AnisotropyTooltip": "Επίπεδο Ανισότροπου Φιλτραρίσματος (ρυθμίστε το στο Αυτόματο για να χρησιμοποιηθεί η τιμή που ζητήθηκε από το παιχνίδι)",
"AspectRatioTooltip": "Λόγος διαστάσεων που εφαρμόστηκε στο παράθυρο απόδοσης.",
"ShaderDumpPathTooltip": "Τοποθεσία Εναπόθεσης Προσωρινής Μνήμης Shaders",
"FileLogTooltip": "Ενεργοποιεί ή απενεργοποιεί την καταγραφή σε ένα αρχείο στο δίσκο",
"StubLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων καταγραφής ατελειών",
"InfoLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων αρχείου καταγραφής πληροφοριών",
"WarnLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων καταγραφής προειδοποιήσεων",
"ErrorLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων αρχείου καταγραφής σφαλμάτων",
"TraceLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων αρχείου καταγραφής ιχνών",
"GuestLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων καταγραφής επισκεπτών",
"FileAccessLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων αρχείου καταγραφής πρόσβασης",
"FSAccessLogModeTooltip": "Ενεργοποιεί την έξοδο καταγραφής πρόσβασης FS στην κονσόλα. Οι πιθανοί τρόποι λειτουργίας είναι 0-3",
"DeveloperOptionTooltip": "Χρησιμοποιήστε με προσοχή",
"OpenGlLogLevel": "Απαιτεί τα κατάλληλα επίπεδα καταγραφής ενεργοποιημένα",
"DebugLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων αρχείου καταγραφής εντοπισμού σφαλμάτων",
"LoadApplicationFileTooltip": "Ανοίξτε έναν επιλογέα αρχείων για να επιλέξετε ένα αρχείο συμβατό με το Switch για φόρτωση",
"LoadApplicationFolderTooltip": "Ανοίξτε έναν επιλογέα αρχείων για να επιλέξετε μία μη συσκευασμένη εφαρμογή, συμβατή με το Switch για φόρτωση",
"OpenRyujinxFolderTooltip": "Ανοίξτε το φάκελο συστήματος αρχείων Ryujinx",
"OpenRyujinxLogsTooltip": "Ανοίξτε το φάκελο στον οποίο διατηρούνται τα αρχεία καταγραφής",
"ExitTooltip": "Έξοδος από το Ryujinx",
"OpenSettingsTooltip": "Ανοίξτε το παράθυρο Ρυθμίσεων",
"OpenProfileManagerTooltip": "Ανοίξτε το παράθυρο Διαχείρισης Προφίλ Χρήστη",
"StopEmulationTooltip": "Σταματήστε την εξομοίωση του τρέχοντος παιχνιδιού και επιστρέψτε στην επιλογή παιχνιδιού",
"CheckUpdatesTooltip": "Ελέγξτε για ενημερώσεις του Ryujinx",
"OpenAboutTooltip": "Ανοίξτε το Παράθυρο Σχετικά",
"GridSize": "Μέγεθος Πλέγματος",
"GridSizeTooltip": "Αλλαγή μεγέθους στοιχείων πλέγματος",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Πορτογαλικά Βραζιλίας",
"AboutRyujinxContributorsButtonHeader": "Δείτε Όλους τους Συντελεστές",
"SettingsTabSystemAudioVolume": "Ενταση Ήχου: ",
"AudioVolumeTooltip": "Αλλαγή Έντασης Ήχου",
"SettingsTabSystemEnableInternetAccess": "Ενεργοποίηση πρόσβασης επισκέπτη στο Διαδίκτυο",
"EnableInternetAccessTooltip": "Επιτρέπει την πρόσβαση επισκέπτη στο Διαδίκτυο. Εάν ενεργοποιηθεί, η εξομοιωμένη κονσόλα Switch θα συμπεριφέρεται σαν να είναι συνδεδεμένη στο Διαδίκτυο. Λάβετε υπόψη ότι σε ορισμένες περιπτώσεις, οι εφαρμογές ενδέχεται να εξακολουθούν να έχουν πρόσβαση στο Διαδίκτυο, ακόμη και όταν αυτή η επιλογή είναι απενεργοποιημένη",
"GameListContextMenuManageCheatToolTip" : "Διαχείριση Κόλπων",
"GameListContextMenuManageCheat" : "Διαχείριση Κόλπων",
"ControllerSettingsStickRange" : "Εύρος",
"DialogStopEmulationTitle" : "Ryujinx - Διακοπή εξομοίωσης",
"DialogStopEmulationMessage": "Είστε βέβαιοι ότι θέλετε να σταματήσετε την εξομοίωση;",
"SettingsTabCpu": "Επεξεργαστής",
"SettingsTabAudio": "Ήχος",
"SettingsTabNetwork": "Δίκτυο",
"SettingsTabNetworkConnection" : "Σύνδεση δικτύου",
"SettingsTabGraphicsFrameRate" : "Ρυθμός Ανανέωσης Υπολογιστή:",
"SettingsTabGraphicsFrameRateTooltip" : "Προκαθορίζει το ρυθμό ανανέωσης του υπολογιστή. Ορίστε το στο 0 για να αφαιρέσετε το όριο.",
"SettingsTabCpuCache" : "Προσωρινή Μνήμη CPU",
"SettingsTabCpuMemory" : "Μνήμη CPU"
}

View file

@ -0,0 +1,552 @@
{
"MenuBarFileOpenApplet": "Open Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Open Mii Editor Applet in Standalone mode",
"SettingsTabInputDirectMouseAccess": "Direct Mouse Access",
"SettingsTabSystemMemoryManagerMode": "Memory Manager Mode:",
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
"SettingsTabSystemMemoryManagerModeHost": "Host (fast)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Unchecked (fastest, unsafe)",
"MenuBarFile": "_File",
"MenuBarFileOpenFromFile": "_Load Application From File",
"MenuBarFileOpenUnpacked": "Load _Unpacked Game",
"MenuBarFileOpenEmuFolder": "Open Ryujinx Folder",
"MenuBarFileOpenLogsFolder": "Open Logs Folder",
"MenuBarFileExit": "_Exit",
"MenuBarOptions": "Options",
"MenuBarOptionsToggleFullscreen": "Toggle Fullscreen",
"MenuBarOptionsStartGamesInFullscreen": "Start Games in Fullscreen Mode",
"MenuBarOptionsStopEmulation": "Stop Emulation",
"MenuBarOptionsSettings": "_Settings",
"MenuBarOptionsManageUserProfiles": "_Manage User Profiles",
"MenuBarActions": "_Actions",
"MenuBarOptionsSimulateWakeUpMessage": "Simulate Wake-up message",
"MenuBarActionsScanAmiibo": "Scan An Amiibo",
"MenuBarTools": "_Tools",
"MenuBarToolsInstallFirmware": "Install Firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Install a firmware from XCI or ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Install a firmware from a directory",
"MenuBarHelp": "Help",
"MenuBarHelpCheckForUpdates": "Check for Updates",
"MenuBarHelpAbout": "About",
"MenuSearch": "Search...",
"GameListHeaderFavorite": "Fav",
"GameListHeaderIcon": "Icon",
"GameListHeaderApplication": "Name",
"GameListHeaderDeveloper": "Developer",
"GameListHeaderVersion": "Version",
"GameListHeaderTimePlayed": "Play Time",
"GameListHeaderLastPlayed": "Last Played",
"GameListHeaderFileExtension": "File Ext",
"GameListHeaderFileSize": "File Size",
"GameListHeaderPath": "Path",
"GameListContextMenuOpenUserSaveDirectory": "Open User Save Directory",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Opens the directory which contains Application's User Save",
"GameListContextMenuOpenUserDeviceDirectory": "Open User Device Directory",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Opens the directory which contains Application's Device Save",
"GameListContextMenuOpenUserBcatDirectory": "Open User BCAT Directory",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Opens the directory which contains Application's BCAT Save",
"GameListContextMenuManageTitleUpdates": "Manage Title Updates",
"GameListContextMenuManageTitleUpdatesToolTip": "Opens the Title Update management window",
"GameListContextMenuManageDlc": "Manage DLC",
"GameListContextMenuManageDlcToolTip": "Opens the DLC management window",
"GameListContextMenuOpenModsDirectory": "Open Mods Directory",
"GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
"GameListContextMenuCacheManagement": "Cache Management",
"GameListContextMenuCacheManagementPurgePptc": "Purge PPTC Cache",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Deletes Application's PPTC cache",
"GameListContextMenuCacheManagementPurgeShaderCache": "Purge Shader Cache",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Deletes Application's shader cache",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Open PPTC Directory",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Opens the directory which contains Application's PPTC cache",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Open Shader Cache Directory",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Opens the directory which contains Application's shader cache",
"GameListContextMenuExtractData": "Extract Data",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Extract the ExeFS section from Application's current config (including updates)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Extract the RomFS section from Application's current config (including updates)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Extract the Logo section from Application's current config (including updates)",
"StatusBarGamesLoaded": "{0}/{1} Games Loaded",
"StatusBarSystemVersion": "System Version: {0}",
"Settings": "Settings",
"SettingsTabGeneral": "User Interface",
"SettingsTabGeneralGeneral": "General",
"SettingsTabGeneralEnableDiscordRichPresence": "Enable Discord Rich Presence",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Check for Updates on Launch",
"SettingsTabGeneralShowConfirmExitDialog": "Show \"Confirm Exit\" Dialog",
"SettingsTabGeneralHideCursorOnIdle": "Hide Cursor on Idle",
"SettingsTabGeneralGameDirectories": "Game Directories",
"SettingsTabGeneralAdd": "Add",
"SettingsTabGeneralRemove": "Remove",
"SettingsTabSystem": "System",
"SettingsTabSystemCore": "Core",
"SettingsTabSystemSystemRegion": "System Region:",
"SettingsTabSystemSystemRegionJapan": "Japan",
"SettingsTabSystemSystemRegionUSA": "USA",
"SettingsTabSystemSystemRegionEurope": "Europe",
"SettingsTabSystemSystemRegionAustralia": "Australia",
"SettingsTabSystemSystemRegionChina": "China",
"SettingsTabSystemSystemRegionKorea": "Korea",
"SettingsTabSystemSystemRegionTaiwan": "Taiwan",
"SettingsTabSystemSystemLanguage": "System Language:",
"SettingsTabSystemSystemLanguageJapanese": "Japanese",
"SettingsTabSystemSystemLanguageAmericanEnglish": "American English",
"SettingsTabSystemSystemLanguageFrench": "French",
"SettingsTabSystemSystemLanguageGerman": "German",
"SettingsTabSystemSystemLanguageItalian": "Italian",
"SettingsTabSystemSystemLanguageSpanish": "Spanish",
"SettingsTabSystemSystemLanguageChinese": "Chinese",
"SettingsTabSystemSystemLanguageKorean": "Korean",
"SettingsTabSystemSystemLanguageDutch": "Dutch",
"SettingsTabSystemSystemLanguagePortuguese": "Portuguese",
"SettingsTabSystemSystemLanguageRussian": "Russian",
"SettingsTabSystemSystemLanguageTaiwanese": "Taiwanese",
"SettingsTabSystemSystemLanguageBritishEnglish": "British English",
"SettingsTabSystemSystemLanguageCanadianFrench": "Canadian French",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Latin American Spanish",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Simplified Chinese",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditional Chinese",
"SettingsTabSystemSystemTimeZone": "System TimeZone:",
"SettingsTabSystemSystemTime": "System Time:",
"SettingsTabSystemEnableVsync": "Enable VSync",
"SettingsTabSystemEnablePptc": "Enable PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Enable FS Integrity Checks",
"SettingsTabSystemAudioBackend": "Audio Backend:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": " - These many cause instabilities",
"SettingsTabSystemExpandDramSize": "Expand DRAM size to 6GB",
"SettingsTabSystemIgnoreMissingServices": "Ignore Missing Services",
"SettingsTabGraphics": "Graphics",
"SettingsTabGraphicsEnhancements": "Enhancements",
"SettingsTabGraphicsEnableShaderCache": "Enable Shader Cache",
"SettingsTabGraphicsAnisotropicFiltering": "Anisotropic Filtering:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Resolution Scale:",
"SettingsTabGraphicsResolutionScaleCustom": "Custom (Not recommended)",
"SettingsTabGraphicsResolutionScaleNative": "Native (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Aspect Ratio:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Stretch to Fit Window",
"SettingsTabGraphicsDeveloperOptions": "Developer Options",
"SettingsTabGraphicsShaderDumpPath": "Graphics Shader Dump Path:",
"SettingsTabLogging": "Logging",
"SettingsTabLoggingLogging": "Logging",
"SettingsTabLoggingEnableLoggingToFile": "Enable Logging to File",
"SettingsTabLoggingEnableStubLogs": "Enable Stub Logs",
"SettingsTabLoggingEnableInfoLogs": "Enable Info Logs",
"SettingsTabLoggingEnableWarningLogs": "Enable Warning Logs",
"SettingsTabLoggingEnableErrorLogs": "Enable Error Logs",
"SettingsTabLoggingEnableTraceLogs": "Enable Trace Logs",
"SettingsTabLoggingEnableGuestLogs": "Enable Guest Logs",
"SettingsTabLoggingEnableFsAccessLogs": "Enable Fs Access Logs",
"SettingsTabLoggingFsGlobalAccessLogMode": "Fs Global Access Log Mode:",
"SettingsTabLoggingDeveloperOptions": "Developer Options (WARNING: Will reduce performance)",
"SettingsTabLoggingOpenglLogLevel": "OpenGL Log Level:",
"SettingsTabLoggingOpenglLogLevelNone": "None",
"SettingsTabLoggingOpenglLogLevelError": "Error",
"SettingsTabLoggingOpenglLogLevelPerformance": "Slowdowns",
"SettingsTabLoggingOpenglLogLevelAll": "All",
"SettingsTabLoggingEnableDebugLogs": "Enable Debug Logs",
"SettingsTabInput": "Input",
"SettingsTabInputEnableDockedMode": "Enable Docked Mode",
"SettingsTabInputDirectKeyboardAccess": "Direct Keyboard Access",
"SettingsButtonSave": "Save",
"SettingsButtonClose": "Close",
"SettingsButtonApply": "Apply",
"ControllerSettingsPlayer": "Player",
"ControllerSettingsPlayer1": "Player 1",
"ControllerSettingsPlayer2": "Player 2",
"ControllerSettingsPlayer3": "Player 3",
"ControllerSettingsPlayer4": "Player 4",
"ControllerSettingsPlayer5": "Player 5",
"ControllerSettingsPlayer6": "Player 6",
"ControllerSettingsPlayer7": "Player 7",
"ControllerSettingsPlayer8": "Player 8",
"ControllerSettingsHandheld": "Handheld",
"ControllerSettingsInputDevice": "Input Device",
"ControllerSettingsRefresh": "Refresh",
"ControllerSettingsDeviceDisabled": "Disabled",
"ControllerSettingsControllerType": "Controller Type",
"ControllerSettingsControllerTypeHandheld": "Handheld",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "JoyCon Pair",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Left",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon Right",
"ControllerSettingsProfile": "Profile",
"ControllerSettingsProfileDefault": "Default",
"ControllerSettingsLoad": "Load",
"ControllerSettingsAdd": "Add",
"ControllerSettingsRemove": "Remove",
"ControllerSettingsButtons": "Buttons",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Directional Pad",
"ControllerSettingsDPadUp": "Up",
"ControllerSettingsDPadDown": "Down",
"ControllerSettingsDPadLeft": "Left",
"ControllerSettingsDPadRight": "Right",
"ControllerSettingsLStick": "Left Stick",
"ControllerSettingsLStickButton": "Button",
"ControllerSettingsLStickUp": "Up",
"ControllerSettingsLStickDown": "Down",
"ControllerSettingsLStickLeft": "Left",
"ControllerSettingsLStickRight": "Right",
"ControllerSettingsLStickStick": "Stick",
"ControllerSettingsLStickInvertXAxis": "Invert Stick X",
"ControllerSettingsLStickInvertYAxis": "Invert Stick Y",
"ControllerSettingsLStickDeadzone": "Deadzone:",
"ControllerSettingsRStick": "Right Stick",
"ControllerSettingsRStickButton": "Button",
"ControllerSettingsRStickUp": "Up",
"ControllerSettingsRStickDown": "Down",
"ControllerSettingsRStickLeft": "Left",
"ControllerSettingsRStickRight": "Right",
"ControllerSettingsRStickStick": "Stick",
"ControllerSettingsRStickInvertXAxis": "Invert Stick X",
"ControllerSettingsRStickInvertYAxis": "Invert Stick Y",
"ControllerSettingsRStickDeadzone": "Deadzone:",
"ControllerSettingsTriggersLeft": "Triggers Left",
"ControllerSettingsTriggersRight": "Triggers Right",
"ControllerSettingsTriggersButtonsLeft": "Trigger Buttons Left",
"ControllerSettingsTriggersButtonsRight": "Trigger Buttons Right",
"ControllerSettingsTriggers": "Triggers",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Buttons Left",
"ControllerSettingsExtraButtonsRight": "Buttons Right",
"ControllerSettingsMisc": "Miscellaneous",
"ControllerSettingsTriggerThreshold": "Trigger Threshold:",
"ControllerSettingsMotion": "Motion",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Enable Motion Controls",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Use CemuHook compatible motion",
"ControllerSettingsMotionControllerSlot": "Controller Slot:",
"ControllerSettingsMotionMirrorInput": "Mirror Input",
"ControllerSettingsMotionRightJoyConSlot": "Right JoyCon Slot:",
"ControllerSettingsMotionServerHost": "Server Host:",
"ControllerSettingsMotionGyroSensitivity": "Gyro Sensitivity:",
"ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:",
"ControllerSettingsSave": "Save",
"ControllerSettingsClose": "Close",
"UserProfilesSelectedUserProfile": "Selected User Profile:",
"UserProfilesSaveProfileName": "Save Profile Name",
"UserProfilesChangeProfileImage": "Change Profile Image",
"UserProfilesAvailableUserProfiles": "Available User Profiles:",
"UserProfilesAddNewProfile": "Add New Profile",
"UserProfilesDeleteSelectedProfile": "Delete Selected Profile",
"UserProfilesClose": "Close",
"ProfileImageSelectionTitle": "Profile Image Selection",
"ProfileImageSelectionHeader": "Choose a profile Image",
"ProfileImageSelectionNote": "You may import a custom profile image, or select an avatar from system firmware",
"ProfileImageSelectionImportImage": "Import Image File",
"ProfileImageSelectionSelectAvatar": "Select Firmware Avatar",
"InputDialogTitle": "Input Dialog",
"InputDialogOk": "OK",
"InputDialogCancel": "Cancel",
"InputDialogAddNewProfileTitle": "Choose the Profile Name",
"InputDialogAddNewProfileHeader": "Please Enter a Profile Name",
"InputDialogAddNewProfileSubtext": "(Max Length: {0})",
"AvatarChoose": "Choose",
"AvatarSetBackgroundColor": "Set Background Color",
"AvatarClose": "Close",
"ControllerSettingsLoadProfileToolTip": "Load Profile",
"ControllerSettingsAddProfileToolTip": "Add Profile",
"ControllerSettingsRemoveProfileToolTip": "Remove Profile",
"ControllerSettingsSaveProfileToolTip": "Save Profile",
"MenuBarFileToolsTakeScreenshot": "Take Screenshot",
"MenuBarFileToolsHideUi": "Hide Ui",
"GameListContextMenuToggleFavorite": "Toggle Favorite",
"GameListContextMenuToggleFavoriteToolTip": "Toggle Favorite status of Game",
"SettingsTabGeneralTheme": "Theme",
"SettingsTabGeneralThemeCustomTheme": "Custom Theme Path",
"SettingsTabGeneralThemeBaseStyle": "Base Style",
"SettingsTabGeneralThemeBaseStyleDark": "Dark",
"SettingsTabGeneralThemeBaseStyleLight": "Light",
"SettingsTabGeneralThemeEnableCustomTheme": "Enable Custom Theme",
"ButtonBrowse": "Browse",
"ControllerSettingsMotionConfigureCemuHookSettings": "Configure CemuHook Motion",
"ControllerSettingsRumble": "Rumble",
"ControllerSettingsRumbleEnable": "Enable Rumble",
"ControllerSettingsRumbleStrongMultiplier": "Strong Rumble Multiplier",
"ControllerSettingsRumbleWeakMultiplier": "Weak Rumble Multiplier",
"DialogMessageSaveNotAvailableMessage": "There is no savedata for {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Would you like to create savedata for this game?",
"DialogConfirmationTitle": "Ryujinx - Confirmation",
"DialogUpdaterTitle": "Ryujinx - Updater",
"DialogErrorTitle": "Ryujinx - Error",
"DialogWarningTitle": "Ryujinx - Warning",
"DialogExitTitle": "Ryujinx - Exit",
"DialogErrorMessage": "Ryujinx has encountered an error",
"DialogExitMessage": "Are you sure you want to close Ryujinx?",
"DialogExitSubMessage": "All unsaved data will be lost!",
"DialogMessageCreateSaveErrorMessage": "There was an error creating the specified savedata: {0}",
"DialogMessageFindSaveErrorMessage": "There was an error finding the specified savedata: {0}",
"FolderDialogExtractTitle": "Choose the folder to extract into",
"DialogNcaExtractionMessage": "Extracting {0} section from {1}...",
"DialogNcaExtractionTitle": "Ryujinx - NCA Section Extractor",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Extraction failure. The main NCA was not present in the selected file.",
"DialogNcaExtractionCheckLogErrorMessage": "Extraction failure. Read the log file for further information.",
"DialogNcaExtractionSuccessMessage": "Extraction completed successfully.",
"DialogUpdaterConvertFailedMessage": "Failed to convert the current Ryujinx version.",
"DialogUpdaterCancelUpdateMessage": "Cancelling Update!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "You are already using the most updated version of Ryujinx!",
"DialogUpdaterFailedToGetVersionMessage": "An error has occurred when trying to get release information from Github Release. This can be caused if a new release is being compiled by GitHub Actions. Try again in a few minutes.",
"DialogUpdaterConvertFailedGithubMessage": "Failed to convert the received Ryujinx version from Github Release.",
"DialogUpdaterDownloadingMessage": "Downloading Update...",
"DialogUpdaterExtractionMessage": "Extracting Update...",
"DialogUpdaterRenamingMessage": "Renaming Update...",
"DialogUpdaterAddingFilesMessage": "Adding New Update...",
"DialogUpdaterCompleteMessage": "Update Complete!",
"DialogUpdaterRestartMessage": "Do you want to restart Ryujinx now?",
"DialogUpdaterArchNotSupportedMessage": "You are not running a supported system architecture!",
"DialogUpdaterArchNotSupportedSubMessage": "(Only x64 systems are supported!)",
"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://ryujinx.org/ 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",
"DialogFirmwareInstallEmbeddedMessage": "Would you like to install the firmware embedded in this game? (Firmware {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "No installed firmware was found but Ryujinx was able to install firmware {0} from the provided game.\\nThe emulator will now start.",
"DialogFirmwareNoFirmwareInstalledMessage": "No Firmware Installed",
"DialogFirmwareInstalledMessage": "Firmware {0} was installed",
"DialogOpenSettingsWindowLabel": "Open Settings Window",
"DialogControllerAppletTitle": "Controller Applet",
"DialogMessageDialogErrorExceptionMessage": "Error displaying Message Dialog: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Error displaying Software Keyboard: {0}",
"DialogErrorAppletErrorExceptionMessage": "Error displaying ErrorApplet Dialog: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nFor more information on how to fix this error, follow our Setup Guide.",
"DialogUserErrorDialogTitle": "Ryujinx Error ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "An error occured while fetching information from the API.",
"DialogAmiiboApiConnectErrorMessage": "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online.",
"DialogProfileInvalidProfileErrorMessage": "Profile {0} is incompatible with the current input configuration system.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "Default Profile can not be overwritten",
"DialogProfileDeleteProfileTitle": "Deleting Profile",
"DialogProfileDeleteProfileMessage": "This action is irreversible, are you sure you want to continue?",
"DialogWarning": "Warning",
"DialogPPTCDeletionMessage": "You are about to delete the PPTC cache for :\n\n{0}\n\nAre you sure you want to proceed?",
"DialogPPTCDeletionErrorMessage": "Error purging PPTC cache at {0}: {1}",
"DialogShaderDeletionMessage": "You are about to delete the Shader cache for :\n\n{0}\n\nAre you sure you want to proceed?",
"DialogShaderDeletionErrorMessage": "Error purging Shader cache at {0}: {1}",
"DialogRyujinxErrorMessage": "Ryujinx has encountered an error",
"DialogInvalidTitleIdErrorMessage": "UI error: The selected game did not have a valid title ID",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "A valid system firmware was not found in {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Install Firmware {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "System version {0} will be installed.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nThis will replace the current system version {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nDo you want to continue?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Installing firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "System version {0} successfully installed.",
"DialogUserProfileDeletionWarningMessage": "There would be no other profiles to be opened if selected profile is deleted",
"DialogUserProfileDeletionConfirmMessage": "Do you want to delete the selected profile",
"DialogControllerSettingsModifiedConfirmMessage": "The current controller settings has been updated.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Do you want to save?",
"DialogDlcLoadNcaErrorMessage": "{0}. Errored File: {1}",
"DialogDlcNoDlcErrorMessage": "The specified file does not contain a DLC for the selected title!",
"DialogPerformanceCheckLoggingEnabledMessage": "You have trace logging enabled, which is designed to be used by developers only.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "For optimal performance, it's recommended to disable trace logging. Would you like to disable trace logging now?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "You have shader dumping enabled, which is designed to be used by developers only.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "For optimal performance, it's recommended to disable shader dumping. Would you like to disable shader dumping now?",
"DialogLoadAppGameAlreadyLoadedMessage": "A game has already been loaded",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Please stop emulation or close the emulator before launching another game.",
"DialogUpdateAddUpdateErrorMessage": "The specified file does not contain an update for the selected title!",
"DialogSettingsBackendThreadingWarningTitle": "Warning - Backend Threading",
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx must be restarted after changing this option for it to apply fully. Depending on your platform, you may need to manually disable your driver's own multithreading when using Ryujinx's.",
"SettingsTabGraphicsFeaturesOptions": "Features",
"SettingsTabGraphicsBackendMultithreading": "Graphics Backend Multithreading:",
"CommonAuto": "Auto",
"CommonOff": "Off",
"CommonOn": "On",
"InputDialogYes": "Yes",
"InputDialogNo": "No",
"DialogProfileInvalidProfileNameErrorMessage": "The file name contains invalid characters. Please try again.",
"MenuBarOptionsPauseEmulation": "Pause",
"MenuBarOptionsResumeEmulation": "Resume",
"AboutUrlTooltipMessage": "Click to open the Ryujinx website in your default browser.",
"AboutDisclaimerMessage": "Ryujinx is not affiliated with Nintendo™,\nor any of its partners, in any way.",
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) is used\nin our Amiibo emulation.",
"AboutPatreonUrlTooltipMessage": "Click to open the Ryujinx Patreon page in your default browser.",
"AboutGithubUrlTooltipMessage": "Click to open the Ryujinx GitHub page in your default browser.",
"AboutDiscordUrlTooltipMessage": "Click to open an invite to the Ryujinx Discord server in your default browser.",
"AboutTwitterUrlTooltipMessage": "Click to open the Ryujinx Twitter page in your default browser.",
"AboutRyujinxAboutTitle": "About:",
"AboutRyujinxAboutContent": "Ryujinx is an emulator for the Nintendo Switch™.\nPlease support us on Patreon.\nGet all the latest news on our Twitter or Discord.\nDevelopers interested in contributing can find out more on our GitHub or Discord.",
"AboutRyujinxMaintainersTitle": "Maintained By:",
"AboutRyujinxMaintainersContentTooltipMessage": "Click to open the Contributors page in your default browser.",
"AboutRyujinxSupprtersTitle": "Supported on Patreon By:",
"AmiiboSeriesLabel": "Amiibo Series",
"AmiiboCharacterLabel": "Character",
"AmiiboScanButtonLabel": "Scan It",
"AmiiboOptionsShowAllLabel": "Show All Amiibo",
"AmiiboOptionsUsRandomTagLabel": "Hack: Use Random tag Uuid",
"DlcManagerTableHeadingEnabledLabel": "Enabled",
"DlcManagerTableHeadingTitleIdLabel": "Title ID",
"DlcManagerTableHeadingContainerPathLabel": "Container Path",
"DlcManagerTableHeadingFullPathLabel": "Full Path",
"DlcManagerRemoveAllButton": "Remove All",
"MenuBarOptionsChangeLanguage": "Change Language",
"CommonSort": "Sort",
"CommonShowNames": "Show Names",
"CommonFavorite": "Favorite",
"OrderAscending": "Ascending",
"OrderDescending": "Descending",
"SettingsTabGraphicsFeatures": "Features",
"ErrorWindowTitle": "Error Window",
"ToggleDiscordTooltip": "Enables or disables Discord Rich Presence",
"AddGameDirBoxTooltip": "Enter a game directory to add to the list",
"AddGameDirTooltip": "Add a game directory to the list",
"RemoveGameDirTooltip": "Remove selected game directory",
"CustomThemeCheckTooltip": "Enable or disable custom themes in the GUI",
"CustomThemePathTooltip": "Path to custom GUI theme",
"CustomThemeBrowseTooltip": "Browse for a custom GUI theme",
"DockModeToggleTooltip": "Enable or disable Docked Mode",
"DirectKeyboardTooltip": "Enable or disable \"direct keyboard access (HID) support\" (Provides games access to your keyboard as a text entry device)",
"DirectMouseTooltip": "Enable or disable \"direct mouse access (HID) support\" (Provides games access to your mouse as a pointing device)",
"RegionTooltip": "Change System Region",
"LanguageTooltip": "Change System Language",
"TimezoneTooltip": "Change System TimeZone",
"TimeTooltip": "Change System Time",
"VSyncToggleTooltip": "Enables or disables Vertical Sync",
"PptcToggleTooltip": "Enables or disables PPTC",
"FsIntegrityToggleTooltip": "Enables integrity checks on Game content files",
"AudioBackendTooltip": "Change Audio Backend",
"MemoryManagerTooltip": "Change how guest memory is mapped and accessed. Greatly affects emulated CPU performance.",
"MemoryManagerSoftwareTooltip": "Use a software page table for address translation. Highest accuracy but slowest performance.",
"MemoryManagerHostTooltip": "Directly map memory in the host address space. Much faster JIT compilation and execution.",
"MemoryManagerUnsafeTooltip": "Directly map memory, but do not mask the address within the guest address space before access. Faster, but at the cost of safety. The guest application can access memory from anywhere in Ryujinx, so only run programs you trust with this mode.",
"DRamTooltip": "Expands the amount of memory on the emulated system from 4GB to 6GB",
"IgnoreMissingServicesTooltip": "Enable or disable ignoring missing services option",
"GraphicsBackendThreadingTooltip": "Enable Graphics Backend Multithreading",
"GalThreadingTooltip": "Executes graphics backend commands on a second thread. Allows runtime multithreading of shader compilation, reduces stuttering, and improves performance on drivers without multithreading support of their own. Slightly varying peak performance on drivers with multithreading. Ryujinx may need to be restarted to correctly disable driver built-in multithreading, or you may need to do it manually to get the best performance.",
"ShaderCacheToggleTooltip": "Enables or disables Shader Cache",
"ResolutionScaleTooltip": "Resolution Scale applied to applicable render targets",
"ResolutionScaleEntryTooltip": "Floating point resolution scale, such as 1.5. Non-integral scales are more likely to cause issues or crash.",
"AnisotropyTooltip": "Level of Anisotropic Filtering (set to Auto to use the value requested by the game)",
"AspectRatioTooltip": "Aspect Ratio applied to the renderer window.",
"ShaderDumpPathTooltip": "Graphics Shaders Dump Path",
"FileLogTooltip": "Enables or disables logging to a file on disk",
"StubLogTooltip": "Enables printing stub log messages",
"InfoLogTooltip": "Enables printing info log messages",
"WarnLogTooltip": "Enables printing warning log messages",
"ErrorLogTooltip": "Enables printing error log messages",
"TraceLogTooltip": "Enables printing trace log messages",
"GuestLogTooltip": "Enables printing guest log messages",
"FileAccessLogTooltip": "Enables printing file access log messages",
"FSAccessLogModeTooltip": "Enables FS access log output to the console. Possible modes are 0-3",
"DeveloperOptionTooltip": "Use with care",
"OpenGlLogLevel": "Requires appropriate log levels enabled",
"DebugLogTooltip": "Enables printing debug log messages",
"LoadApplicationFileTooltip": "Open a file chooser to choose a Switch compatible file to load",
"LoadApplicationFolderTooltip": "Open a file chooser to choose a Switch compatible, unpacked application to load",
"OpenRyujinxFolderTooltip": "Open Ryujinx filesystem folder",
"OpenRyujinxLogsTooltip": "Opens the folder where logs are written to",
"ExitTooltip": "Exit Ryujinx",
"OpenSettingsTooltip": "Open settings window",
"OpenProfileManagerTooltip": "Open User Profiles Manager window",
"StopEmulationTooltip": "Stop emulation of the current game and return to game selection",
"CheckUpdatesTooltip": "Check for updates to Ryujinx",
"OpenAboutTooltip": "Open About Window",
"GridSize": "Grid Size",
"GridSizeTooltip": "Change the size of grid items",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Brazilian Portuguese",
"AboutRyujinxContributorsButtonHeader": "See All Contributors",
"SettingsTabSystemAudioVolume": "Volume: ",
"AudioVolumeTooltip": "Change Audio Volume",
"SettingsTabSystemEnableInternetAccess": "Enable Guest Internet Access",
"EnableInternetAccessTooltip": "Enables guest Internet access. If enabled, the application will behave as if the emulated Switch console was connected to the Internet. Note that in some cases, applications may still access the Internet even with this option disabled",
"GameListContextMenuManageCheatToolTip": "Manage Cheats",
"GameListContextMenuManageCheat": "Manage Cheats",
"ControllerSettingsStickRange": "Range",
"DialogStopEmulationTitle": "Ryujinx - Stop Emulation",
"DialogStopEmulationMessage": "Are you sure you want to stop emulation?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "Audio",
"SettingsTabNetwork": "Network",
"SettingsTabNetworkConnection": "Network Connection",
"[REMOVE]SettingsTabGraphicsFrameRate": "Host Refresh Rate:",
"[REMOVE]SettingsTabGraphicsFrameRateTooltip": "Sets host refresh rate. Set to 0 to remove limit.",
"SettingsTabCpuCache": "CPU Cache",
"SettingsTabCpuMemory": "CPU Memory",
"DialogUpdaterFlatpakNotSupportedMessage": "Please update Ryujinx via FlatHub.",
"UpdaterDisabledWarningTitle": "Updater Disabled!",
"GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods",
"ControllerSettingsRotate90": "Rotate 90° Clockwise",
"IconSize": "Icon Size",
"IconSizeTooltip": "Change the size of game icon",
"MenuBarOptionsShowConsole": "Show Console",
"ShaderCachePurgeError": "Error purging shader cache at {0}: {1}",
"UserErrorNoKeys": "Keys not found",
"UserErrorNoFirmware": "Firmware not found",
"UserErrorFirmwareParsingFailed": "Firmware parsing error",
"UserErrorApplicationNotFound": "Application not found",
"UserErrorUnknown": "Unknown error",
"UserErrorUndefined": "Undefined error",
"UserErrorNoKeysDescription": "Ryujinx was unable to find your 'prod.keys' file",
"UserErrorNoFirmwareDescription": "Ryujinx was unable to find any firmwares installed",
"UserErrorFirmwareParsingFailedDescription": "Ryujinx was unable to parse the provided firmware. This is usually caused by outdated keys.",
"UserErrorApplicationNotFoundDescription": "Ryujinx couldn't find a valid application at the given path.",
"UserErrorUnknownDescription": "An unknown error occured!",
"UserErrorUndefinedDescription": "An undefined error occured! This shouldn't happen, please contact a dev!",
"OpenSetupGuideMessage": "Open the Setup Guide",
"NoUpdate": "No Update",
"TitleUpdateVersionLabel": "Version {0} - {1}",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Confirmation",
"FileDialogAllTypes": "All types",
"Never": "Never",
"SwkbdMinCharacters": "Must be at least {0} characters long",
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
"SoftwareKeyboard": "Software Keyboard",
"DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n",
"UpdaterRenaming": "Renaming Old Files...",
"UpdaterRenameFailed": "Updater was unable to rename file: {0}",
"UpdaterAddingFiles": "Adding New Files...",
"UpdaterExtracting": "Extracting Update...",
"UpdaterDownloading": "Downloading Update...",
"Game": "Game",
"Docked": "Docked",
"Handheld": "Handheld",
"ConnectionError": "Connection Error.",
"AboutPageDeveloperListMore": "{0} and more...",
"ApiError": "API Error.",
"LoadingHeading": "Loading {0}",
"CompilingPPTC": "Compiling PTC",
"CompilingShaders": "Compiling Shaders",
"AllKeyboards": "All keyboards",
"OpenFileDialogTitle": "Select a supported file to open",
"OpenFolderDialogTitle": "Select a folder with an unpacked game",
"AllSupportedFormats": "All Supported Formats",
"RyujinxUpdater": "Ryujinx Updater"
}

View file

@ -0,0 +1,497 @@
{
"MenuBarFileOpenApplet": "Abrir applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abre el editor de Mii en modo autónomo",
"SettingsTabInputDirectMouseAccess": "Acceso directo al ratón",
"SettingsTabSystemMemoryManagerMode": "Modo del administrador de memoria:",
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
"SettingsTabSystemMemoryManagerModeHost": "Host (rápido)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host sin verificación (más rápido, inseguro)",
"MenuBarFile": "_Archivo",
"MenuBarFileOpenFromFile": "_Cargar aplicación desde un archivo",
"MenuBarFileOpenUnpacked": "Cargar juego _desempaquetado",
"MenuBarFileOpenEmuFolder": "Abrir carpeta de Ryujinx",
"MenuBarFileOpenLogsFolder": "Abrir carpeta de registros",
"MenuBarFileExit": "_Salir",
"MenuBarOptions": "_Opciones",
"MenuBarOptionsToggleFullscreen": "Alternar pantalla completa",
"MenuBarOptionsStartGamesInFullscreen": "Iniciar juegos en pantalla completa",
"MenuBarOptionsStopEmulation": "Detener emulación",
"MenuBarOptionsSettings": "_Configuración",
"MenuBarOptionsManageUserProfiles": "_Gestionar perfiles de usuario",
"MenuBarActions": "Accio_nes",
"MenuBarOptionsSimulateWakeUpMessage": "Simular mensaje de _reactivación",
"MenuBarActionsScanAmiibo": "_Escanear Amiibo",
"MenuBarTools": "_Herramientas",
"MenuBarToolsInstallFirmware": "Instalar firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware desde un archivo XCI o ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware desde una carpeta",
"MenuBarHelp": "A_yuda",
"MenuBarHelpCheckForUpdates": "Buscar actualizaciones",
"MenuBarHelpAbout": "Acerca de",
"MenuSearch": "Buscar...",
"GameListHeaderFavorite": "Fav",
"GameListHeaderIcon": "Icono",
"GameListHeaderApplication": "Aplicación",
"GameListHeaderDeveloper": "Desarrollador",
"GameListHeaderVersion": "Versión",
"GameListHeaderTimePlayed": "Tiempo jugado",
"GameListHeaderLastPlayed": "Última vez",
"GameListHeaderFileExtension": "Extensión",
"GameListHeaderFileSize": "Tamaño",
"GameListHeaderPath": "Directorio",
"GameListContextMenuOpenUserSaveDirectory": "Abrir carpeta de guardado de este usuario",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Abre la carpeta que contiene la partida guardada del usuario para esta aplicación",
"GameListContextMenuOpenUserDeviceDirectory": "Abrir carpeta de guardado del sistema para el usuario actual",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Abre la carpeta que contiene la partida guardada del sistema para esta aplicación",
"GameListContextMenuOpenUserBcatDirectory": "Abrir carpeta de guardado BCAT del usuario",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Abre la carpeta que contiene el guardado BCAT de esta aplicación",
"GameListContextMenuManageTitleUpdates": "Gestionar actualizaciones del juego",
"GameListContextMenuManageTitleUpdatesToolTip": "Abre la ventana de gestión de actualizaciones de esta aplicación",
"GameListContextMenuManageDlc": "Gestionar DLC",
"GameListContextMenuManageDlcToolTip": "Abre la ventana de gestión del contenido descargable",
"GameListContextMenuOpenModsDirectory": "Abrir carpeta de mods",
"GameListContextMenuOpenModsDirectoryToolTip": "Abre la carpeta que contiene los mods (archivos modificantes) de esta aplicación",
"GameListContextMenuCacheManagement": "Gestión de cachés",
"GameListContextMenuCacheManagementPurgePptc": "Purgar caché de PPTC",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Elimina la caché de PPTC de esta aplicación",
"GameListContextMenuCacheManagementPurgeShaderCache": "Purgar caché de sombreadores",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Elimina la caché de sombreadores de esta aplicación",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Abrir carpeta de PPTC",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Abre la carpeta que contiene la caché de PPTC de esta aplicación",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Abrir carpeta de caché de sombreadores",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Abre la carpeta que contiene la caché de sombreadores de esta aplicación",
"GameListContextMenuExtractData": "Extraer datos",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Extrae la sección ExeFS de la configuración actual de la aplicación (incluyendo actualizaciones)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Extrae la sección RomFS de la configuración actual de la aplicación (incluyendo actualizaciones)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Extrae la sección Logo de la configuración actual de la aplicación (incluyendo actualizaciones)",
"StatusBarGamesLoaded": "{0}/{1} juegos cargados",
"StatusBarSystemVersion": "Versión del sistema: {0}",
"Settings": "Configuración",
"SettingsTabGeneral": "General",
"SettingsTabGeneralGeneral": "General",
"SettingsTabGeneralEnableDiscordRichPresence": "Habilitar presencia enriquecida de Discord",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Buscar actualizaciones al iniciar",
"SettingsTabGeneralShowConfirmExitDialog": "Mostrar diálogo de confirmación al cerrar",
"SettingsTabGeneralHideCursorOnIdle": "Ocultar cursor cuando esté inactivo",
"SettingsTabGeneralGameDirectories": "Carpetas de juegos",
"SettingsTabGeneralAdd": "Agregar",
"SettingsTabGeneralRemove": "Quitar",
"SettingsTabSystem": "Sistema",
"SettingsTabSystemCore": "Principal",
"SettingsTabSystemSystemRegion": "Región del sistema:",
"SettingsTabSystemSystemRegionJapan": "Japón",
"SettingsTabSystemSystemRegionUSA": "EEUU",
"SettingsTabSystemSystemRegionEurope": "Europa",
"SettingsTabSystemSystemRegionAustralia": "Australia",
"SettingsTabSystemSystemRegionChina": "China",
"SettingsTabSystemSystemRegionKorea": "Corea",
"SettingsTabSystemSystemRegionTaiwan": "Taiwán",
"SettingsTabSystemSystemLanguage": "Idioma del sistema:",
"SettingsTabSystemSystemLanguageJapanese": "Japonés",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Inglés americano",
"SettingsTabSystemSystemLanguageFrench": "Francés",
"SettingsTabSystemSystemLanguageGerman": "Alemán",
"SettingsTabSystemSystemLanguageItalian": "Italiano",
"SettingsTabSystemSystemLanguageSpanish": "Español",
"SettingsTabSystemSystemLanguageChinese": "Chino",
"SettingsTabSystemSystemLanguageKorean": "Coreano",
"SettingsTabSystemSystemLanguageDutch": "Neerlandés/Holandés",
"SettingsTabSystemSystemLanguagePortuguese": "Portugués",
"SettingsTabSystemSystemLanguageRussian": "Ruso",
"SettingsTabSystemSystemLanguageTaiwanese": "Taiwanés",
"SettingsTabSystemSystemLanguageBritishEnglish": "Inglés británico",
"SettingsTabSystemSystemLanguageCanadianFrench": "Francés canadiense",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Español latinoamericano",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Chino simplificado",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Chino tradicional",
"SettingsTabSystemSystemTimeZone": "Zona horaria del sistema:",
"SettingsTabSystemSystemTime": "Hora del sistema:",
"SettingsTabSystemEnableVsync": "Habilitar sincronización vertical",
"SettingsTabSystemEnablePptc": "Habilitar PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Habilitar comprobaciones de integridad FS",
"SettingsTabSystemAudioBackend": "Motor de audio:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": " - Pueden causar inestabilidad",
"SettingsTabSystemExpandDramSize": "Expandir DRAM a 6GB",
"SettingsTabSystemIgnoreMissingServices": "Ignorar falta de servicios",
"SettingsTabGraphics": "Gráficos",
"SettingsTabGraphicsEnhancements": "Mejoras",
"SettingsTabGraphicsEnableShaderCache": "Habilitar caché de sombreadores",
"SettingsTabGraphicsAnisotropicFiltering": "Filtro anisotrópico:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
"SettingsTabGraphicsAnisotropicFiltering2x": "x2",
"SettingsTabGraphicsAnisotropicFiltering4x": "x4",
"SettingsTabGraphicsAnisotropicFiltering8x": "x8",
"SettingsTabGraphicsAnisotropicFiltering16x": "x16",
"SettingsTabGraphicsResolutionScale": "Escala de resolución:",
"SettingsTabGraphicsResolutionScaleCustom": "Personalizada (no recomendado)",
"SettingsTabGraphicsResolutionScaleNative": "Nativa (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "x2 (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "x3 (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "x4 (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Relación de aspecto:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Estirar a la ventana",
"SettingsTabGraphicsDeveloperOptions": "Opciones de desarrollador",
"SettingsTabGraphicsShaderDumpPath": "Directorio de volcado de sombreadores:",
"SettingsTabLogging": "Registros",
"SettingsTabLoggingLogging": "Registros",
"SettingsTabLoggingEnableLoggingToFile": "Escribir registros en archivo",
"SettingsTabLoggingEnableStubLogs": "Habilitar registros de Stub",
"SettingsTabLoggingEnableInfoLogs": "Habilitar registros de Info",
"SettingsTabLoggingEnableWarningLogs": "Habilitar registros de Advertencia",
"SettingsTabLoggingEnableErrorLogs": "Habilitar registros de Error",
"SettingsTabLoggingEnableGuestLogs": "Habilitar registros de Guest",
"SettingsTabLoggingEnableFsAccessLogs": "Habilitar registros de Fs Access",
"SettingsTabLoggingFsGlobalAccessLogMode": "Modo de registros Fs Global Access:",
"SettingsTabLoggingDeveloperOptions": "Opciones de desarrollador (ADVERTENCIA: empeorarán el rendimiento)",
"SettingsTabLoggingOpenglLogLevel": "Nivel de registro de OpenGL:",
"SettingsTabLoggingOpenglLogLevelNone": "Nada",
"SettingsTabLoggingOpenglLogLevelError": "Errores",
"SettingsTabLoggingOpenglLogLevelPerformance": "Ralentizaciones",
"SettingsTabLoggingOpenglLogLevelAll": "Todo",
"SettingsTabLoggingEnableDebugLogs": "Habilitar registros de debug",
"SettingsTabInput": "Entrada",
"SettingsTabInputEnableDockedMode": "Habilitar modo acoplado (dock/TV)",
"SettingsTabInputDirectKeyboardAccess": "Acceso directo al teclado",
"SettingsButtonSave": "Guardar",
"SettingsButtonClose": "Cerrar",
"SettingsButtonApply": "Aplicar",
"ControllerSettingsPlayer": "Jugador",
"ControllerSettingsPlayer1": "Jugador 1",
"ControllerSettingsPlayer2": "Jugador 2",
"ControllerSettingsPlayer3": "Jugador 3",
"ControllerSettingsPlayer4": "Jugador 4",
"ControllerSettingsPlayer5": "Jugador 5",
"ControllerSettingsPlayer6": "Jugador 6",
"ControllerSettingsPlayer7": "Jugador 7",
"ControllerSettingsPlayer8": "Jugador 8",
"ControllerSettingsHandheld": "Portátil",
"ControllerSettingsInputDevice": "Dispositivo de entrada",
"ControllerSettingsRefresh": "Actualizar",
"ControllerSettingsDeviceDisabled": "Deshabilitado",
"ControllerSettingsControllerType": "Tipo de Mando",
"ControllerSettingsControllerTypeHandheld": "Portátil",
"ControllerSettingsControllerTypeProController": "Mando Pro",
"ControllerSettingsControllerTypeJoyConPair": "Doble Joy-Con",
"ControllerSettingsControllerTypeJoyConLeft": "Joy-Con Izquierdo",
"ControllerSettingsControllerTypeJoyConRight": "Joy-Con Derecho",
"ControllerSettingsProfile": "Perfil",
"ControllerSettingsProfileDefault": "Predeterminado",
"ControllerSettingsLoad": "Cargar",
"ControllerSettingsAdd": "Agregar",
"ControllerSettingsRemove": "Quitar",
"ControllerSettingsButtons": "Botones",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Pad direccional",
"ControllerSettingsDPadUp": "Arriba",
"ControllerSettingsDPadDown": "Abajo",
"ControllerSettingsDPadLeft": "Izquierda",
"ControllerSettingsDPadRight": "Derecha",
"ControllerSettingsLStick": "Palanca izquierda",
"ControllerSettingsLStickButton": "Botón (L3)",
"ControllerSettingsLStickUp": "Arriba",
"ControllerSettingsLStickDown": "Abajo",
"ControllerSettingsLStickLeft": "Izquierda",
"ControllerSettingsLStickRight": "Derecha",
"ControllerSettingsLStickStick": "Palanca",
"ControllerSettingsLStickInvertXAxis": "Invertir eje X",
"ControllerSettingsLStickInvertYAxis": "Invertir eje Y",
"ControllerSettingsLStickDeadzone": "Zona muerta:",
"ControllerSettingsRStick": "Palanca derecha",
"ControllerSettingsRStickButton": "Botón (R3)",
"ControllerSettingsRStickUp": "Arriba",
"ControllerSettingsRStickDown": "Abajo",
"ControllerSettingsRStickLeft": "Izquierda",
"ControllerSettingsRStickRight": "Derecha",
"ControllerSettingsRStickStick": "Palanca",
"ControllerSettingsRStickInvertXAxis": "Invertir eje X",
"ControllerSettingsRStickInvertYAxis": "Invertir eje Y",
"ControllerSettingsRStickDeadzone": "Zona muerta:",
"ControllerSettingsTriggersLeft": "Gatillos izquierdos",
"ControllerSettingsTriggersRight": "Gatillos derechos",
"ControllerSettingsTriggersButtonsLeft": "Botones de gatillo izquierdos",
"ControllerSettingsTriggersButtonsRight": "Botones de gatillo derechos",
"ControllerSettingsTriggers": "Gatillos",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Botones izquierdos",
"ControllerSettingsExtraButtonsRight": "Botones derechos",
"ControllerSettingsMisc": "Misceláneo",
"ControllerSettingsTriggerThreshold": "Límite de gatillos:",
"ControllerSettingsMotion": "Movimiento",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Habilitar controles por movimiento",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Usar movimiento compatible con CemuHook",
"ControllerSettingsMotionControllerSlot": "Puerto del mando:",
"ControllerSettingsMotionMirrorInput": "Paralelizar derecho e izquierdo",
"ControllerSettingsMotionRightJoyConSlot": "Puerto del Joy-Con derecho:",
"ControllerSettingsMotionServerHost": "Host del servidor:",
"ControllerSettingsMotionGyroSensitivity": "Sensibilidad de Gyro:",
"ControllerSettingsMotionGyroDeadzone": "Zona muerta de Gyro:",
"ControllerSettingsSave": "Guardar",
"ControllerSettingsClose": "Cerrar",
"UserProfilesSelectedUserProfile": "Perfil de usuario seleccionado:",
"UserProfilesSaveProfileName": "Guardar nombre de perfil",
"UserProfilesChangeProfileImage": "Cambiar imagen de perfil",
"UserProfilesAvailableUserProfiles": "Perfiles de usuario disponibles:",
"UserProfilesAddNewProfile": "Añadir nuevo perfil",
"UserProfilesDeleteSelectedProfile": "Eliminar perfil seleccionado",
"UserProfilesClose": "Cerrar",
"ProfileImageSelectionTitle": "Selección de imagen de perfil",
"ProfileImageSelectionHeader": "Elige una imagen de perfil",
"ProfileImageSelectionNote": "Puedes importar una imagen de perfil personalizada, o seleccionar un avatar del firmware de sistema",
"ProfileImageSelectionImportImage": "Importar imagen",
"ProfileImageSelectionSelectAvatar": "Seleccionar avatar del firmware",
"InputDialogTitle": "Cuadro de diálogo de entrada",
"InputDialogOk": "Aceptar",
"InputDialogCancel": "Cancelar",
"InputDialogAddNewProfileTitle": "Introducir nombre de perfil",
"InputDialogAddNewProfileHeader": "Por favor elige un nombre de usuario",
"InputDialogAddNewProfileSubtext": "(Máximo de caracteres: {0})",
"AvatarChoose": "Escoger",
"AvatarSetBackgroundColor": "Establecer color de fondo",
"AvatarClose": "Cerrar",
"ControllerSettingsLoadProfileToolTip": "Cargar perfil",
"ControllerSettingsAddProfileToolTip": "Agregar perfil",
"ControllerSettingsRemoveProfileToolTip": "Eliminar perfil",
"ControllerSettingsSaveProfileToolTip": "Guardar perfil",
"MenuBarFileToolsTakeScreenshot": "Captura de pantalla",
"MenuBarFileToolsHideUi": "Ocultar interfaz",
"GameListContextMenuToggleFavorite": "Marcar favorito",
"GameListContextMenuToggleFavoriteToolTip": "Marca o desmarca el juego como favorito",
"SettingsTabGeneralTheme": "Tema",
"SettingsTabGeneralThemeCustomTheme": "Directorio de tema personalizado",
"SettingsTabGeneralThemeBaseStyle": "Estilo base",
"SettingsTabGeneralThemeBaseStyleDark": "Oscuro",
"SettingsTabGeneralThemeBaseStyleLight": "Claro",
"SettingsTabGeneralThemeEnableCustomTheme": "Habilitar tema personalizado",
"ButtonBrowse": "Buscar",
"ControllerSettingsMotionConfigureCemuHookSettings": "Configurar controles por movimiento de CemuHook",
"ControllerSettingsRumble": "Vibración",
"ControllerSettingsRumbleEnable": "Habilitar vibraciones",
"ControllerSettingsRumbleStrongMultiplier": "Multiplicador de vibraciones fuertes",
"ControllerSettingsRumbleWeakMultiplier": "Multiplicador de vibraciones débiles",
"DialogMessageSaveNotAvailableMessage": "No hay datos de guardado para {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "¿Quieres crear datos de guardado para este juego?",
"DialogConfirmationTitle": "Ryujinx - Confirmación",
"DialogUpdaterTitle": "Ryujinx - Actualizador",
"DialogErrorTitle": "Ryujinx - Error",
"DialogWarningTitle": "Ryujinx - Advertencia",
"DialogExitTitle": "Ryujinx - Salir",
"DialogErrorMessage": "Ryujinx encontró un error",
"DialogExitMessage": "¿Seguro que quieres cerrar Ryujinx?",
"DialogExitSubMessage": "¡Se perderán los datos no guardados!",
"DialogMessageCreateSaveErrorMessage": "Hubo un error al crear los datos de guardado especificados: {0}",
"DialogMessageFindSaveErrorMessage": "Hubo un error encontrando los datos de guardado especificados: {0}",
"FolderDialogExtractTitle": "Elige la carpeta en la que deseas extraer",
"DialogNcaExtractionMessage": "Extrayendo {0} sección de {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Extractor de sección NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Fallo de extracción. El NCA principal no estaba presente en el archivo seleccionado.",
"DialogNcaExtractionCheckLogErrorMessage": "Fallo de extracción. Lee el registro para más información.",
"DialogNcaExtractionSuccessMessage": "Se completó la extracción con éxito.",
"DialogUpdaterConvertFailedMessage": "No se pudo convertir la versión actual de Ryujinx.",
"DialogUpdaterCancelUpdateMessage": "¡Cancelando actualización!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "¡Ya tienes la versión más reciente de Ryujinx!",
"DialogUpdaterFailedToGetVersionMessage": "Ha ocurrido un error al intentar obtener información de versión desde AppVeyor.",
"DialogUpdaterConvertFailedAppveyorMessage": "No se pudo convertir la versión de Ryujinx recibida de AppVeyor.",
"DialogUpdaterDownloadingMessage": "Descargando actualización...",
"DialogUpdaterExtractionMessage": "Extrayendo actualización...",
"DialogUpdaterRenamingMessage": "Renombrando actualización...",
"DialogUpdaterAddingFilesMessage": "Aplicando actualización...",
"DialogUpdaterCompleteMessage": "¡Actualización completa!",
"DialogUpdaterRestartMessage": "¿Quieres reiniciar Ryujinx?",
"DialogUpdaterArchNotSupportedMessage": "¡Tu arquitectura de sistema no es compatible!",
"DialogUpdaterArchNotSupportedSubMessage": "(¡Solo son compatibles los sistemas x64!)",
"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://ryujinx.org/ si buscas una versión con soporte.",
"DialogRestartRequiredMessage": "Se necesita reiniciar",
"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 se encontró firmware instalado pero Ryujinx pudo instalar el firmware {0} a partir de este juego.\nA continuación, se iniciará el emulador.",
"DialogFirmwareNoFirmwareInstalledMessage": "No hay firmware instalado",
"DialogFirmwareInstalledMessage": "Se instaló el firmware {0}",
"DialogOpenSettingsWindowLabel": "Abrir ventana de opciones",
"DialogControllerAppletTitle": "Applet de mandos",
"DialogMessageDialogErrorExceptionMessage": "Error al mostrar cuadro de diálogo: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Error al mostrar teclado de software: {0}",
"DialogErrorAppletErrorExceptionMessage": "Error al mostrar díalogo ErrorApplet: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nPara más información sobre cómo arreglar este error, sigue nuestra Guía de Instalación.",
"DialogUserErrorDialogTitle": "Ryujinx Error ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "Ocurrió un error al recibir información de la API.",
"DialogAmiiboApiConnectErrorMessage": "No se pudo conectar al servidor de la API Amiibo. El servicio puede estar caído o tu conexión a internet puede haberse desconectado.",
"DialogProfileInvalidProfileErrorMessage": "El perfil {0} no es compatible con el sistema actual de configuración de entrada.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "El perfil predeterminado no se puede sobreescribir",
"DialogProfileDeleteProfileTitle": "Eliminando perfil",
"DialogProfileDeleteProfileMessage": "Esta acción es irreversible, ¿estás seguro de querer continuar?",
"DialogWarning": "Advertencia",
"DialogPPTCDeletionMessage": "Vas a borrar la caché de PPTC para:\n\n{0}\n\n¿Estás seguro de querer continuar?",
"DialogPPTCDeletionErrorMessage": "Error purgando la caché de PPTC en {0}: {1}",
"DialogShaderDeletionMessage": "Vas a borrar la caché de sombreadores para:\n\n{0}\n\n¿Estás seguro de querer continuar?",
"DialogShaderDeletionErrorMessage": "Error purgando la caché de sombreadores en {0}: {1}",
"DialogRyujinxErrorMessage": "Ryujinx ha encontrado un error",
"DialogInvalidTitleIdErrorMessage": "Error de interfaz: El juego seleccionado no tiene una ID válida",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "No se pudo encontrar un firmware válido en {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Instalar firmware {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "Se instalará la versión de sistema {0}.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nEsto reemplazará la versión de sistema actual, {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n¿Continuar?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Instalando firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versión de sistema {0} instalada con éxito.",
"DialogUserProfileDeletionWarningMessage": "Si eliminas el perfil seleccionado no quedará ningún otro perfil",
"DialogUserProfileDeletionConfirmMessage": "¿Quieres eliminar el perfil seleccionado?",
"DialogControllerSettingsModifiedConfirmMessage": "Se ha actualizado la configuración del mando actual.",
"DialogControllerSettingsModifiedConfirmSubMessage": "¿Guardar cambios?",
"DialogDlcLoadNcaErrorMessage": "{0}. Archivo con error: {1}",
"DialogDlcNoDlcErrorMessage": "¡Ese archivo no contiene contenido descargable para el título seleccionado!",
"DialogPerformanceCheckLoggingEnabledMessage": "Has habilitado los registros debug, diseñados solo para uso de los desarrolladores.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Para un rendimiento óptimo, se recomienda deshabilitar los registros debug. ¿Quieres deshabilitarlos ahora?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "Has habilitado el volcado de sombreadores, diseñado solo para uso de los desarrolladores.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Para un rendimiento óptimo, se recomienda deshabilitar el volcado de sombreadores. ¿Quieres deshabilitarlo ahora?",
"DialogLoadAppGameAlreadyLoadedMessage": "Ya has cargado un juego",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Por favor, detén la emulación o cierra el emulador antes de iniciar otro juego.",
"DialogUpdateAddUpdateErrorMessage": "¡Ese archivo no contiene una actualización para el título seleccionado!",
"DialogSettingsBackendThreadingWarningTitle": "Advertencia - multihilado de gráficos",
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx debe reiniciarse para aplicar este cambio. Dependiendo de tu plataforma, puede que tengas que desactivar manualmente la optimización enlazada de tus controladores gráficos para usar el multihilo de Ryujinx.",
"SettingsTabGraphicsFeaturesOptions": "Funcionalidades",
"SettingsTabGraphicsBackendMultithreading": "Multihilado del motor gráfico:",
"CommonAuto": "Auto",
"CommonOff": "Desactivado",
"CommonOn": "Activado",
"InputDialogYes": "Sí",
"InputDialogNo": "No",
"DialogProfileInvalidProfileNameErrorMessage": "El nombre de archivo contiene caracteres inválidos. Por favor, inténtalo de nuevo.",
"MenuBarOptionsPauseEmulation": "Pausar",
"MenuBarOptionsResumeEmulation": "Reanudar",
"AboutUrlTooltipMessage": "Haz clic para abrir el sitio web de Ryujinx en tu navegador predeterminado.",
"AboutDisclaimerMessage": "Ryujinx no tiene afiliación alguna con Nintendo™,\nni con ninguno de sus socios.",
"AboutAmiiboDisclaimerMessage": "Utilizamos AmiiboAPI (www.amiiboapi.com)\nen nuestra emulación de Amiibo.",
"AboutPatreonUrlTooltipMessage": "Haz clic para abrir el Patreon de Ryujinx en tu navegador predeterminado.",
"AboutGithubUrlTooltipMessage": "Haz clic para abrir el GitHub de Ryujinx en tu navegador predeterminado.",
"AboutDiscordUrlTooltipMessage": "Haz clic para recibir una invitación al Discord de Ryujinx en tu navegador predeterminado.",
"AboutTwitterUrlTooltipMessage": "Haz clic para abrir el Twitter de Ryujinx en tu navegador predeterminado.",
"AboutRyujinxAboutTitle": "Acerca de:",
"AboutRyujinxAboutContent": "Ryujinx es un emulador para Nintendo Switch™.\nPor favor, apóyanos en Patreon.\nEncuentra las noticias más recientes en nuestro Twitter o Discord.\nDesarrolladores interesados en contribuir pueden encontrar más información en GitHub o Discord.",
"AboutRyujinxMaintainersTitle": "Mantenido por:",
"AboutRyujinxMaintainersContentTooltipMessage": "Haz clic para abrir la página de contribuidores en tu navegador predeterminado.",
"AboutRyujinxSupprtersTitle": "Mecenas en Patreon:",
"AmiiboSeriesLabel": "Serie de Amiibo",
"AmiiboCharacterLabel": "Personaje",
"AmiiboScanButtonLabel": "Escanear",
"AmiiboOptionsShowAllLabel": "Mostrar todos los Amiibo",
"AmiiboOptionsUsRandomTagLabel": "Hack: usar etiqueta aleatoria Uuid",
"DlcManagerTableHeadingEnabledLabel": "Habilitado",
"DlcManagerTableHeadingTitleIdLabel": "ID de título",
"DlcManagerTableHeadingContainerPathLabel": "Directorio del contenedor",
"DlcManagerTableHeadingFullPathLabel": "Directorio completo",
"DlcManagerRemoveAllButton": "Quitar todo",
"MenuBarOptionsChangeLanguage": "Cambiar idioma",
"CommonSort": "Orden",
"CommonShowNames": "Mostrar nombres",
"CommonFavorite": "Favorito",
"OrderAscending": "Ascendente",
"OrderDescending": "Descendente",
"SettingsTabGraphicsFeatures": "Funcionalidades",
"ErrorWindowTitle": "Ventana de error",
"ToggleDiscordTooltip": "Activa o desactiva la presencia enriquecida de Discord",
"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",
"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": "Activa o desactiva el modo TV de la Nintendo Switch",
"DirectKeyboardTooltip": "Activa o desactiva \"soporte para acceso directo al teclado (HID)\" (Permite a los juegos utilizar tu teclado como entrada de texto)",
"DirectMouseTooltip": "Activa o desactiva \"soporte para acceso directo al ratón (HID)\" (Permite a los juegos utilizar tu ratón como cursor)",
"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": "Activa o desactiva la sincronización vertical",
"PptcToggleTooltip": "Activa o desactiva la caché de PPTC",
"FsIntegrityToggleTooltip": "Activa comprobaciones de integridad de los archivos de un juego",
"AudioBackendTooltip": "Cambia el motor de audio",
"MemoryManagerTooltip": "Cambia la forma de mapear y acceder a la memoria del guest. Afecta en gran medida al rendimiento de la CPU emulada.",
"MemoryManagerSoftwareTooltip": "Usa una tabla de paginación de software para traducir direcciones. Ofrece la precisión más exacta pero el rendimiento más lento.",
"MemoryManagerHostTooltip": "Mapea la memoria directamente en la dirección de espacio del host. Compilación y ejecución JIT mucho más rápida.",
"MemoryManagerUnsafeTooltip": "Mapea la memoria directamente, pero no enmascara la dirección dentro del espacio de dirección del guest antes del acceso. El modo más rápido, pero a costa de seguridad. La aplicación guest puede acceder a la memoria desde cualquier parte en Ryujinx, así que ejecuta solo programas en los que confíes cuando uses este modo.",
"DRamTooltip": "Expande la memoria DRAM del sistema emulado de 4GB a 6GB. Utilizar solo con mods 4K.",
"IgnoreMissingServicesTooltip": "Activa o desactiva un hack para ignorar servicios no implementados",
"GraphicsBackendThreadingTooltip": "Activa el multihilado del motor gráfico",
"GalThreadingTooltip": "Ejecuta los comandos del motor gráfico en un segundo hilo. Permite multihilar la compilación de sombreadores, reduce los tirones, y mejora el rendimiento en controladores gráficos sin necesidad de que utilicen su propio multihilado. Rendimiento máximo ligeramente variable en controladores gráficos que soporten multihilado. Ryujinx puede necesitar reiniciarse para desactivar correctamente el multihilado de tu controlador de gráficos, o puede que tengas que desactivarlo manualmente para lograr el mejor rendimiento posible.",
"ShaderCacheToggleTooltip": "Activa o desactiva la caché de sombreadores",
"ResolutionScaleTooltip": "Escala de resolución aplicada a objetivos aplicables en el renderizado",
"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": "Nivel de filtrado anisotrópico (selecciona Auto para utilizar el valor solicitado por el juego)",
"AspectRatioTooltip": "Relación de aspecto aplicada a la ventana de renderizado.",
"ShaderDumpPathTooltip": "Directorio en el cual se volcarán los sombreadores de los gráficos",
"FileLogTooltip": "Activa o desactiva el guardado de registros en archivos en disco",
"StubLogTooltip": "Activa mensajes de Stub en la consola",
"InfoLogTooltip": "Activa mensajes de Info en la consola",
"WarnLogTooltip": "Activa mensajes de Advertencia en la consola",
"ErrorLogTooltip": "Activa mensajes de Error en la consola",
"GuestLogTooltip": "Activa mensajes de Guest en la consola",
"FileAccessLogTooltip": "Activa mensajes de acceso a archivo en la consola",
"FSAccessLogModeTooltip": "Activa registros FS Access en la consola. Los modos posibles son entre 0 y 3",
"DeveloperOptionTooltip": "Usar con cuidado",
"OpenGlLogLevel": "Requiere activar los niveles de registro apropiados",
"DebugLogTooltip": "Activa mensajes de debug en la consola",
"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",
"OpenRyujinxFolderTooltip": "Abre la carpeta de sistema de Ryujinx",
"OpenRyujinxLogsTooltip": "Abre la carpeta en la que se guardan los registros",
"ExitTooltip": "Cierra Ryujinx",
"OpenSettingsTooltip": "Abre la ventana de configuración",
"OpenProfileManagerTooltip": "Abre la ventana para gestionar los perfiles de usuario",
"StopEmulationTooltip": "Detiene la emulación del juego actual y regresa a la selección de juegos",
"CheckUpdatesTooltip": "Busca actualizaciones para Ryujinx",
"OpenAboutTooltip": "Abre la ventana \"Acerca de\"",
"GridSize": "Tamaño de cuadrícula",
"GridSizeTooltip": "Cambia el tamaño de los objetos en la cuadrícula",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Portugués brasileño",
"AboutRyujinxContributorsButtonHeader" : "Ver todos los contribuidores",
"SettingsTabSystemAudioVolume": "Volumen: ",
"AudioVolumeTooltip": "Ajusta el nivel de volumen",
"SettingsTabSystemEnableInternetAccess": "Habilitar acceso a Internet del guest",
"EnableInternetAccessTooltip": "Activa el acceso a Internet del guest. Cuando esté activo, la aplicación actuará como si la Nintendo Switch emulada estuviese conectada a Internet. Ten en cuenta que algunas aplicaciones pueden intentar acceder a Internet incluso con esta opción desactivada.",
"GameListContextMenuManageCheatToolTip" : "Activa o desactiva los cheats",
"GameListContextMenuManageCheat" : "Administrar cheats",
"ControllerSettingsStickRange" : "Alcance",
"DialogStopEmulationTitle" : "Ryujinx - Detener emulación",
"DialogStopEmulationMessage": "¿Seguro que quieres detener la emulación actual?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "Audio",
"SettingsTabNetwork": "Red",
"SettingsTabNetworkConnection" : "Conexión de red",
"SettingsTabGraphicsFrameRate" : "Velocidad máxima de fotogramas:",
"SettingsTabGraphicsFrameRateTooltip" : "Fija el límite de fotogramas del host. Elige 0 para deshabilitar el límite.",
"SettingsTabCpuCache" : "Caché de CPU",
"SettingsTabCpuMemory" : "Memoria de CPU"
}

View file

@ -0,0 +1,270 @@
{
"MenuBarFile": "_Fichier",
"MenuBarFileOpenFromFile": "_Charger un jeu depuis un fichier",
"MenuBarFileOpenUnpacked": "Charger un jeu _extrait",
"MenuBarFileOpenEmuFolder": "Ouvrir le dossier Ryujinx",
"MenuBarFileOpenLogsFolder": "Ouvrir le dossier de Logs",
"MenuBarFileExit": "_Quitter",
"MenuBarOptions": "Options",
"MenuBarOptionsToggleFullscreen": "Basculer en plein écran",
"MenuBarOptionsStartGamesInFullscreen": "Démarrer le jeu en plein écran",
"MenuBarOptionsStopEmulation": "Arrêter l'émulation",
"MenuBarOptionsSettings": "_Paramètres",
"MenuBarOptionsManageUserProfiles": "_Gêrer les profils d'utilisateurs",
"MenuBarActions": "_Actions",
"MenuBarOptionsSimulateWakeUpMessage": "Simuler une sortie de veille",
"MenuBarActionsScanAmiibo": "Scanner un Amiibo",
"MenuBarTools": "_Outils",
"MenuBarToolsInstallFirmware": "Installer un firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Installer un firmware depuis un fichier XCI ou ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Installer un firmware depuis un dossier",
"MenuBarHelp": "Aide",
"MenuBarHelpCheckForUpdates": "Vérifier les mises à jour",
"MenuBarHelpAbout": "Á propos",
"MenuSearch": "Rechercher...",
"GameListHeaderFavorite": "Favoris",
"GameListHeaderIcon": "Icône",
"GameListHeaderApplication": "Application",
"GameListHeaderDeveloper": "Développeur",
"GameListHeaderVersion": "Version",
"GameListHeaderTimePlayed": "Temps de jeu",
"GameListHeaderLastPlayed": "Dernière partie",
"GameListHeaderFileExtension": "Extension du Fichier",
"GameListHeaderFileSize": "Taille du Fichier",
"GameListHeaderPath": "Chemin",
"GameListContextMenuOpenUserSaveDirectory": "Ouvrir le dossier de sauvegarde utilisateur",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Ouvre le dossier contenant la sauvegarde utilisateur du jeu",
"GameListContextMenuOpenUserDeviceDirectory": "Ouvrir le dossier de sauvegarde console",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Ouvre le dossier contenant la sauvegarde console du jeu",
"GameListContextMenuOpenUserBcatDirectory": "Ouvrir le dossier de sauvegarde BCAT",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Ouvre le dossier contenant la sauvegarde BCAT du jeu",
"GameListContextMenuManageTitleUpdates": "Gérer les mises à jour",
"GameListContextMenuManageTitleUpdatesToolTip": "Ouvre la fenêtre de gestion des mises à jour",
"GameListContextMenuManageDlc": "Gérer les DLC",
"GameListContextMenuManageDlcToolTip": "Ouvre la fenêtre de gestion des DLC",
"GameListContextMenuOpenModsDirectory": "Ouvrir le dossier des Mods",
"GameListContextMenuOpenModsDirectoryToolTip": "Ouvre le dossier contenant les mods du jeu",
"GameListContextMenuCacheManagement": "Gestion des caches",
"GameListContextMenuCacheManagementPurgePptc": "Purger le PPTC",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Supprime le PPTC du jeu",
"GameListContextMenuCacheManagementPurgeShaderCache": "Purger le cache des Shaders",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Supprime le cache des shaders du jeu",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Ouvrir le dossier du PPTC",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Ouvre le dossier contenant le PPTC du jeu",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Ouvrir le dossier du cache des shaders",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Ouvre le dossier contenant le cache des shaders du jeu",
"GameListContextMenuExtractData": "Extraire les données",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Extrait la section ExeFS du jeu (mise à jour incluse)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Extrait la section RomFS du jeu (mise à jour incluse)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Extrait la section Logo du jeu (mise à jour incluse)",
"StatusBarGamesLoaded": "{0}/{1} Jeux chargés",
"StatusBarSystemVersion": "Version du Firmware: {0}",
"Settings": "Paramètres",
"SettingsTabGeneral": "Général",
"SettingsTabGeneralGeneral": "Général",
"SettingsTabGeneralEnableDiscordRichPresence": "Active Discord Rich Presence",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Vérifier les mises à jour au démarrage",
"SettingsTabGeneralShowConfirmExitDialog": "Afficher le message de \"Confirmation de fermeture\"",
"SettingsTabGeneralHideCursorOnIdle": "Masquer le curseur si inactif",
"SettingsTabGeneralGameDirectories": "Dossiers de Jeux",
"SettingsTabGeneralAdd": "Ajouter",
"SettingsTabGeneralRemove": "Supprimer",
"SettingsTabSystem": "Système",
"SettingsTabSystemCore": "Core",
"SettingsTabSystemSystemRegion": "Région du système:",
"SettingsTabSystemSystemRegionJapan": "Japon",
"SettingsTabSystemSystemRegionUSA": "USA",
"SettingsTabSystemSystemRegionEurope": "Europe",
"SettingsTabSystemSystemRegionAustralia": "Australie",
"SettingsTabSystemSystemRegionChina": "Chine",
"SettingsTabSystemSystemRegionKorea": "Corée",
"SettingsTabSystemSystemRegionTaiwan": "Taïwan",
"SettingsTabSystemSystemLanguage": "Langue du système:",
"SettingsTabSystemSystemLanguageJapanese": "Japonais",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Américain",
"SettingsTabSystemSystemLanguageFrench": "Français",
"SettingsTabSystemSystemLanguageGerman": "Allemand",
"SettingsTabSystemSystemLanguageItalian": "Italien",
"SettingsTabSystemSystemLanguageSpanish": "Espagnol",
"SettingsTabSystemSystemLanguageChinese": "Chinois",
"SettingsTabSystemSystemLanguageKorean": "Coréen",
"SettingsTabSystemSystemLanguageDutch": "Néerlandais",
"SettingsTabSystemSystemLanguagePortuguese": "Portugais",
"SettingsTabSystemSystemLanguageRussian": "Russe",
"SettingsTabSystemSystemLanguageTaiwanese": "Taïwanais",
"SettingsTabSystemSystemLanguageBritishEnglish": "Anglais",
"SettingsTabSystemSystemLanguageCanadianFrench": "Canadien",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Espagnol latino-américain",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Chinois simplifié",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Chinois traditionnel",
"SettingsTabSystemSystemTimeZone": "Fuseau horaire du système:",
"SettingsTabSystemSystemTime": "Heure du système:",
"SettingsTabSystemEnableVsync": "Activer la VSync",
"SettingsTabSystemEnablePptc": "Activer le PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Activer la vérification de l'intégrité du système de fichiers",
"SettingsTabSystemAudioBackend": "Bibliothèque Audio:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": " - Cela peut causer des instabilitées",
"SettingsTabSystemExpandDramSize": "Augmenter la taille de la DRAM à 6GB",
"SettingsTabSystemIgnoreMissingServices": "Ignorer les services manquant",
"SettingsTabGraphics": "Graphique",
"SettingsTabGraphicsEnhancements": "Améliorations",
"SettingsTabGraphicsEnableShaderCache": "Activer le cache des shaders",
"SettingsTabGraphicsAnisotropicFiltering": "Filtrage anisotrope:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Échelle de résolution:",
"SettingsTabGraphicsResolutionScaleCustom": "Customisée (Non recommandée)",
"SettingsTabGraphicsResolutionScaleNative": "Native (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Format:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Écran étiré",
"SettingsTabGraphicsDeveloperOptions": "Options développeur",
"SettingsTabGraphicsShaderDumpPath": "Chemin du dossier de dump des shaders:",
"SettingsTabLogging": "Journaux",
"SettingsTabLoggingLogging": "Journaux",
"SettingsTabLoggingEnableLoggingToFile": "Activer la sauvegarde des journaux vers un fichier",
"SettingsTabLoggingEnableStubLogs": "Activer les journaux stub",
"SettingsTabLoggingEnableInfoLogs": "Activer les journaux d'informations",
"SettingsTabLoggingEnableWarningLogs": "Activer les journaux d'avertissements",
"SettingsTabLoggingEnableErrorLogs": "Activer les journaux d'erreurs",
"SettingsTabLoggingEnableGuestLogs": "Activer les journaux du programme simulé",
"SettingsTabLoggingEnableFsAccessLogs": "Activer les journaux des accès au système de fichiers",
"SettingsTabLoggingFsGlobalAccessLogMode": "Niveau des journaux des accès au système de fichiers:",
"SettingsTabLoggingDeveloperOptions": "Options développeur (ATTENTION: Cela peut réduire les performances)",
"SettingsTabLoggingOpenglLogLevel": "Niveau des journaux OpenGL:",
"SettingsTabLoggingOpenglLogLevelNone": "Aucun",
"SettingsTabLoggingOpenglLogLevelError": "Erreur",
"SettingsTabLoggingOpenglLogLevelPerformance": "Ralentissements",
"SettingsTabLoggingOpenglLogLevelAll": "Tout",
"SettingsTabLoggingEnableDebugLogs": "Activer les journaux de debug",
"SettingsTabInput": "Contrôles",
"SettingsTabInputEnableDockedMode": "Active le mode station d'accueil",
"SettingsTabInputDirectKeyboardAccess": "Accès direct au clavier",
"SettingsButtonSave": "Enregistrer",
"SettingsButtonClose": "Fermer",
"SettingsButtonApply": "Appliquer",
"ControllerSettingsPlayer": "Joueur",
"ControllerSettingsPlayer1": "Joueur 1",
"ControllerSettingsPlayer2": "Joueur 2",
"ControllerSettingsPlayer3": "Joueur 3",
"ControllerSettingsPlayer4": "Joueur 4",
"ControllerSettingsPlayer5": "Joueur 5",
"ControllerSettingsPlayer6": "Joueur 6",
"ControllerSettingsPlayer7": "Joueur 7",
"ControllerSettingsPlayer8": "Joueur 8",
"ControllerSettingsHandheld": "Portable",
"ControllerSettingsInputDevice": "Périphériques",
"ControllerSettingsRefresh": "Actualiser",
"ControllerSettingsDeviceDisabled": "Désactivé",
"ControllerSettingsControllerType": "Type de Controleur",
"ControllerSettingsControllerTypeHandheld": "Portable",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "JoyCon Joints",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Gauche",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon Droite",
"ControllerSettingsProfile": "Profil",
"ControllerSettingsProfileDefault": "Défaut",
"ControllerSettingsLoad": "Charger",
"ControllerSettingsAdd": "Ajouter",
"ControllerSettingsRemove": "Supprimer",
"ControllerSettingsButtons": "Boutons",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Croix Directionnelle",
"ControllerSettingsDPadUp": "Haut",
"ControllerSettingsDPadDown": "Bas",
"ControllerSettingsDPadLeft": "Gauche",
"ControllerSettingsDPadRight": "Droite",
"ControllerSettingsLStick": "Joystick Gauche",
"ControllerSettingsLStickButton": "Bouton",
"ControllerSettingsLStickUp": "Haut",
"ControllerSettingsLStickDown": "Bas",
"ControllerSettingsLStickLeft": "Gauche",
"ControllerSettingsLStickRight": "Droite",
"ControllerSettingsLStickStick": "Joystick",
"ControllerSettingsLStickInvertXAxis": "Inverser l'axe X",
"ControllerSettingsLStickInvertYAxis": "Inverser l'axe Y",
"ControllerSettingsLStickDeadzone": "Zone morte:",
"ControllerSettingsRStick": "Joystick Droit",
"ControllerSettingsRStickButton": "Bouton",
"ControllerSettingsRStickUp": "Haut",
"ControllerSettingsRStickDown": "Bas",
"ControllerSettingsRStickLeft": "Gauche",
"ControllerSettingsRStickRight": "Droite",
"ControllerSettingsRStickStick": "Joystick",
"ControllerSettingsRStickInvertXAxis": "Inverser l'axe X",
"ControllerSettingsRStickInvertYAxis": "Inverser l'axe Y",
"ControllerSettingsRStickDeadzone": "Zone morte:",
"ControllerSettingsTriggers": "Gachettes",
"ControllerSettingsTriggersLeft": "Gachettes Gauche",
"ControllerSettingsTriggersRight": "Gachettes Droite",
"ControllerSettingsTriggersButtonsLeft": "Boutons Gachettes Gauche",
"ControllerSettingsTriggersButtonsRight": "Boutons Gachettes Droite",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Boutons Gauche",
"ControllerSettingsExtraButtonsRight": "Boutons Droite",
"ControllerSettingsMisc": "Divers",
"ControllerSettingsTriggerThreshold": "Seuil de gachettes:",
"ControllerSettingsMotion": "Mouvements",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Activer le capteur de mouvements",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Utiliser un capteur de mouvements CemuHook",
"ControllerSettingsMotionControllerSlot": "Contrôleur ID:",
"ControllerSettingsMotionMirrorInput": "Inverser les contrôles",
"ControllerSettingsMotionRightJoyConSlot": "JoyCon Droit ID:",
"ControllerSettingsMotionServerHost": "Addresse du Server:",
"ControllerSettingsMotionGyroSensitivity": "Sensibilitée du gyroscope:",
"ControllerSettingsMotionGyroDeadzone": "Zone morte du gyroscope:",
"ControllerSettingsSave": "Enregistrer",
"ControllerSettingsClose": "Fermer",
"UserProfilesSelectedUserProfile": "Choisir un profil utilisateur:",
"UserProfilesSaveProfileName": "Enregistrer le nom du profil",
"UserProfilesChangeProfileImage": "Changer l'image du profil",
"UserProfilesAvailableUserProfiles": "Profils utilisateurs disponible:",
"UserProfilesAddNewProfile": "Ajouter un nouveau profil",
"UserProfilesDeleteSelectedProfile": "Supprimer le profil sélectionné",
"UserProfilesClose": "Fermer",
"ProfileImageSelectionTitle": "Sélection de l'image du profil",
"ProfileImageSelectionHeader": "Choisir l'image du profil",
"ProfileImageSelectionNote": "Vous pouvez importer une image de profil personnalisée ou sélectionner un avatar à partir du firmware",
"ProfileImageSelectionImportImage": "Importer une image",
"ProfileImageSelectionSelectAvatar": "Choisir un avatar du firmware",
"InputDialogTitle": "Fenêtre d'entrée de texte",
"InputDialogOk": "OK",
"InputDialogCancel": "Annuler",
"InputDialogAddNewProfileTitle": "Choisir un nom de profil",
"InputDialogAddNewProfileHeader": "Merci d'entrer un nom de profil",
"InputDialogAddNewProfileSubtext": "(Longueur max.: {0})",
"AvatarChoose": "Choisir",
"AvatarSetBackgroundColor": "Choisir une couleur de fond",
"AvatarClose": "Fermer"
}

View file

@ -0,0 +1,547 @@
{
"MenuBarFileOpenApplet": "Apri applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Apri l'editor Mii in modalità standalone",
"SettingsTabInputDirectMouseAccess": "Accesso diretto al mouse",
"SettingsTabSystemMemoryManagerMode": "Modalità di gestione della memoria:",
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
"SettingsTabSystemMemoryManagerModeHost": "Host (veloce)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Unchecked (più veloce, non sicura)",
"MenuBarFile": "_File",
"MenuBarFileOpenFromFile": "_Carica applicazione da un file",
"MenuBarFileOpenUnpacked": "Carica _gioco estratto",
"MenuBarFileOpenEmuFolder": "Apri cartella di Ryujinx",
"MenuBarFileOpenLogsFolder": "Apri cartella dei logs",
"MenuBarFileExit": "_Esci",
"MenuBarOptions": "Opzioni",
"MenuBarOptionsToggleFullscreen": "Schermo intero",
"MenuBarOptionsStartGamesInFullscreen": "Avvia i giochi a schermo intero",
"MenuBarOptionsStopEmulation": "Ferma emulazione",
"MenuBarOptionsSettings": "_Impostazioni",
"MenuBarOptionsManageUserProfiles": "_Gestisci i profili utente",
"MenuBarActions": "_Azioni",
"MenuBarOptionsSimulateWakeUpMessage": "Simula messaggio Wake-up",
"MenuBarActionsScanAmiibo": "Scansiona un Amiibo",
"MenuBarTools": "_Strumenti",
"MenuBarToolsInstallFirmware": "Installa firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Installa un firmware da file XCI o ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Installa un firmare da una cartella",
"MenuBarHelp": "Aiuto",
"MenuBarHelpCheckForUpdates": "Controlla aggiornamenti",
"MenuBarHelpAbout": "Informazioni",
"MenuSearch": "Cerca...",
"GameListHeaderFavorite": "Pref",
"GameListHeaderIcon": "Icona",
"GameListHeaderApplication": "Nome",
"GameListHeaderDeveloper": "Sviluppatore",
"GameListHeaderVersion": "Versione",
"GameListHeaderTimePlayed": "Tempo di gioco",
"GameListHeaderLastPlayed": "Giocato l'ultima volta",
"GameListHeaderFileExtension": "Estensione",
"GameListHeaderFileSize": "Dimensione file",
"GameListHeaderPath": "Percorso",
"GameListContextMenuOpenUserSaveDirectory": "Apri la cartella salvataggi dell'utente",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Apre la cartella che contiene i salvataggi di gioco dell'utente",
"GameListContextMenuOpenUserDeviceDirectory": "Apri la cartella dispositivo dell'utente",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Apre la cartella che contiene i salvataggi di gioco del dispositivo",
"GameListContextMenuOpenUserBcatDirectory": "Apri la cartella BCAT dell'utente",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Apre la cartella che contiene i salvataggi BCAT dell'applicazione",
"GameListContextMenuManageTitleUpdates": "Gestisci aggiornamenti del gioco",
"GameListContextMenuManageTitleUpdatesToolTip": "Apre la finestra di gestione aggiornamenti del gioco",
"GameListContextMenuManageDlc": "Gestici DLC",
"GameListContextMenuManageDlcToolTip": "Apre la finestra di gestione DLC",
"GameListContextMenuOpenModsDirectory": "Apri cartella delle mods",
"GameListContextMenuOpenModsDirectoryToolTip": "Apre la cartella che contiene le mods dell'applicazione",
"GameListContextMenuCacheManagement": "Gestione della cache",
"GameListContextMenuCacheManagementPurgePptc": "Pulisci PPTC cache",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Elimina la PPTC cache dell'applicazione",
"GameListContextMenuCacheManagementPurgeShaderCache": "Pulisci shader cache",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Elimina la shader cache dell'applicazione",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Apri cartella PPTC",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Apre la cartella che contiene la PPTC cache dell'applicazione",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Apri cartella shader cache",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Apre la cartella che contiene la shader cache dell'applicazione",
"GameListContextMenuExtractData": "Estrai dati",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Estrae la sezione ExeFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Estrae la sezione RomFS dall'attuale configurazione dell'applicazione (includendo aggiornamenti)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Estrae la sezione Logo dall'attuale configurazione dell'applicazione (includendo aggiornamenti)",
"StatusBarGamesLoaded": "{0}/{1} Giochi caricati",
"StatusBarSystemVersion": "Versione di sistema: {0}",
"Settings": "Impostazioni",
"SettingsTabGeneral": "Interfaccia utente",
"SettingsTabGeneralGeneral": "Generali",
"SettingsTabGeneralEnableDiscordRichPresence": "Attiva Discord Rich Presence",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Controlla aggiornamenti all'avvio",
"SettingsTabGeneralShowConfirmExitDialog": "Mostra dialogo \"Conferma Uscita\"",
"SettingsTabGeneralHideCursorOnIdle": "Nascondi cursore inattivo",
"SettingsTabGeneralGameDirectories": "Cartelle dei giochi",
"SettingsTabGeneralAdd": "Aggiungi",
"SettingsTabGeneralRemove": "Rimuovi",
"SettingsTabSystem": "Sistema",
"SettingsTabSystemCore": "Core",
"SettingsTabSystemSystemRegion": "Regione di sistema:",
"SettingsTabSystemSystemRegionJapan": "Giappone",
"SettingsTabSystemSystemRegionUSA": "Stati Uniti d'America",
"SettingsTabSystemSystemRegionEurope": "Europa",
"SettingsTabSystemSystemRegionAustralia": "Australia",
"SettingsTabSystemSystemRegionChina": "Cina",
"SettingsTabSystemSystemRegionKorea": "Corea",
"SettingsTabSystemSystemRegionTaiwan": "Taiwan",
"SettingsTabSystemSystemLanguage": "Lingua di sistema:",
"SettingsTabSystemSystemLanguageJapanese": "Giapponese",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Inglese americano",
"SettingsTabSystemSystemLanguageFrench": "Francese",
"SettingsTabSystemSystemLanguageGerman": "Tedesco",
"SettingsTabSystemSystemLanguageItalian": "Italiano",
"SettingsTabSystemSystemLanguageSpanish": "Spagnolo",
"SettingsTabSystemSystemLanguageChinese": "Cinese",
"SettingsTabSystemSystemLanguageKorean": "Coreano",
"SettingsTabSystemSystemLanguageDutch": "Olandese",
"SettingsTabSystemSystemLanguagePortuguese": "Portoghese",
"SettingsTabSystemSystemLanguageRussian": "Russo",
"SettingsTabSystemSystemLanguageTaiwanese": "Taiwanese",
"SettingsTabSystemSystemLanguageBritishEnglish": "Inglese britannico",
"SettingsTabSystemSystemLanguageCanadianFrench": "Francese canadese",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Spagnolo latino americano",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Cinese semplificato",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Cinese tradizionale",
"SettingsTabSystemSystemTimeZone": "Fuso orario di sistema:",
"SettingsTabSystemSystemTime": "Data e ora di sistema:",
"SettingsTabSystemEnableVsync": "Attiva VSync",
"SettingsTabSystemEnablePptc": "Attiva PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Attiva controlli d'integrità FS",
"SettingsTabSystemAudioBackend": "Backend audio:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": " - Possono causare instabilità",
"SettingsTabSystemExpandDramSize": "Espandi dimensione DRAM a 6GB",
"SettingsTabSystemIgnoreMissingServices": "Ignora servizi mancanti",
"SettingsTabGraphics": "Grafica",
"SettingsTabGraphicsEnhancements": "Miglioramenti",
"SettingsTabGraphicsEnableShaderCache": "Attiva Shader Cache",
"SettingsTabGraphicsAnisotropicFiltering": "Filtro anisotropico:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Scala della risoluzione:",
"SettingsTabGraphicsResolutionScaleCustom": "Personalizzata (Non raccomandata)",
"SettingsTabGraphicsResolutionScaleNative": "Nativa (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Rapporto d'aspetto:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Adatta alla finestra",
"SettingsTabGraphicsDeveloperOptions": "Opzioni da sviluppatore",
"SettingsTabGraphicsShaderDumpPath": "Percorso di dump degli shaders:",
"SettingsTabLogging": "Log",
"SettingsTabLoggingLogging": "Log",
"SettingsTabLoggingEnableLoggingToFile": "Salva i log su file",
"SettingsTabLoggingEnableStubLogs": "Attiva Stub Logs",
"SettingsTabLoggingEnableInfoLogs": "Attiva Info Logs",
"SettingsTabLoggingEnableWarningLogs": "Attiva Warning Logs",
"SettingsTabLoggingEnableErrorLogs": "Attiva Error Logs",
"SettingsTabLoggingEnableTraceLogs": "Attiva Trace Logs",
"SettingsTabLoggingEnableGuestLogs": "Attiva Guest Logs",
"SettingsTabLoggingEnableFsAccessLogs": "Attiva Fs Access Logs",
"SettingsTabLoggingFsGlobalAccessLogMode": "Modalità di log accesso globale Fs:",
"SettingsTabLoggingDeveloperOptions": "Opzioni da sviluppatore (AVVISO: Ridurrà le prestazioni)",
"SettingsTabLoggingOpenglLogLevel": "Livello di log OpenGL:",
"SettingsTabLoggingOpenglLogLevelNone": "Nessuno",
"SettingsTabLoggingOpenglLogLevelError": "Errore",
"SettingsTabLoggingOpenglLogLevelPerformance": "Rallentamenti",
"SettingsTabLoggingOpenglLogLevelAll": "Tutto",
"SettingsTabLoggingEnableDebugLogs": "Attiva logs di debug",
"SettingsTabInput": "Input",
"SettingsTabInputEnableDockedMode": "Attiva modalità TV",
"SettingsTabInputDirectKeyboardAccess": "Accesso diretto alla tastiera",
"SettingsButtonSave": "Salva",
"SettingsButtonClose": "Chiudi",
"SettingsButtonApply": "Applica",
"ControllerSettingsPlayer": "Giocatore",
"ControllerSettingsPlayer1": "Giocatore 1",
"ControllerSettingsPlayer2": "Giocatore 2",
"ControllerSettingsPlayer3": "Giocatore 3",
"ControllerSettingsPlayer4": "Giocatore 4",
"ControllerSettingsPlayer5": "Giocatore 5",
"ControllerSettingsPlayer6": "Giocatore 6",
"ControllerSettingsPlayer7": "Giocatore 7",
"ControllerSettingsPlayer8": "Giocatore 8",
"ControllerSettingsHandheld": "Portatile",
"ControllerSettingsInputDevice": "Dispositivo di input",
"ControllerSettingsRefresh": "Ricarica",
"ControllerSettingsDeviceDisabled": "Disabilitato",
"ControllerSettingsControllerType": "Tipo di controller",
"ControllerSettingsControllerTypeHandheld": "Portatile",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "Coppia di JoyCon",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon sinistro",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon destro",
"ControllerSettingsProfile": "Profilo",
"ControllerSettingsProfileDefault": "Predefinito",
"ControllerSettingsLoad": "Carica",
"ControllerSettingsAdd": "Aggiungi",
"ControllerSettingsRemove": "Rimuovi",
"ControllerSettingsButtons": "Pulsanti",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Croce direzionale",
"ControllerSettingsDPadUp": "Su",
"ControllerSettingsDPadDown": "Giù",
"ControllerSettingsDPadLeft": "Sinistra",
"ControllerSettingsDPadRight": "Destra",
"ControllerSettingsLStick": "Stick sinistro",
"ControllerSettingsLStickButton": "Pulsante",
"ControllerSettingsLStickUp": "Su",
"ControllerSettingsLStickDown": "Giù",
"ControllerSettingsLStickLeft": "Sinistra",
"ControllerSettingsLStickRight": "Destra",
"ControllerSettingsLStickStick": "Stick",
"ControllerSettingsLStickInvertXAxis": "Inverti stick X",
"ControllerSettingsLStickInvertYAxis": "Inverti stick Y",
"ControllerSettingsLStickDeadzone": "Zona morta:",
"ControllerSettingsRStick": "Stick destro",
"ControllerSettingsRStickButton": "Pulsante",
"ControllerSettingsRStickUp": "Su",
"ControllerSettingsRStickDown": "Giù",
"ControllerSettingsRStickLeft": "Sinistra",
"ControllerSettingsRStickRight": "Destra",
"ControllerSettingsRStickStick": "Stick",
"ControllerSettingsRStickInvertXAxis": "Inverti stick X",
"ControllerSettingsRStickInvertYAxis": "Inverti stick Y",
"ControllerSettingsRStickDeadzone": "Zona morta:",
"ControllerSettingsTriggersLeft": "Grilletto sinistro",
"ControllerSettingsTriggersRight": "Grilletto destro",
"ControllerSettingsTriggersButtonsLeft": "Pulsante dorsale sinistro",
"ControllerSettingsTriggersButtonsRight": "Pulsante dorsale destro",
"ControllerSettingsTriggers": "Grilletti",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Tasto sinitro",
"ControllerSettingsExtraButtonsRight": "Tasto destro",
"ControllerSettingsMisc": "Miscellanee",
"ControllerSettingsTriggerThreshold": "Sensibilità dei grilletti:",
"ControllerSettingsMotion": "Movimento",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Attiva sensore di movimento",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Usa sensore compatibile con CemuHook",
"ControllerSettingsMotionControllerSlot": "Slot del controller:",
"ControllerSettingsMotionMirrorInput": "Input specchiato",
"ControllerSettingsMotionRightJoyConSlot": "Slot JoyCon destro:",
"ControllerSettingsMotionServerHost": "Server:",
"ControllerSettingsMotionGyroSensitivity": "Sensibilità del giroscopio:",
"ControllerSettingsMotionGyroDeadzone": "Zona morta del giroscopio:",
"ControllerSettingsSave": "Salva",
"ControllerSettingsClose": "Chiudi",
"UserProfilesSelectedUserProfile": "Profilo utente selezionato:",
"UserProfilesSaveProfileName": "Salva nome del profilo",
"UserProfilesChangeProfileImage": "Cambia immagine profilo",
"UserProfilesAvailableUserProfiles": "Profili utente disponibili:",
"UserProfilesAddNewProfile": "Aggiungi nuovo profilo",
"UserProfilesDeleteSelectedProfile": "Elimina il profilo selezionato",
"UserProfilesClose": "Chiudi",
"ProfileImageSelectionTitle": "Selezione dell'immagine profilo",
"ProfileImageSelectionHeader": "Scegli un'immagine profilo",
"ProfileImageSelectionNote": "Puoi importare un'immagine profilo personalizzata o selezionare un avatar dal firmware di sistema",
"ProfileImageSelectionImportImage": "Importa file immagine",
"ProfileImageSelectionSelectAvatar": "Seleziona avatar dal firmware",
"InputDialogTitle": "Input Dialog",
"InputDialogOk": "OK",
"InputDialogCancel": "Annulla",
"InputDialogAddNewProfileTitle": "Scegli il nome profilo",
"InputDialogAddNewProfileHeader": "Digita un nome profilo",
"InputDialogAddNewProfileSubtext": "(Lunghezza massima: {0})",
"AvatarChoose": "Scegli",
"AvatarSetBackgroundColor": "Imposta colore di sfondo",
"AvatarClose": "Chiudi",
"ControllerSettingsLoadProfileToolTip": "Carica profilo",
"ControllerSettingsAddProfileToolTip": "Aggiungi profilo",
"ControllerSettingsRemoveProfileToolTip": "Rimuovi profilo",
"ControllerSettingsSaveProfileToolTip": "Salva profilo",
"MenuBarFileToolsTakeScreenshot": "Fai uno screenshot",
"MenuBarFileToolsHideUi": "Nascondi Ui",
"GameListContextMenuToggleFavorite": "Preferito",
"GameListContextMenuToggleFavoriteToolTip": "Segna il gioco come preferito",
"SettingsTabGeneralTheme": "Tema",
"SettingsTabGeneralThemeCustomTheme": "Percorso del tema personalizzato",
"SettingsTabGeneralThemeBaseStyle": "Modalità",
"SettingsTabGeneralThemeBaseStyleDark": "Scura",
"SettingsTabGeneralThemeBaseStyleLight": "Chiara",
"SettingsTabGeneralThemeEnableCustomTheme": "Attiva tema personalizzato",
"ButtonBrowse": "Sfoglia",
"ControllerSettingsMotionConfigureCemuHookSettings": "Configura movimento CemuHook",
"ControllerSettingsRumble": "Vibrazione",
"ControllerSettingsRumbleEnable": "Attiva vibrazione",
"ControllerSettingsRumbleStrongMultiplier": "Moltiplicatore vibrazione forte",
"ControllerSettingsRumbleWeakMultiplier": "Moltiplicatore vibrazione debole",
"DialogMessageSaveNotAvailableMessage": "Non ci sono dati di salvataggio per {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Vuoi creare dei dat di salvataggio per questo gioco?",
"DialogConfirmationTitle": "Ryujinx - Conferma",
"DialogUpdaterTitle": "Ryujinx - Updater",
"DialogErrorTitle": "Ryujinx - Errore",
"DialogWarningTitle": "Ryujinx - Avviso",
"DialogExitTitle": "Ryujinx - Uscita",
"DialogErrorMessage": "Ryujinx ha riscontrato un problema",
"DialogExitMessage": "Sei sicuro di voler chiudere Ryujinx?",
"DialogExitSubMessage": "Tutti i dati non salvati andranno persi!",
"DialogMessageCreateSaveErrorMessage": "C'è stato un errore durante la creazione dei dati di salvataggio: {0}",
"DialogMessageFindSaveErrorMessage": "C'è stato un errore durante la ricerca dei dati di salvataggio: {0}",
"FolderDialogExtractTitle": "Scegli una cartella in cui estrarre",
"DialogNcaExtractionMessage": "Estrazione della sezione {0} da {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Estrattore sezione NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "L'estrazione è fallita. L'NCA principale non era presente nel file selezionato.",
"DialogNcaExtractionCheckLogErrorMessage": "L'estrazione è fallita. Leggi il log per più informazioni.",
"DialogNcaExtractionSuccessMessage": "Estrazione completata con successo.",
"DialogUpdaterConvertFailedMessage": "La conversione dell'attuale versione di Ryujinx è fallita.",
"DialogUpdaterCancelUpdateMessage": "Annullando l'aggiornamento!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "Stai già usando la versione più recente di Ryujinx!",
"DialogUpdaterFailedToGetVersionMessage": "Si è verificato un errore nel tentativo di ottenere informazioni da Github Release. Questo può verificarsi se una nuova release è in compilazione su GitHub Actions. Riprova tra qualche minuto.",
"DialogUpdaterConvertFailedGithubMessage": "La conversione della versione di Ryujinx ricevuta da Github Release è fallita.",
"DialogUpdaterDownloadingMessage": "Download dell'aggiornamento...",
"DialogUpdaterExtractionMessage": "Estrazione dell'aggiornamento...",
"DialogUpdaterRenamingMessage": "Rinominazione dell'aggiornamento...",
"DialogUpdaterAddingFilesMessage": "Aggiunta nuovo aggiornamento...",
"DialogUpdaterCompleteMessage": "Aggiornamento completato!",
"DialogUpdaterRestartMessage": "Vuoi riavviare Ryujinx adesso?",
"DialogUpdaterArchNotSupportedMessage": "Non stai usando un'architettura di sistema supportata!",
"DialogUpdaterArchNotSupportedSubMessage": "(Solo sistemi x64 sono supportati!)",
"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://ryujinx.org/ se stai cercando una versione supportata.",
"DialogRestartRequiredMessage": "Riavvio richiesto",
"DialogThemeRestartMessage": "Il tema è stato salvato. E' richiesto un riavvio per applicare un tema.",
"DialogThemeRestartSubMessage": "Vuoi riavviare?",
"DialogFirmwareInstallEmbeddedMessage": "Vuoi installare il firmware incorporato in questo gioco? (Firmware {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "Non è stato trovato alcun firmware installato, ma Ryujinx è riuscito di installare il firmware {0} dal gioco fornito.\nL'emulatore si avvierà adesso.",
"DialogFirmwareNoFirmwareInstalledMessage": "Nessun firmware installato",
"DialogFirmwareInstalledMessage": "Il firmware {0} è stato installato",
"DialogOpenSettingsWindowLabel": "Apri finestra delle impostazioni",
"DialogControllerAppletTitle": "Applet del controller",
"DialogMessageDialogErrorExceptionMessage": "Errore nella visualizzazione del Message Dialog: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Errore nella visualizzazione della tastiera software: {0}",
"DialogErrorAppletErrorExceptionMessage": "Errore nella visualizzazione dell'ErrorApplet Dialog: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nPer più informazioni su come risolvere questo errore, segui la nostra guida all'installazione.",
"DialogUserErrorDialogTitle": "Errore di Ryujinx ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "Si è verificato un errore durante il recupero delle informazioni dall'API.",
"DialogAmiiboApiConnectErrorMessage": "Impossibile connettersi al server Amiibo API. Il servizio potrebbe essere fuori uso o potresti dover verificare che la tua connessione internet sia online.",
"DialogProfileInvalidProfileErrorMessage": "Il profilo {0} è incompatibile con l'attuale sistema di configurazione input.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "Il profilo predefinito non può essere sovrascritto",
"DialogProfileDeleteProfileTitle": "Eliminazione profilo",
"DialogProfileDeleteProfileMessage": "Quest'azione è irreversibile, sei sicuro di voler continuare?",
"DialogWarning": "Avviso",
"DialogPPTCDeletionMessage": "Stai per eliminare la PPTC cache per :\n\n{0}\n\nSei sicuro di voler proseguire?",
"DialogPPTCDeletionErrorMessage": "Errore nell'eliminazione della PPTC cache a {0}: {1}",
"DialogShaderDeletionMessage": "Stai per eliminare la Shader cache per :\n\n{0}\n\nSei sicuro di voler proseguire?",
"DialogShaderDeletionErrorMessage": "Errore nell'eliminazione della Shader cache a {0}: {1}",
"DialogRyujinxErrorMessage": "Ryujinx ha incontrato un errore",
"DialogInvalidTitleIdErrorMessage": "Errore UI: Il gioco selezionato non ha un title ID valido",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Un firmware di sistema valido non è stato trovato in {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Installa firmware {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "La versione di sistema {0} sarà installata.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nQuesta sostituirà l'attuale versione di sistema {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nVuoi continuare?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Installazione del firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "La versione di sistema {0} è stata installata.",
"DialogUserProfileDeletionWarningMessage": "Non ci sarebbero altri profili da aprire se il profilo selezionato viene cancellato",
"DialogUserProfileDeletionConfirmMessage": "Vuoi eliminare il profilo selezionato?",
"DialogControllerSettingsModifiedConfirmMessage": "Le attuali impostazioni del controller sono state aggiornate.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Vuoi salvare?",
"DialogDlcLoadNcaErrorMessage": "{0}. File errato: {1}",
"DialogDlcNoDlcErrorMessage": "Il file specificato non contiene un DLC per il titolo selezionato!",
"DialogPerformanceCheckLoggingEnabledMessage": "Hai abilitato il trace logging, che è progettato per essere usato solo dagli sviluppatori.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Per prestazioni ottimali, si raccomanda di disabilitare il trace logging. Vuoi disabilitare il debug logging adesso?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "Hai abilitato lo shader dumping, che è progettato per essere usato solo dagli sviluppatori.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Per prestazioni ottimali, si raccomanda di disabilitare lo shader dumping. Vuoi disabilitare lo shader dumping adesso?",
"DialogLoadAppGameAlreadyLoadedMessage": "Un gioco è già stato caricato",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Ferma l'emulazione o chiudi l'emulatore prima di avviare un altro gioco.",
"DialogUpdateAddUpdateErrorMessage": "Il file specificato non contiene un aggiornamento per il titolo selezionato!",
"DialogSettingsBackendThreadingWarningTitle": "Avviso - Backend Threading",
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx deve essere riavviato dopo aver cambiato questa opzione per applicarla completamente. A seconda della tua piattaforma, potrebbe essere necessario disabilitare manualmente il multithreading del driver quando usi quello di Ryujinx.",
"SettingsTabGraphicsFeaturesOptions": "Funzionalità",
"SettingsTabGraphicsBackendMultithreading": "Graphics Backend Multithreading",
"CommonAuto": "Auto",
"CommonOff": "Spento",
"CommonOn": "Acceso",
"InputDialogYes": "Si",
"InputDialogNo": "No",
"DialogProfileInvalidProfileNameErrorMessage": "Il nome del file contiene caratteri non validi. Riprova.",
"MenuBarOptionsPauseEmulation": "Pausa",
"MenuBarOptionsResumeEmulation": "Riprendi",
"AboutUrlTooltipMessage": "Clicca per aprire il sito web di Ryujinx nel tuo browser predefinito.",
"AboutDisclaimerMessage": "Ryujinx non è affiliato con Nintendo™,\no i suoi partner, in alcun modo.",
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) è usata\nnella nostra emulazione Amiibo.",
"AboutPatreonUrlTooltipMessage": "Clicca per aprire la pagina Patreon di Ryujinx nel tuo browser predefinito.",
"AboutGithubUrlTooltipMessage": "Clicca per aprire la pagina GitHub di Ryujinx nel tuo browser predefinito.",
"AboutDiscordUrlTooltipMessage": "Clicca per aprire un invito al server Discord di Ryujinx nel tuo browser predefinito.",
"AboutTwitterUrlTooltipMessage": "Clicca per aprire la pagina Twitter di Ryujinx nel tuo browser predefinito.",
"AboutRyujinxAboutTitle": "Informazioni:",
"AboutRyujinxAboutContent": "Ryujinx è un emulatore per la Nintendo Switch™.\nPer favore supportaci su Patreon.\nRicevi tutte le ultime notizie sul nostro Twitter o su Discord.\nGli sviluppatori interessati a contribuire possono trovare più informazioni sul nostro GitHub o Discord.",
"AboutRyujinxMaintainersTitle": "Mantenuto da:",
"AboutRyujinxMaintainersContentTooltipMessage": "Clicca per aprire la pagina dei Contributors nel tuo browser predefinito.",
"AboutRyujinxSupprtersTitle": "Supportato su Patreon da:",
"AmiiboSeriesLabel": "Serie Amiibo",
"AmiiboCharacterLabel": "Personaggio",
"AmiiboScanButtonLabel": "Scannerizza",
"AmiiboOptionsShowAllLabel": "Mostra tutti gli amiibo",
"AmiiboOptionsUsRandomTagLabel": "Hack: Usa un tag uuid casuale",
"DlcManagerTableHeadingEnabledLabel": "Abilitato",
"DlcManagerTableHeadingTitleIdLabel": "Title ID",
"DlcManagerTableHeadingContainerPathLabel": "Percorso del contenitore",
"DlcManagerTableHeadingFullPathLabel": "Percorso completo",
"DlcManagerRemoveAllButton": "Rimuovi tutti",
"MenuBarOptionsChangeLanguage": "Cambia lingua",
"CommonSort": "Ordina",
"CommonShowNames": "Mostra nomi",
"CommonFavorite": "Preferito",
"OrderAscending": "Crescente",
"OrderDescending": "Decrescente",
"SettingsTabGraphicsFeatures": "Funzionalità",
"ErrorWindowTitle": "Finestra errore",
"ToggleDiscordTooltip": "Attiva o disattiva Discord Rich Presence",
"AddGameDirBoxTooltip": "Inserisci la directory di un gioco per aggiungerlo alla lista",
"AddGameDirTooltip": "Aggiungi la directory di un gioco alla lista",
"RemoveGameDirTooltip": "Rimuovi la directory di gioco selezionata",
"CustomThemeCheckTooltip": "Attiva o disattiva temi personalizzati nella GUI",
"CustomThemePathTooltip": "Percorso al tema GUI personalizzato",
"CustomThemeBrowseTooltip": "Sfoglia per cercare un tema GUI personalizzato",
"DockModeToggleTooltip": "Attiva o disabilta modalità TV",
"DirectKeyboardTooltip": "Attiva o disattiva \"il supporto all'accesso diretto alla tastiera (HID)\" (Fornisce l'accesso ai giochi alla tua tastiera come dispositivo di immissione del testo)",
"DirectMouseTooltip": "Attiva o disattiva \"il supporto all'accesso diretto al mouse (HID)\" (Fornisce l'accesso ai giochi al tuo mouse come dispositivo di puntamento)",
"RegionTooltip": "Cambia regione di sistema",
"LanguageTooltip": "Cambia lingua di sistema",
"TimezoneTooltip": "Cambia fuso orario di sistema",
"TimeTooltip": "Cambia data e ora di sistema",
"VSyncToggleTooltip": "Attiva o disattiva sincronizzazione verticale",
"PptcToggleTooltip": "Attiva o disattiva PPTC",
"FsIntegrityToggleTooltip": "Attiva controlli d'integrità sui file dei contenuti di gioco",
"AudioBackendTooltip": "Cambia backend audio",
"MemoryManagerTooltip": "Cambia il modo in cui la memoria guest è mappata e vi si accede. Influisce notevolmente sulle prestazioni della CPU emulata.",
"MemoryManagerSoftwareTooltip": "Usa una software page table per la traduzione degli indirizzi. Massima precisione ma prestazioni più lente.",
"MemoryManagerHostTooltip": "Mappa direttamente la memoria nello spazio degli indirizzi dell'host. Compilazione ed esecuzione JIT molto più veloce.",
"MemoryManagerUnsafeTooltip": "Mappa direttamente la memoria, ma non maschera l'indirizzo all'interno dello spazio degli indirizzi guest prima dell'accesso. Più veloce, ma a costo della sicurezza. L'applicazione guest può accedere alla memoria da qualsiasi punto di Ryujinx, quindi esegui solo programmi di cui ti fidi con questa modalità.",
"DRamTooltip": "Espande l'ammontare di memoria sul sistema emulato da 4GB A 6GB",
"IgnoreMissingServicesTooltip": "Attiva o disattiva l'opzione di ignorare i servizi mancanti",
"GraphicsBackendThreadingTooltip": "Attiva il Graphics Backend Multithreading",
"GalThreadingTooltip": "Esegue i comandi del backend grafico su un secondo thread. Permette il multithreading runtime della compilazione degli shader, riduce lo stuttering e migliora le prestazioni sui driver senza supporto multithreading proprio. Varia leggermente le prestazioni di picco sui driver con multithreading. Ryujinx potrebbe aver bisogno di essere riavviato per disabilitare correttamente il multithreading integrato nel driver, o potrebbe essere necessario farlo manualmente per ottenere le migliori prestazioni.",
"ShaderCacheToggleTooltip": "Attiva o disattiva la Shader Cache",
"ResolutionScaleTooltip": "Scala della risoluzione applicata ai render targets applicabili",
"ResolutionScaleEntryTooltip": "Scala della risoluzione in virgola mobile, come 1,5. Le scale non integrali hanno maggiori probabilità di causare problemi o crash.",
"AnisotropyTooltip": "Livello del filtro anisotropico (imposta su Auto per usare il valore richiesto dal gioco)",
"AspectRatioTooltip": "Rapporto d'aspetto applicato alla finestra del renderer.",
"ShaderDumpPathTooltip": "Percorso di dump Graphics Shaders",
"FileLogTooltip": "Attiva o disattiva il logging su file",
"StubLogTooltip": "Attiva messaggi stub log",
"InfoLogTooltip": "Attiva messaggi info log",
"WarnLogTooltip": "Attiva messaggi warning log",
"ErrorLogTooltip": "Attiva messaggi error log",
"TraceLogTooltip": "Attiva messaggi trace log",
"GuestLogTooltip": "Attiva messaggi guest log",
"FileAccessLogTooltip": "Attiva messaggi file access log",
"FSAccessLogModeTooltip": "Attiva output FS access log alla console. Le mpdalità possibili sono 0-3",
"DeveloperOptionTooltip": "Usa con attenzione",
"OpenGlLogLevel": "Richiede livelli di log appropriati abilitati",
"DebugLogTooltip": "Attiva messaggi debug log",
"LoadApplicationFileTooltip": "Apri un file explorer per scegliere un file compatibile Switch da caricare",
"LoadApplicationFolderTooltip": "Apri un file explorer per scegliere un file compatibile Switch, applicazione sfusa da caricare",
"OpenRyujinxFolderTooltip": "Apri la cartella del filesystem di Ryujinx",
"OpenRyujinxLogsTooltip": "Apre la cartella dove vengono scritti i log",
"ExitTooltip": "Esci da Ryujinx",
"OpenSettingsTooltip": "Apri finestra delle impostazioni",
"OpenProfileManagerTooltip": "Apri la finestra di gestione dei profili utente",
"StopEmulationTooltip": "Ferma l'emulazione del gioco attuale e torna alla selezione dei giochi",
"CheckUpdatesTooltip": "Controlla la presenza di aggiornamenti di Ryujinx",
"OpenAboutTooltip": "Apri finestra delle informazioni",
"GridSize": "Dimensione griglia",
"GridSizeTooltip": "Cambia la dimensione dei riquardi della griglia",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Portoghese Brasiliano",
"AboutRyujinxContributorsButtonHeader": "Vedi tutti i Contributors",
"SettingsTabSystemAudioVolume": "Volume: ",
"AudioVolumeTooltip": "Cambia volume audio",
"SettingsTabSystemEnableInternetAccess": "Attiva Guest Internet Access",
"EnableInternetAccessTooltip": "Attiva il guest Internet access. Se abilitato, l'applicazione si comporterà come se la console Switch emulata fosse collegata a Internet. Si noti che in alcuni casi, le applicazioni possono comunque accedere a Internet anche con questa opzione disabilitata",
"GameListContextMenuManageCheatToolTip": "Gestisci Cheats",
"GameListContextMenuManageCheat": "Gestisci Cheats",
"ControllerSettingsStickRange": "Raggio",
"DialogStopEmulationTitle": "Ryujinx - Ferma emulazione",
"DialogStopEmulationMessage": "Sei sicuro di voler fermare l'emulazione?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "Audio",
"SettingsTabNetwork": "Rete",
"SettingsTabNetworkConnection": "Connessione di rete",
"SettingsTabGraphicsFrameRate": "Frequenza di aggiornamento dell'host:",
"SettingsTabGraphicsFrameRateTooltip": "Imposta la frequenza di aggiornamento dell'host. Imposta a 0 per rimuovere il limite.",
"SettingsTabCpuCache": "Cache CPU",
"SettingsTabCpuMemory": "Memoria CPU",
"DialogUpdaterFlatpakNotSupportedMessage": "Per favore aggiorna Ryujinx via FlatHub.",
"UpdaterDisabledWarningTitle": "Updater disabilitato!",
"GameListContextMenuOpenSdModsDirectory": "Apri cartella delle mods Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Apre la cartella aternativa di atmosphere che contiene le mods dell'applicazione",
"ControllerSettingsRotate90": "Ruota in senso orario di 90°",
"IconSize": "Dimensioni icona",
"IconSizeTooltip": "Cambia le dimensioni dell'icona di un gioco",
"MenuBarOptionsShowConsole": "Mostra console",
"ShaderCachePurgeError" : "Errore nella pulizia della shader cache a {0}: {1}",
"UserErrorNoKeys": "Chiavi non trovate",
"UserErrorNoFirmware": "Firmware non trovato",
"UserErrorFirmwareParsingFailed": "Errori di analisi del firmware",
"UserErrorApplicationNotFound": "Applicazione non trovata",
"UserErrorUnknown": "Errore sconosciuto",
"UserErrorUndefined": "Errore non definito",
"UserErrorNoKeysDescription": "Ryujinx non è riuscito a trovare il file 'prod.keys'",
"UserErrorNoFirmwareDescription": "Ryujinx non è riuscito a trovare alcun firmware installato",
"UserErrorFirmwareParsingFailedDescription": "Ryujinx non è riuscito ad analizzare il firmware. Questo di solito è causato da chiavi non aggiornate.",
"UserErrorApplicationNotFoundDescription": "Ryujinx non è riuscito a trovare un'applicazione valida al percorso specificato.",
"UserErrorUnknownDescription": "Si è verificato un errore sconosciuto!",
"UserErrorUndefinedDescription": "Si è verificato un errore sconosciuto! Non dovrebbe succedere, per favore contatta uno sviluppatore!",
"OpenSetupGuideMessage": "Apri la guida all'installazione",
"NoUpdate": "Nessun aggiornamento",
"TitleUpdateVersionLabel": "Versione {0} - {1}",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Conferma",
"FileDialogAllTypes": "Tutti i tipi",
"Never": "Mai",
"SwkbdMinCharacters": "Non può avere meno di {0} caratteri",
"SwkbdMinRangeCharacters": "Può avere da {0} a {1} caratteri",
"SoftwareKeyboard": "Tastiera software",
"DialogControllerAppletMessagePlayerRange": "L'applicazione richiede {0} giocatori con:\n\nTIPI: {1}\n\nGIOCATORI: {2}\n\n{3}Apri le impostazioni e riconfigura l'input adesso o premi Chiudi.",
"DialogControllerAppletMessage": "L'applicazione richiede esattamente {0} giocatori con:\n\nTIPI: {1}\n\nGIOCATORI: {2}\n\n{3}Apri le impostazioni e riconfigura l'input adesso o premi Chiudi.",
"DialogControllerAppletDockModeSet": "Modalità TV attivata. Neanche portatile è valida.\n\n",
"UpdaterRenaming": "Rinominazione dei vecchi files...",
"UpdaterRenameFailed": "L'updater non è riuscito a rinominare il file: {0}",
"UpdaterAddingFiles": "Aggiunta nuovi files...",
"UpdaterExtracting": "Estrazione aggiornamento...",
"UpdaterDownloading": "Download aggiornamento...",
"Game": "Gioco",
"Docked": "TV",
"Handheld": "Portatile",
"ConnectionError": "Errore di connessione.",
"AboutPageDeveloperListMore": "{0} e altri ancora...",
"ApiError": "Errore dell'API.",
"LoadingHeading": "Caricamento di {0}",
"CompilingPPTC": "Compilazione PTC",
"CompilingShaders": "Compilazione Shaders"
}

View file

@ -0,0 +1,497 @@
{
"MenuBarFileOpenApplet": "애플릿 열기",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "독립 실행형 모드에서 Mii 편집기 애플릿 열기",
"SettingsTabInputDirectMouseAccess": "직접 마우스 액세스",
"SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드 :",
"SettingsTabSystemMemoryManagerModeSoftware": "소프트웨어",
"SettingsTabSystemMemoryManagerModeHost": "호스트 (빠른)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "호스트가 확인되지 않음 (가장 빠르고 안전하지 않은)",
"MenuBarFile": "_파일",
"MenuBarFileOpenFromFile": "_서류철음에서 애플리케이션 로드",
"MenuBarFileOpenUnpacked": "_압축을 푼 게임 로드",
"MenuBarFileOpenEmuFolder": "Ryujinx 폴더 열기",
"MenuBarFileOpenLogsFolder": "로그 폴더 열기",
"MenuBarFileExit": "_그만두",
"MenuBarOptions": "옵션",
"MenuBarOptionsToggleFullscreen": "전체 화면 전환",
"MenuBarOptionsStartGamesInFullscreen": "전체 화면 모드에서 게임 열기",
"MenuBarOptionsStopEmulation": "에뮬레이션 중지",
"MenuBarOptionsSettings": "_조절",
"MenuBarOptionsManageUserProfiles": "사용자 프로필 _관리",
"MenuBarActions": "_행위",
"MenuBarOptionsSimulateWakeUpMessage": "깨우기 명령어 시뮬레이션",
"MenuBarActionsScanAmiibo": "Amiibo 스캔",
"MenuBarTools": "_도구",
"MenuBarToolsInstallFirmware": "펌웨어 설치",
"MenuBarFileToolsInstallFirmwareFromFile": "XCI 또는 ZIP에서 펌웨어 설치",
"MenuBarFileToolsInstallFirmwareFromDirectory": "디렉토리에서 펌웨어 설치",
"MenuBarHelp": "돕다",
"MenuBarHelpCheckForUpdates": "업데이트 확인",
"MenuBarHelpAbout": "통지",
"MenuSearch": "찾다···",
"GameListHeaderFavorite": "즐겨찾기",
"GameListHeaderIcon": "상",
"GameListHeaderApplication": "이름",
"GameListHeaderDeveloper": "개발자",
"GameListHeaderVersion": "버전",
"GameListHeaderTimePlayed": "플레이 시간",
"GameListHeaderLastPlayed": "해본 마지막",
"GameListHeaderFileExtension": "파일 확장자",
"GameListHeaderFileSize": "파일 크기",
"GameListHeaderPath": "파일 경로",
"GameListContextMenuOpenUserSaveDirectory": "사용자 저장 폴더 열기",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "응용 프로그램의 사용자 저장이 포함된 폴더를 엽니다",
"GameListContextMenuOpenUserDeviceDirectory": "사용자 장치 폴더 열기",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "응용 프로그램의 장치 저장이 포함된 폴더를 엽니다",
"GameListContextMenuOpenUserBcatDirectory": "사용자의 BCAT 폴더 열기",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "응용 프로그램의 BCAT 저장이 포함된 폴더를 엽니다",
"GameListContextMenuManageTitleUpdates": "타이틀 업데이트 관리s",
"GameListContextMenuManageTitleUpdatesToolTip": "타이틀 업데이트 관리 창 열기",
"GameListContextMenuManageDlc": "DLC 관리",
"GameListContextMenuManageDlcToolTip": "DLC 관리 창 열기",
"GameListContextMenuOpenModsDirectory": "모드 디렉토리 열기",
"GameListContextMenuOpenModsDirectoryToolTip": "응용 프로그램의 모드가들 포함된 디렉터리를 엽니다",
"GameListContextMenuCacheManagement": "캐시 관리",
"GameListContextMenuCacheManagementPurgePptc": "PPTC 캐시 제거",
"GameListContextMenuCacheManagementPurgePptcToolTip": "응용 프로그램 PPTC 캐시 삭제",
"GameListContextMenuCacheManagementPurgeShaderCache": "셰이더 캐시 제거",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "애플리케이션 셰이더 캐시를 삭제합니다.",
"GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC 디렉토리 열기",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "응용 프로그램 PPTC 캐시가 포함된 디렉터리를 엽니다",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "셰이더 캐시 디렉토리 열기",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "응용 프로그램 셰이더 캐시가 포함된 디렉터리를 엽니다",
"GameListContextMenuExtractData": "데이터 추출",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "애플리케이션의 현재 구성에서 ExeFS 추출 (업데이트 포함)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "애플리케이션의 현재 구성에서 RomFS 추출 (업데이트 포함)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "애플리케이션의 현재 구성에서 로고 섹션 추출 (업데이트 포함)",
"StatusBarGamesLoaded": "로드된 {0}/{1}개의 게임",
"StatusBarSystemVersion": "시스템 버전 : {0}",
"Settings": "조절",
"SettingsTabGeneral": "사용자 인터페이스",
"SettingsTabGeneralGeneral": "일반",
"SettingsTabGeneralEnableDiscordRichPresence": "Discord Rich Presence 활성화",
"SettingsTabGeneralCheckUpdatesOnLaunch": "열 때 업데이트 확인",
"SettingsTabGeneralShowConfirmExitDialog": "\"종료 확인\" 대화 상자 표시",
"SettingsTabGeneralHideCursorOnIdle": "유휴 상태에서 커서 숨기기",
"SettingsTabGeneralGameDirectories": "게임 디렉토리들",
"SettingsTabGeneralAdd": "추가하다",
"SettingsTabGeneralRemove": "제거하다",
"SettingsTabSystem": "체계",
"SettingsTabSystemCore": "핵심",
"SettingsTabSystemSystemRegion": "시스템 영역 :",
"SettingsTabSystemSystemRegionJapan": "일본",
"SettingsTabSystemSystemRegionUSA": "미국",
"SettingsTabSystemSystemRegionEurope": "유럽",
"SettingsTabSystemSystemRegionAustralia": "호주",
"SettingsTabSystemSystemRegionChina": "중국",
"SettingsTabSystemSystemRegionKorea": "한국",
"SettingsTabSystemSystemRegionTaiwan": "대만",
"SettingsTabSystemSystemLanguage": "시스템 언어 :",
"SettingsTabSystemSystemLanguageJapanese": "일본어",
"SettingsTabSystemSystemLanguageAmericanEnglish": "영어(미국)",
"SettingsTabSystemSystemLanguageFrench": "프랑스어",
"SettingsTabSystemSystemLanguageGerman": "독일어",
"SettingsTabSystemSystemLanguageItalian": "이탈리아어",
"SettingsTabSystemSystemLanguageSpanish": "스페인어",
"SettingsTabSystemSystemLanguageChinese": "중국어",
"SettingsTabSystemSystemLanguageKorean": "한국어",
"SettingsTabSystemSystemLanguageDutch": "네덜란드 어",
"SettingsTabSystemSystemLanguagePortuguese": "포르투갈어",
"SettingsTabSystemSystemLanguageRussian": "러시아어",
"SettingsTabSystemSystemLanguageTaiwanese": "대만어",
"SettingsTabSystemSystemLanguageBritishEnglish": "영어(영국)",
"SettingsTabSystemSystemLanguageCanadianFrench": "프랑스어(캐나다)",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "스페인어(라틴 아메리카)",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "중국어 간체",
"SettingsTabSystemSystemLanguageTraditionalChinese": "중국어 번체",
"SettingsTabSystemSystemTimeZone": "시스템 시간대 :",
"SettingsTabSystemSystemTime": "시스템 시간 :",
"SettingsTabSystemEnableVsync": "수직 동기화 사용",
"SettingsTabSystemEnablePptc": "PPTC(Profiled Persistent Translation Cache) 활성화",
"SettingsTabSystemEnableFsIntegrityChecks": "FS 무결성 검사 활성화",
"SettingsTabSystemAudioBackend": "오디오 백엔드 :",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "해킹",
"SettingsTabSystemHacksNote": " - 불안정을 일으킬 수 있음",
"SettingsTabSystemExpandDramSize": "DRAM 크기를 6GB로 확장",
"SettingsTabSystemIgnoreMissingServices": "누락된 서비스 무시",
"SettingsTabGraphics": "제도법",
"SettingsTabGraphicsEnhancements": "개선 사항",
"SettingsTabGraphicsEnableShaderCache": "셰이더 캐시 활성화",
"SettingsTabGraphicsAnisotropicFiltering": "이방성 필터링 :",
"SettingsTabGraphicsAnisotropicFilteringAuto": "자동적 인",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "해상도 스케일 :",
"SettingsTabGraphicsResolutionScaleCustom": "사용자 지정(권장하지 않음)",
"SettingsTabGraphicsResolutionScaleNative": "기본 (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "종횡비 :",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "창에 맞게 늘리기",
"SettingsTabGraphicsDeveloperOptions": "개발자 옵션",
"SettingsTabGraphicsShaderDumpPath": "그래픽 쉐이더 덤프 경로 :",
"SettingsTabLogging": "로깅",
"SettingsTabLoggingLogging": "로깅",
"SettingsTabLoggingEnableLoggingToFile": "파일에 로깅 활성화",
"SettingsTabLoggingEnableStubLogs": "스텁 로그 켜기 ",
"SettingsTabLoggingEnableInfoLogs": "정보 로그 켜기",
"SettingsTabLoggingEnableWarningLogs": "경고 로그 켜기",
"SettingsTabLoggingEnableErrorLogs": "오류 로그 켜기",
"SettingsTabLoggingEnableGuestLogs": "게스트 로그 켜기",
"SettingsTabLoggingEnableFsAccessLogs": "Fs 액세스 로그 켜기",
"SettingsTabLoggingFsGlobalAccessLogMode": "Fs 전역 액세스 로그 모드 :",
"SettingsTabLoggingDeveloperOptions": "개발자 옵션 (경고 : 성능이 저하됩니다.)",
"SettingsTabLoggingOpenglLogLevel": "OpenGL 로그 수준 :",
"SettingsTabLoggingOpenglLogLevelNone": "없음",
"SettingsTabLoggingOpenglLogLevelError": "오류",
"SettingsTabLoggingOpenglLogLevelPerformance": "감속",
"SettingsTabLoggingOpenglLogLevelAll": "모두",
"SettingsTabLoggingEnableDebugLogs": "디버그 로그 사용",
"SettingsTabInput": "입력",
"SettingsTabInputEnableDockedMode": "도킹 모드 활성화",
"SettingsTabInputDirectKeyboardAccess": "직접 키보드 액세스",
"SettingsButtonSave": "구하다",
"SettingsButtonClose": "출구",
"SettingsButtonApply": "적용하다",
"ControllerSettingsPlayer": "플레이어",
"ControllerSettingsPlayer1": "플레이어 1",
"ControllerSettingsPlayer2": "플레이어 2",
"ControllerSettingsPlayer3": "플레이어 3",
"ControllerSettingsPlayer4": "플레이어 4",
"ControllerSettingsPlayer5": "플레이어 5",
"ControllerSettingsPlayer6": "플레이어 6",
"ControllerSettingsPlayer7": "플레이어 7",
"ControllerSettingsPlayer8": "플레이어 8",
"ControllerSettingsHandheld": "휴대용",
"ControllerSettingsInputDevice": "입력 장치",
"ControllerSettingsRefresh": "새로 고치다",
"ControllerSettingsDeviceDisabled": "장애가있는",
"ControllerSettingsControllerType": "컨트롤러 유형",
"ControllerSettingsControllerTypeHandheld": "휴대용",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "JoyCon 페어",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon 왼쪽",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon 오른쪽",
"ControllerSettingsProfile": "프로필",
"ControllerSettingsProfileDefault": "기본",
"ControllerSettingsLoad": "짐",
"ControllerSettingsAdd": "추가하다",
"ControllerSettingsRemove": "제거하다",
"ControllerSettingsButtons": "버튼",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Directional Pad",
"ControllerSettingsDPadUp": "위로",
"ControllerSettingsDPadDown": "아래에",
"ControllerSettingsDPadLeft": "왼쪽",
"ControllerSettingsDPadRight": "오른쪽",
"ControllerSettingsLStick": "왼쪽 스틱",
"ControllerSettingsLStickButton": "단추",
"ControllerSettingsLStickUp": "위로",
"ControllerSettingsLStickDown": "아래에",
"ControllerSettingsLStickLeft": "왼쪽",
"ControllerSettingsLStickRight": "오른쪽",
"ControllerSettingsLStickStick": "막대",
"ControllerSettingsLStickInvertXAxis": "스틱 X축 반전",
"ControllerSettingsLStickInvertYAxis": "스틱 Y축 반전",
"ControllerSettingsLStickDeadzone": "데드 존 :",
"ControllerSettingsRStick": "오른쪽 스틱",
"ControllerSettingsRStickButton": "단추",
"ControllerSettingsRStickUp": "위로",
"ControllerSettingsRStickDown": "아래에",
"ControllerSettingsRStickLeft": "왼쪽",
"ControllerSettingsRStickRight": "오른쪽",
"ControllerSettingsRStickStick": "Stick",
"ControllerSettingsRStickInvertXAxis": "스틱 X축 반전",
"ControllerSettingsRStickInvertYAxis": "스틱 Y축 반전",
"ControllerSettingsRStickDeadzone": "데드 존 :",
"ControllerSettingsTriggersLeft": "왼쪽 트리거",
"ControllerSettingsTriggersRight": "오른쪽 트리거",
"ControllerSettingsTriggersButtonsLeft": "트리거 버튼 왼쪽",
"ControllerSettingsTriggersButtonsRight": "트리거 버튼 오른쪽",
"ControllerSettingsTriggers": "방아쇠",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "왼쪽 버튼",
"ControllerSettingsExtraButtonsRight": "버튼 오른쪽",
"ControllerSettingsMisc": "여러 가지 잡다한",
"ControllerSettingsTriggerThreshold": "트리거 임계값 :",
"ControllerSettingsMotion": "운동",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "모션 컨트롤 활성화",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook 호환 모션 사용",
"ControllerSettingsMotionControllerSlot": "컨트롤러 슬롯 :",
"ControllerSettingsMotionMirrorInput": "미러 입력",
"ControllerSettingsMotionRightJoyConSlot": "오른쪽 JoyCon 슬롯 :",
"ControllerSettingsMotionServerHost": "서버 호스트 :",
"ControllerSettingsMotionGyroSensitivity": "자이로 감도 :",
"ControllerSettingsMotionGyroDeadzone": "자이로 데드존 :",
"ControllerSettingsSave": "구하다",
"ControllerSettingsClose": "출구",
"UserProfilesSelectedUserProfile": "선택한 사용자 프로필 :",
"UserProfilesSaveProfileName": "프로필 이름 저장",
"UserProfilesChangeProfileImage": "프로필 이미지 변경",
"UserProfilesAvailableUserProfiles": "사용 가능한 사용자 프로필 :",
"UserProfilesAddNewProfile": "새 프로필 추가",
"UserProfilesDeleteSelectedProfile": "선택한 프로필 삭제",
"UserProfilesClose": "출구",
"ProfileImageSelectionTitle": "프로필 이미지 선택",
"ProfileImageSelectionHeader": "이미지 선택",
"ProfileImageSelectionNote": "사용자 정의 프로필 이미지를 사용하거나 시스템 펌웨어에서 하나를 선택할 수 있습니다",
"ProfileImageSelectionImportImage": "이미지 파일 가져오기",
"ProfileImageSelectionSelectAvatar": "펌웨어 아바타 선택",
"InputDialogTitle": "입력 대화 상자",
"InputDialogOk": "확인",
"InputDialogCancel": "취소",
"InputDialogAddNewProfileTitle": "프로필 이름 선택",
"InputDialogAddNewProfileHeader": "프로필 이름을 입력하세요",
"InputDialogAddNewProfileSubtext": "최대 길이 : {0})",
"AvatarChoose": "선택하다",
"AvatarSetBackgroundColor": "배경색 설정",
"AvatarClose": "출구",
"ControllerSettingsLoadProfileToolTip": "프로필 로드",
"ControllerSettingsAddProfileToolTip": "프로필 추가",
"ControllerSettingsRemoveProfileToolTip": "프로필 제거",
"ControllerSettingsSaveProfileToolTip": "프로필 저장",
"MenuBarFileToolsTakeScreenshot": "스크린 샷을 찍다",
"MenuBarFileToolsHideUi": "사용자 인터페이스 숨기기",
"GameListContextMenuToggleFavorite": "즐겨찾기 설정",
"GameListContextMenuToggleFavoriteToolTip": "이 게임이 즐겨찾기인지 여부를 전환합니다",
"SettingsTabGeneralTheme": "테마",
"SettingsTabGeneralThemeCustomTheme": "사용자 정의 테마 경로",
"SettingsTabGeneralThemeBaseStyle": "기본 스타일",
"SettingsTabGeneralThemeBaseStyleDark": "어두운",
"SettingsTabGeneralThemeBaseStyleLight": "빛",
"SettingsTabGeneralThemeEnableCustomTheme": "사용자 정의 테마 활성화",
"ButtonBrowse": "검색",
"ControllerSettingsMotionConfigureCemuHookSettings": "CemuHook 모션 구성",
"ControllerSettingsRumble": "하인 좌석",
"ControllerSettingsRumbleEnable": "럼블을 활성화",
"ControllerSettingsRumbleStrongMultiplier": "강력한 럼블 배율기",
"ControllerSettingsRumbleWeakMultiplier": "약한 럼블 승수",
"DialogMessageSaveNotAvailableMessage": "에 대한 세이브 데이터가 없습니다 {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "이 게임의 세이브 데이터를 생성하시겠습니까?",
"DialogConfirmationTitle": "Ryujinx - 확인",
"DialogUpdaterTitle": "Ryujinx - 업데이터",
"DialogErrorTitle": "Ryujinx - 오류",
"DialogWarningTitle": "Ryujinx - 경고",
"DialogExitTitle": "Ryujinx - 출구",
"DialogErrorMessage": "Ryujinx에 오류가 발생했습니다",
"DialogExitMessage": "Ryujinx를 종료하시겠습니까?",
"DialogExitSubMessage": "저장하지 않은 모든 데이터는 손실됩니다!",
"DialogMessageCreateSaveErrorMessage": "지정된 세이브 데이터를 작성하는 중에 오류가 발생했습니다 : {0}",
"DialogMessageFindSaveErrorMessage": "지정된 저장 데이터를 찾는 중에 오류가 발생했습니다 : {0}",
"FolderDialogExtractTitle": "추출할 폴더 선택",
"DialogNcaExtractionMessage": "{1}에서 섹션 {0} 추출···",
"DialogNcaExtractionTitle": "Ryujinx - NCA 섹션 추출기",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "추출 실패. 선택한 파일에 기본 NCA가 없습니다.",
"DialogNcaExtractionCheckLogErrorMessage": "추출 실패. 자세한 내용은 로그 파일을 읽으십시오.",
"DialogNcaExtractionSuccessMessage": "추출이 성공적으로 완료되었습니다.",
"DialogUpdaterConvertFailedMessage": "현재 Ryujinx 버전을 변환하지 못했습니다.",
"DialogUpdaterCancelUpdateMessage": "업데이트 취소 중!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "이미 최신 버전의 Ryujinx를 사용하고 있습니다!",
"DialogUpdaterFailedToGetVersionMessage": "Github 릴리스에서 릴리스 정보를 가져오는 중에 오류가 발생했습니다. 이는 GitHub Actions에서 새 릴리스를 컴파일하는 경우 발생할 수 있습니다. 몇 분 후에 다시 시도하십시오.",
"DialogUpdaterConvertFailedGithubMessage": "Github Release에서 받은 Ryujinx 버전을 변환하지 못했습니다.",
"DialogUpdaterDownloadingMessage": "업데이트 다운로드 중···",
"DialogUpdaterExtractionMessage": "업데이트 추출···",
"DialogUpdaterRenamingMessage": "업데이트 이름 바꾸기···",
"DialogUpdaterAddingFilesMessage": "새 업데이트 추가···",
"DialogUpdaterCompleteMessage": "업데이트 완료!",
"DialogUpdaterRestartMessage": "지금 Ryujinx를 다시 시작하시겠습니까?",
"DialogUpdaterArchNotSupportedMessage": "지원되는 시스템 아키텍처를 실행하고 있지 않습니다!",
"DialogUpdaterArchNotSupportedSubMessage": "(x86 시스템만 지원됩니다!)",
"DialogUpdaterNoInternetMessage": "인터넷에 연결되어 있지 않습니다!",
"DialogUpdaterNoInternetSubMessage": "인터넷 연결이 작동하는지 확인하십시오!",
"DialogUpdaterDirtyBuildMessage": "Ryujinx의 더러운 빌드는 업데이트할 수 없습니다!",
"DialogUpdaterDirtyBuildSubMessage": "지원되는 버전을 찾고 있다면 https://ryujinx.org/에서 Ryujinx를 다운로드하십시오.",
"DialogRestartRequiredMessage": "재시작 필요",
"DialogThemeRestartMessage": "테마가 저장되었습니다. 테마를 적용하려면 다시 시작해야 합니다.",
"DialogThemeRestartSubMessage": "다시 시작하시겠습니까?",
"DialogFirmwareInstallEmbeddedMessage": "이 게임에 내장된 펌웨어를 설치하시겠습니까? (펌웨어 {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "설치된 펌웨어를 찾을 수 없지만 Ryujinx는 제공된 게임에서 펌웨어 {0} 설치할 수 있었습니다.\n이제 에뮬레이터가 시작됩니다.",
"DialogFirmwareNoFirmwareInstalledMessage": "펌웨어가 설치되지 않았습니다",
"DialogFirmwareInstalledMessage": "펌웨어 {0} 설치되었습니다.",
"DialogOpenSettingsWindowLabel": "설정 창 열기",
"DialogControllerAppletTitle": "컨트롤러 애플릿",
"DialogMessageDialogErrorExceptionMessage": "메시지 대화 상자를 표시하는 동안 오류가 발생했습니다 : {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "소프트웨어 키보드를 표시하는 동안 오류가 발생했습니다 : {0}",
"DialogErrorAppletErrorExceptionMessage": "ErrorApplet 대화 상자를 표시하는 동안 오류가 발생했습니다 : {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\n이 오류를 수정하는 방법에 대한 자세한 내용은 설정 가이드를 따르십시오",
"DialogUserErrorDialogTitle": "Ryuijnx의 오류 ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "API에서 정보를 가져오는 동안 오류가 발생했습니다.",
"DialogAmiiboApiConnectErrorMessage": "Amiibo API 서버에 연결할 수 없습니다. 서비스가 다운되었거나 인터넷 연결이 오프라인인지 확인해야 할 수 있습니다.",
"DialogProfileInvalidProfileErrorMessage": "프로필 AAA는 현재 입력 구성 시스템과 호환되지 않습니다.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "기본 프로필을 덮어쓸 수 없습니다",
"DialogProfileDeleteProfileTitle": "프로필 삭제",
"DialogProfileDeleteProfileMessage": "이 작업은 되돌릴 수 없습니다. 계속하시겠습니까?",
"DialogWarning": "경고",
"DialogPPTCDeletionMessage": "{0}에\n\n 대한 PPTC 캐시를 삭제하려고 합니다.\n\n계속하시겠습니까?",
"DialogPPTCDeletionErrorMessage": "{0} : {1}에서 PPTC 캐시를 제거하는 동안 오류가 발생했습니다.",
"DialogShaderDeletionMessage": "{0}에\n\n 대한 셰이더 캐시를 삭제하려고 합니다.\n\n계속하시겠습니까?",
"DialogShaderDeletionErrorMessage": "{0} : {1}에서 셰이더 캐시를 제거하는 동안 오류가 발생했습니다.",
"DialogRyujinxErrorMessage": "Ryujinx에 오류가 발생했습니다",
"DialogInvalidTitleIdErrorMessage": "UI 오류 : 선택한 게임에 유효한 제목 ID가 없습니다",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "{0}에서 유효한 시스템 펌웨어를 찾을 수 없습니다.",
"DialogFirmwareInstallerFirmwareInstallTitle": "펌웨어 {0} 설치",
"DialogFirmwareInstallerFirmwareInstallMessage": "시스템 버전 {0}가 설치되려고 합니다",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\n이것은 현재 설치된 버전 {0}를 대체합니다.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n계속하시겠습니까?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "펌웨어 설치···",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "시스템 버전 {0}가 성공적으로 설치되었습니다.",
"DialogUserProfileDeletionWarningMessage": "선택한 프로필이 삭제되면 사용 가능한 다른 프로필이 없습니다",
"DialogUserProfileDeletionConfirmMessage": "선택한 프로필을 삭제하시겠습니까",
"DialogControllerSettingsModifiedConfirmMessage": "현재 컨트롤러 설정이 업데이트되었습니다.",
"DialogControllerSettingsModifiedConfirmSubMessage": "저장하시겠습니까?",
"DialogDlcLoadNcaErrorMessage": "{0}. 오류 파일 : {1}",
"DialogDlcNoDlcErrorMessage": "지정한 파일에 선택한 타이틀의 DLC가 없습니다!",
"DialogPerformanceCheckLoggingEnabledMessage": "개발자 전용으로 설계된 디버그 로깅을 활성화했습니다.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "최적의 성능을 위해 디버그 로깅을 비활성화하는 것이 좋습니다. 지금 디버그 로깅을 비활성화하시겠습니까?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "Y개발자만 사용하도록 설계된 셰이더 덤핑이 활성화되어 있습니다.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "최적의 성능을 위해 셰이더 덤핑을 비활성화하는 것이 좋습니다. 지금 셰이더 덤핑을 비활성화하시겠습니까?",
"DialogLoadAppGameAlreadyLoadedMessage": "다른 게임이 이미 로드되었습니다",
"DialogLoadAppGameAlreadyLoadedSubMessage": "다른 게임을 시작하기 전에 에뮬레이션을 중지하거나 에뮬레이터를 닫으십시오.",
"DialogUpdateAddUpdateErrorMessage": "파일에 선택한 제목에 대한 업데이트가 포함되어 있지 않습니다!",
"DialogSettingsBackendThreadingWarningTitle": "경고 - 백엔드 스레딩",
"DialogSettingsBackendThreadingWarningMessage": "변경 사항을 완전히 적용하려면 이 옵션을 변경한 후 Ryujinx를 다시 시작해야 합니다. 플랫폼에 따라 Ryujinx를 사용할 때 드라이버 자체의 멀티스레딩을 수동으로 비활성화해야 할 수도 있습니다.",
"SettingsTabGraphicsFeaturesOptions": "특징",
"SettingsTabGraphicsBackendMultithreading": "그래픽 백엔드 멀티스레딩 :",
"CommonAuto": "자동적 인",
"CommonOff": "끄다",
"CommonOn": "켜짐",
"InputDialogYes": "네",
"InputDialogNo": "아니",
"DialogProfileInvalidProfileNameErrorMessage": "파일 이름에 잘못된 기호가 있습니다. 다시 시도하십시오.",
"MenuBarOptionsPauseEmulation": "정지시키다",
"MenuBarOptionsResumeEmulation": "재개하다",
"AboutUrlTooltipMessage": "기본 브라우저에서 Ryujinx 웹사이트를 열려면 클릭하십시오.",
"AboutDisclaimerMessage": "Ryujinx는 Nintendo™와 제휴하지 않으며,\n어떤 식으로든 또는 그 파트너.",
"AboutAmiiboDisclaimerMessage": "AmiiboAPI(www.amiiboapi.com) 사용\nAmiibo 에뮬레이션에서.",
"AboutPatreonUrlTooltipMessage": "기본 브라우저에서 Ryujinx Patreon 페이지를 열려면 클릭하세요.",
"AboutGithubUrlTooltipMessage": "클릭하여 기본 브라우저에서 Ryujinx GitHub 페이지를 엽니다.",
"AboutDiscordUrlTooltipMessage": "기본 브라우저에서 Ryujinx Discord 서버 초대를 열려면 클릭하세요.",
"AboutTwitterUrlTooltipMessage": "클릭하여 기본 브라우저에서 Ryujinx Twitter 페이지를 엽니다.",
"AboutRyujinxAboutTitle": "에 대한 :",
"AboutRyujinxAboutContent": "Ryujinx는 Nintendo Switch™용 에뮬레이터입니다.\nPatreon에서 지원해 주세요.\n모든 최신 뉴스는 Twitter 또는 Discord에서 확인하세요.\n기고에 관심이 있는 개발자는 GitHub 또는 Discord에서 자세한 내용을 확인할 수 있습니다.",
"AboutRyujinxMaintainersTitle": "유지 관리 :",
"AboutRyujinxMaintainersContentTooltipMessage": "기본 브라우저에서 기여자 페이지를 열려면 클릭하십시오.",
"AboutRyujinxSupprtersTitle": "Patreon에서 지원 :",
"AmiiboSeriesLabel": "Amiibo 시리즈",
"AmiiboCharacterLabel": "성격",
"AmiiboScanButtonLabel": "스캔",
"AmiiboOptionsShowAllLabel": "모든 Amiibo 표시",
"AmiiboOptionsUsRandomTagLabel": "해킹: 임의의 태그 UUID 사용",
"DlcManagerTableHeadingEnabledLabel": "활성화됨",
"DlcManagerTableHeadingTitleIdLabel": "제목 ID",
"DlcManagerTableHeadingContainerPathLabel": "컨테이너 경로",
"DlcManagerTableHeadingFullPathLabel": "전체 경로",
"DlcManagerRemoveAllButton": "모두 제거",
"MenuBarOptionsChangeLanguage": "언어 변경",
"CommonSort": "정렬",
"CommonShowNames": "이름 표시",
"CommonFavorite": "가장 좋아하는",
"OrderAscending": "오름차순",
"OrderDescending": "내림차순",
"SettingsTabGraphicsFeatures": "특징",
"ErrorWindowTitle": "오류 창",
"ToggleDiscordTooltip": "Discord Rich Presence 활성화 또는 비활성화",
"AddGameDirBoxTooltip": "게임 디렉토리를 입력하여 목록에 추가하세요",
"AddGameDirTooltip": "목록에 게임 디렉토리 추가",
"RemoveGameDirTooltip": "선택한 게임 디렉토리 제거",
"CustomThemeCheckTooltip": "GUI에서 사용자 정의 테마 활성화 또는 비활성화",
"CustomThemePathTooltip": "사용자 지정 GUI 테마 경로",
"CustomThemeBrowseTooltip": "사용자 정의 GUI 테마 찾기",
"DockModeToggleTooltip": "도킹 모드 활성화 또는 비활성화",
"DirectKeyboardTooltip": "\"직접 키보드 액세스(HID) 지원\" 활성화 또는 비활성화(텍스트 입력 장치로 키보드에 대한 게임 액세스 제공)",
"DirectMouseTooltip": "\"직접 마우스 액세스(HID) 지원\" 활성화 또는 비활성화(포인팅 장치로 마우스에 대한 게임 액세스 제공)",
"RegionTooltip": "시스템 지역 변경",
"LanguageTooltip": "시스템 언어 변경",
"TimezoneTooltip": "시스템 시간대 변경",
"TimeTooltip": "시스템 시간 변경",
"VSyncToggleTooltip": "수직 동기화 활성화 또는 비활성화",
"PptcToggleTooltip": "PPTC 활성화 또는 비활성화",
"FsIntegrityToggleTooltip": "게임 콘텐츠 파일에 대한 무결성 검사 활성화",
"AudioBackendTooltip": "오디오 백엔드 변경",
"MemoryManagerTooltip": "게스트 메모리가 매핑되고 액세스되는 방식을 변경합니다. 에뮬레이트된 CPU 성능에 큰 영향을 줍니다.",
"MemoryManagerSoftwareTooltip": "주소 변환을 위해 소프트웨어 페이지 테이블을 사용하십시오. 정확도는 가장 높지만 성능은 가장 느립니다.",
"MemoryManagerHostTooltip": "호스트 주소 공간에서 메모리를 직접 매핑합니다. 훨씬 더 빠른 JIT 컴파일 및 실행.",
"MemoryManagerUnsafeTooltip": "메모리를 직접 매핑하지만 액세스하기 전에 게스트 주소 공간 내의 주소를 마스킹하지 마십시오. 더 빠르지만 안전을 희생해야 합니다. 게스트 응용 프로그램은 Ryujinx의 어디에서나 메모리에 액세스할 수 있으므로 이 모드로 신뢰할 수 있는 프로그램만 실행하십시오.",
"DRamTooltip": "에뮬레이트된 시스템의 메모리 양을 4GB에서 6GB로 확장",
"IgnoreMissingServicesTooltip": "누락된 서비스 무시 옵션 활성화 또는 비활성화",
"GraphicsBackendThreadingTooltip": "그래픽 백엔드 멀티스레딩 활성화",
"GalThreadingTooltip": "두 번째 스레드에서 그래픽 백엔드 명령을 실행합니다. 셰이더 컴파일의 런타임 멀티스레딩을 허용하고, 말더듬을 줄이고, 자체 멀티스레딩 지원 없이 드라이버의 성능을 개선합니다. 멀티스레딩이 있는 드라이버에서 약간 다른 최대 성능. 드라이버 내장 멀티스레딩을 올바르게 비활성화하려면 Ryujinx를 다시 시작해야 할 수도 있고 최상의 성능을 얻으려면 수동으로 수행해야 할 수도 있습니다.",
"ShaderCacheToggleTooltip": "셰이더 캐시 활성화 또는 비활성화",
"ResolutionScaleTooltip": "적용 가능한 렌더 타겟에 적용된 해상도 배율",
"ResolutionScaleEntryTooltip": "1.5와 같은 부동 소수점 해상도 스케일. 비적분 스케일은 문제나 충돌을 일으킬 가능성이 더 큽니다.",
"AnisotropyTooltip": "이방성 필터링 수준(게임에서 요청한 값을 사용하려면 자동으로 설정)",
"AspectRatioTooltip": "렌더러 창에 적용된 종횡비.",
"ShaderDumpPathTooltip": "그래픽 셰이더 덤프 경로",
"FileLogTooltip": "디스크의 파일에 대한 로깅 활성화 또는 비활성화",
"StubLogTooltip": "스텁 로그 메시지 인쇄 활성화",
"InfoLogTooltip": "정보 로그 메시지 인쇄 활성화",
"WarnLogTooltip": "경고 로그 메시지 인쇄 활성화",
"ErrorLogTooltip": "오류 로그 메시지 인쇄 활성화",
"GuestLogTooltip": "게스트 로그 메시지 인쇄 활성화",
"FileAccessLogTooltip": "파일 액세스 로그 메시지 인쇄 활성화",
"FSAccessLogModeTooltip": "콘솔에 대한 FS 액세스 로그 출력을 활성화합니다. 가능한 모드는 0-3입니다",
"DeveloperOptionTooltip": "주의해서 사용",
"OpenGlLogLevel": "적절한 로그 수준이 활성화되어 있어야 합니다",
"DebugLogTooltip": "디버그 로그 메시지 인쇄 활성화",
"LoadApplicationFileTooltip": "로드할 Switch 호환 파일을 선택하려면 파일 선택기를 엽니다.",
"LoadApplicationFolderTooltip": "파일 선택기를 열어 로드할 Switch 호환 가능하고 압축을 푼 응용 프로그램을 선택합니다",
"OpenRyujinxFolderTooltip": "Ryujinx 파일 시스템 폴더 열기",
"OpenRyujinxLogsTooltip": "로그가 기록되는 폴더를 엽니다.",
"ExitTooltip": "Ryujinx 종료",
"OpenSettingsTooltip": "설정 창 열기",
"OpenProfileManagerTooltip": "사용자 프로필 관리자 창 열기",
"StopEmulationTooltip": "현재 게임의 에뮬레이션을 중지하고 게임 선택으로 돌아가기",
"CheckUpdatesTooltip": "Ryujinx 업데이트 확인",
"OpenAboutTooltip": "정보 창 열기",
"GridSize": "그리드 크기",
"GridSizeTooltip": "그리드 항목의 크기 변경",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "포르투갈어(브라질)",
"AboutRyujinxContributorsButtonHeader": "모든 기여자 보기",
"SettingsTabSystemAudioVolume": "용량 : ",
"AudioVolumeTooltip": "오디오 볼륨 변경",
"SettingsTabSystemEnableInternetAccess": "게스트 인터넷 액세스 활성화s",
"EnableInternetAccessTooltip": "게스트 인터넷 액세스를 활성화합니다. 활성화된 경우 응용 프로그램은 에뮬레이트된 스위치 콘솔이 인터넷에 연결된 것처럼 작동합니다. 경우에 따라 이 옵션이 비활성화된 경우에도 응용 프로그램이 인터넷에 계속 액세스할 수 있습니다",
"GameListContextMenuManageCheatToolTip" : "치트 관리",
"GameListContextMenuManageCheat" : "치트 관리",
"ControllerSettingsStickRange" : "범위",
"DialogStopEmulationTitle" : "Ryujinx - 에뮬레이션 중지",
"DialogStopEmulationMessage": "에뮬레이션을 중지하시겠습니까?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "오디오",
"SettingsTabNetwork": "회로망",
"SettingsTabNetworkConnection" : "네트워크 연결",
"SettingsTabGraphicsFrameRate" : "호스트 새로 고침 빈도 :",
"SettingsTabGraphicsFrameRateTooltip" : "호스트 새로 고침 빈도를 설정합니다. 제한을 제거하려면 0으로 설정하십시오.",
"SettingsTabCpuCache" : "CPU 캐시",
"SettingsTabCpuMemory" : "CPU 메모리"
}

View file

@ -0,0 +1,544 @@
{
"MenuBarFileOpenApplet": "Abrir Applet",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abrir editor Mii em modo avulso",
"SettingsTabInputDirectMouseAccess": "Acesso direto ao mouse",
"SettingsTabSystemMemoryManagerMode": "Modo de gerenciamento de memória:",
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
"SettingsTabSystemMemoryManagerModeHost": "Hóspede (rápido)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Hóspede sem verificação (mais rápido, inseguro)",
"MenuBarFile": "_Arquivo",
"MenuBarFileOpenFromFile": "_Abrir ROM do jogo...",
"MenuBarFileOpenUnpacked": "Abrir jogo _extraído...",
"MenuBarFileOpenEmuFolder": "Abrir diretório do e_mulador...",
"MenuBarFileOpenLogsFolder": "Abrir diretório de _logs...",
"MenuBarFileExit": "_Sair",
"MenuBarOptions": "_Opções",
"MenuBarOptionsToggleFullscreen": "_Mudar para tela cheia",
"MenuBarOptionsStartGamesInFullscreen": "_Iniciar jogos em tela cheia",
"MenuBarOptionsStopEmulation": "_Encerrar emulação",
"MenuBarOptionsSettings": "_Configurações",
"MenuBarOptionsManageUserProfiles": "_Gerenciar perfis de usuário",
"MenuBarActions": "_Ações",
"MenuBarOptionsSimulateWakeUpMessage": "_Simular mensagem de acordar console",
"MenuBarActionsScanAmiibo": "Escanear um Amiibo",
"MenuBarTools": "_Ferramentas",
"MenuBarToolsInstallFirmware": "_Instalar firmware",
"MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware a partir de um arquivo ZIP/XCI",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware a partir de um diretório",
"MenuBarHelp": "A_juda",
"MenuBarHelpCheckForUpdates": "_Verificar se há atualizações",
"MenuBarHelpAbout": "_Sobre",
"MenuSearch": "Buscar...",
"GameListHeaderFavorite": "Favorito",
"GameListHeaderIcon": "Ícone",
"GameListHeaderApplication": "Nome",
"GameListHeaderDeveloper": "Desenvolvedor",
"GameListHeaderVersion": "Versão",
"GameListHeaderTimePlayed": "Tempo de jogo",
"GameListHeaderLastPlayed": "Último jogo",
"GameListHeaderFileExtension": "Extensão",
"GameListHeaderFileSize": "Tamanho",
"GameListHeaderPath": "Caminho",
"GameListContextMenuOpenUserSaveDirectory": "Abrir diretório de saves do usuário",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Abre o diretório que contém jogos salvos para o usuário atual",
"GameListContextMenuOpenUserDeviceDirectory": "Abrir diretório de saves de dispositivo do usuário",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Abre o diretório que contém saves do dispositivo para o usuário atual",
"GameListContextMenuOpenUserBcatDirectory": "Abrir diretório de saves BCAT do usuário",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Abre o diretório que contém saves BCAT para o usuário atual",
"GameListContextMenuManageTitleUpdates": "Gerenciar atualizações do jogo",
"GameListContextMenuManageTitleUpdatesToolTip": "Abre a janela de gerenciamento de atualizações",
"GameListContextMenuManageDlc": "Gerenciar DLCs",
"GameListContextMenuManageDlcToolTip": "Abre a janela de gerenciamento de DLCs",
"GameListContextMenuOpenModsDirectory": "Abrir diretório de mods",
"GameListContextMenuOpenModsDirectoryToolTip": "Abre o diretório que contém modificações (mods) do jogo",
"GameListContextMenuCacheManagement": "Gerenciamento de cache",
"GameListContextMenuCacheManagementPurgePptc": "Limpar cache PPTC",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Deleta o cache PPTC armazenado em disco do jogo",
"GameListContextMenuCacheManagementPurgeShaderCache": "Limpar cache de Shader",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Deleta o cache de Shader armazenado em disco do jogo",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Abrir diretório do cache PPTC",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Abre o diretório contendo os arquivos do cache PPTC",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Abrir diretório do cache de Shader",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Abre o diretório contendo os arquivos do cache de Shader",
"GameListContextMenuExtractData": "Extrair dados",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Extrai a seção ExeFS do jogo (incluindo atualizações)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Extrai a seção RomFS do jogo (incluindo atualizações)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Extrai a seção Logo do jogo (incluindo atualizações)",
"StatusBarGamesLoaded": "{0}/{1} jogos carregados",
"StatusBarSystemVersion": "Versão do firmware: {0}",
"Settings": "Configurações",
"SettingsTabGeneral": "Geral",
"SettingsTabGeneralGeneral": "Geral",
"SettingsTabGeneralEnableDiscordRichPresence": "Habilitar Rich Presence do Discord",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Verificar se há atualizações ao iniciar",
"SettingsTabGeneralShowConfirmExitDialog": "Exibir diálogo de confirmação ao sair",
"SettingsTabGeneralHideCursorOnIdle": "Esconder o cursor quando ocioso",
"SettingsTabGeneralGameDirectories": "Diretórios de jogo",
"SettingsTabGeneralAdd": "Adicionar",
"SettingsTabGeneralRemove": "Remover",
"SettingsTabSystem": "Sistema",
"SettingsTabSystemCore": "Principal",
"SettingsTabSystemSystemRegion": "Região do sistema:",
"SettingsTabSystemSystemRegionJapan": "Japão",
"SettingsTabSystemSystemRegionUSA": "EUA",
"SettingsTabSystemSystemRegionEurope": "Europa",
"SettingsTabSystemSystemRegionAustralia": "Austrália",
"SettingsTabSystemSystemRegionChina": "China",
"SettingsTabSystemSystemRegionKorea": "Coreia",
"SettingsTabSystemSystemRegionTaiwan": "Taiwan",
"SettingsTabSystemSystemLanguage": "Idioma do sistema:",
"SettingsTabSystemSystemLanguageJapanese": "Japonês",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Inglês americano",
"SettingsTabSystemSystemLanguageFrench": "Francês",
"SettingsTabSystemSystemLanguageGerman": "Alemão",
"SettingsTabSystemSystemLanguageItalian": "Italiano",
"SettingsTabSystemSystemLanguageSpanish": "Espanhol",
"SettingsTabSystemSystemLanguageChinese": "Chinês",
"SettingsTabSystemSystemLanguageKorean": "Coreano",
"SettingsTabSystemSystemLanguageDutch": "Holandês",
"SettingsTabSystemSystemLanguagePortuguese": "Português",
"SettingsTabSystemSystemLanguageRussian": "Russo",
"SettingsTabSystemSystemLanguageTaiwanese": "Taiwanês",
"SettingsTabSystemSystemLanguageBritishEnglish": "Inglês britânico",
"SettingsTabSystemSystemLanguageCanadianFrench": "Francês canadense",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Espanhol latino",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Chinês simplificado",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Chinês tradicional",
"SettingsTabSystemSystemTimeZone": "Fuso horário do sistema:",
"SettingsTabSystemSystemTime": "Hora do sistema:",
"SettingsTabSystemEnableVsync": "Habilitar sincronia vertical",
"SettingsTabSystemEnablePptc": "Habilitar PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Habilitar verificação de integridade do sistema de arquivos",
"SettingsTabSystemAudioBackend": "Biblioteca de saída de áudio:",
"SettingsTabSystemAudioBackendDummy": "Nenhuma",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacks",
"SettingsTabSystemHacksNote": " - Pode causar instabilidade",
"SettingsTabSystemExpandDramSize": "Expandir memória para 6GB",
"SettingsTabSystemIgnoreMissingServices": "Ignorar serviços não implementados",
"SettingsTabGraphics": "Gráficos",
"SettingsTabGraphicsEnhancements": "Melhorias",
"SettingsTabGraphicsEnableShaderCache": "Habilitar cache de shader",
"SettingsTabGraphicsAnisotropicFiltering": "Filtragem anisotrópica:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Auto",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Escala de resolução:",
"SettingsTabGraphicsResolutionScaleCustom": "Customizada (não recomendado)",
"SettingsTabGraphicsResolutionScaleNative": "Nativa (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Proporção:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Esticar até caber",
"SettingsTabGraphicsDeveloperOptions": "Opções do desenvolvedor",
"SettingsTabGraphicsShaderDumpPath": "Diretório para despejo de shaders:",
"SettingsTabLogging": "Log",
"SettingsTabLoggingLogging": "Log",
"SettingsTabLoggingEnableLoggingToFile": "Salvar logs em arquivo",
"SettingsTabLoggingEnableStubLogs": "Habilitar logs de stub",
"SettingsTabLoggingEnableInfoLogs": "Habilitar logs de informação",
"SettingsTabLoggingEnableWarningLogs": "Habilitar logs de alerta",
"SettingsTabLoggingEnableErrorLogs": "Habilitar logs de erro",
"SettingsTabLoggingEnableTraceLogs": "Habilitar logs de rastreamento",
"SettingsTabLoggingEnableGuestLogs": "Habilitar logs do programa convidado",
"SettingsTabLoggingEnableFsAccessLogs": "Habilitar logs de acesso ao sistema de arquivos",
"SettingsTabLoggingFsGlobalAccessLogMode": "Modo global de logs do sistema de arquivos:",
"SettingsTabLoggingDeveloperOptions": "Opções do desenvolvedor (AVISO: Vai reduzir a performance)",
"SettingsTabLoggingOpenglLogLevel": "Nível de log do OpenGL:",
"SettingsTabLoggingOpenglLogLevelNone": "Nenhum",
"SettingsTabLoggingOpenglLogLevelError": "Erro",
"SettingsTabLoggingOpenglLogLevelPerformance": "Lentidão",
"SettingsTabLoggingOpenglLogLevelAll": "Todos",
"SettingsTabLoggingEnableDebugLogs": "Habilitar logs de depuração",
"SettingsTabInput": "Controle",
"SettingsTabInputEnableDockedMode": "Habilitar modo TV",
"SettingsTabInputDirectKeyboardAccess": "Acesso direto ao teclado",
"SettingsButtonSave": "Salvar",
"SettingsButtonClose": "Fechar",
"SettingsButtonApply": "Aplicar",
"ControllerSettingsPlayer": "Jogador",
"ControllerSettingsPlayer1": "Jogador 1",
"ControllerSettingsPlayer2": "Jogador 2",
"ControllerSettingsPlayer3": "Jogador 3",
"ControllerSettingsPlayer4": "Jogador 4",
"ControllerSettingsPlayer5": "Jogador 5",
"ControllerSettingsPlayer6": "Jogador 6",
"ControllerSettingsPlayer7": "Jogador 7",
"ControllerSettingsPlayer8": "Jogador 8",
"ControllerSettingsHandheld": "Portátil",
"ControllerSettingsInputDevice": "Dispositivo de entrada",
"ControllerSettingsRefresh": "Atualizar",
"ControllerSettingsDeviceDisabled": "Disabled",
"ControllerSettingsControllerType": "Tipo do controle",
"ControllerSettingsControllerTypeHandheld": "Portátil",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "Par de JoyCon",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon esquerdo",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon direito",
"ControllerSettingsProfile": "Perfil",
"ControllerSettingsProfileDefault": "Padrão",
"ControllerSettingsLoad": "Carregar",
"ControllerSettingsAdd": "Adicionar",
"ControllerSettingsRemove": "Remover",
"ControllerSettingsButtons": "Botões",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Direcional",
"ControllerSettingsDPadUp": "Cima",
"ControllerSettingsDPadDown": "Baixo",
"ControllerSettingsDPadLeft": "Esquerda",
"ControllerSettingsDPadRight": "Direita",
"ControllerSettingsLStick": "Analógico esquerdo",
"ControllerSettingsLStickButton": "Botão",
"ControllerSettingsLStickUp": "Cima",
"ControllerSettingsLStickDown": "Baixo",
"ControllerSettingsLStickLeft": "Esquerda",
"ControllerSettingsLStickRight": "Direita",
"ControllerSettingsLStickStick": "Analógico",
"ControllerSettingsLStickInvertXAxis": "Inverter eixo X",
"ControllerSettingsLStickInvertYAxis": "Inverter eixo Y",
"ControllerSettingsLStickDeadzone": "Zona morta:",
"ControllerSettingsRStick": "Analógico direito",
"ControllerSettingsRStickButton": "Botão",
"ControllerSettingsRStickUp": "Cima",
"ControllerSettingsRStickDown": "Baixo",
"ControllerSettingsRStickLeft": "Esquerda",
"ControllerSettingsRStickRight": "Direita",
"ControllerSettingsRStickStick": "Analógico",
"ControllerSettingsRStickInvertXAxis": "Inverter eixo X",
"ControllerSettingsRStickInvertYAxis": "Inverter eixo Y",
"ControllerSettingsRStickDeadzone": "Zona morta:",
"ControllerSettingsTriggers": "Gatilhos",
"ControllerSettingsTriggersLeft": "Gatilhos esquerda",
"ControllerSettingsTriggersRight": "Gatilhos direita",
"ControllerSettingsTriggersButtonsLeft": "Botões de gatilho esquerda",
"ControllerSettingsTriggersButtonsRight": "Botões de gatilho direita",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Botões esquerda",
"ControllerSettingsExtraButtonsRight": "Botões direita",
"ControllerSettingsMisc": "Miscelâneas",
"ControllerSettingsTriggerThreshold": "Sensibilidade do gatilho:",
"ControllerSettingsMotion": "Sensor de movimento",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Habilitar sensor de movimento",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Usar sensor compatível com CemuHook",
"ControllerSettingsMotionControllerSlot": "Slot do controle:",
"ControllerSettingsMotionMirrorInput": "Espelhar movimento",
"ControllerSettingsMotionRightJoyConSlot": "Slot do JoyCon direito:",
"ControllerSettingsMotionServerHost": "Endereço do servidor:",
"ControllerSettingsMotionGyroSensitivity": "Sensibilidade do giroscópio:",
"ControllerSettingsMotionGyroDeadzone": "Zona morta do giroscópio:",
"ControllerSettingsSave": "Salvar",
"ControllerSettingsClose": "Fechar",
"UserProfilesSelectedUserProfile": "Perfil de usuário selecionado:",
"UserProfilesSaveProfileName": "Salvar nome de perfil",
"UserProfilesChangeProfileImage": "Mudar imagem de perfil",
"UserProfilesAvailableUserProfiles": "Perfis de usuário disponíveis:",
"UserProfilesAddNewProfile": "Adicionar novo perfil",
"UserProfilesDeleteSelectedProfile": "Apagar perfil selecionado",
"UserProfilesClose": "Fechar",
"ProfileImageSelectionTitle": "Seleção da imagem de perfil",
"ProfileImageSelectionHeader": "Escolha uma imagem de perfil",
"ProfileImageSelectionNote": "Você pode importar uma imagem customizada, ou selecionar um avatar do firmware",
"ProfileImageSelectionImportImage": "Importar arquivo de imagem",
"ProfileImageSelectionSelectAvatar": "Selecionar avatar do firmware",
"InputDialogTitle": "Diálogo de texto",
"InputDialogOk": "OK",
"InputDialogCancel": "Cancelar",
"InputDialogAddNewProfileTitle": "Escolha o nome de perfil",
"InputDialogAddNewProfileHeader": "Escreva o nome do perfil",
"InputDialogAddNewProfileSubtext": "(Máximo de caracteres: {0})",
"AvatarChoose": "Escolher",
"AvatarSetBackgroundColor": "Definir cor de fundo",
"AvatarClose": "Fechar",
"ControllerSettingsLoadProfileToolTip": "Carregar perfil",
"ControllerSettingsAddProfileToolTip": "Adicionar perfil",
"ControllerSettingsRemoveProfileToolTip": "Remover perfil",
"ControllerSettingsSaveProfileToolTip": "Salvar perfil",
"MenuBarFileToolsTakeScreenshot": "Salvar captura de tela",
"MenuBarFileToolsHideUi": "Esconder interface gráfica",
"GameListContextMenuToggleFavorite": "Alternar favorito",
"GameListContextMenuToggleFavoriteToolTip": "Marca ou desmarca jogo como favorito",
"SettingsTabGeneralTheme": "Tema",
"SettingsTabGeneralThemeCustomTheme": "Diretório de tema customizado",
"SettingsTabGeneralThemeBaseStyle": "Estilo base",
"SettingsTabGeneralThemeBaseStyleDark": "Escuro",
"SettingsTabGeneralThemeBaseStyleLight": "Claro",
"SettingsTabGeneralThemeEnableCustomTheme": "Habilitar tema customizado",
"ButtonBrowse": "Procurar",
"ControllerSettingsMotionConfigureCemuHookSettings": "Configurar sensor de movimento CemuHook",
"ControllerSettingsRumble": "Vibração",
"ControllerSettingsRumbleEnable": "Habilitar vibração",
"ControllerSettingsRumbleStrongMultiplier": "Multiplicador de vibração forte",
"ControllerSettingsRumbleWeakMultiplier": "Multiplicador de vibração fraca",
"DialogMessageSaveNotAvailableMessage": "Não há jogos salvos para {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Gostaria de criar o diretório de salvamento para esse jogo?",
"DialogConfirmationTitle": "Ryujinx - Confirmação",
"DialogUpdaterTitle": "Ryujinx - Atualizador",
"DialogErrorTitle": "Ryujinx - Erro",
"DialogWarningTitle": "Ryujinx - Alerta",
"DialogExitTitle": "Ryujinx - Sair",
"DialogErrorMessage": "Ryujinx encontrou um erro",
"DialogExitMessage": "Tem certeza que deseja fechar o Ryujinx?",
"DialogExitSubMessage": "Todos os dados que não foram salvos serão perdidos!",
"DialogMessageCreateSaveErrorMessage": "Ocorreu um erro ao criar o diretório de salvamento: {0}",
"DialogMessageFindSaveErrorMessage": "Ocorreu um erro ao tentar encontrar o diretório de salvamento: {0}",
"FolderDialogExtractTitle": "Escolha o diretório onde os arquivos serão extraídos",
"DialogNcaExtractionMessage": "Extraindo seção {0} de {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Extrator de seções NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Falha na extração. O NCA principal não foi encontrado no arquivo selecionado.",
"DialogNcaExtractionCheckLogErrorMessage": "Falha na extração. Leia o arquivo de log para mais informações.",
"DialogNcaExtractionSuccessMessage": "Extração concluída com êxito.",
"DialogUpdaterConvertFailedMessage": "Falha ao converter a versão atual do Ryujinx.",
"DialogUpdaterCancelUpdateMessage": "Cancelando atualização!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "Você já está usando a versão mais recente do Ryujinx!",
"DialogUpdaterFailedToGetVersionMessage": "Ocorreu um erro ao tentar obter informações de atualização do AppVeyor.",
"DialogUpdaterConvertFailedGithubMessage": "Falha ao converter a versão do Ryujinx recebida do AppVeyor.",
"DialogUpdaterDownloadingMessage": "Baixando atualização...",
"DialogUpdaterExtractionMessage": "Extraindo atualização...",
"DialogUpdaterRenamingMessage": "Renomeando atualização...",
"DialogUpdaterAddingFilesMessage": "Adicionando nova atualização...",
"DialogUpdaterCompleteMessage": "Atualização concluída!",
"DialogUpdaterRestartMessage": "Deseja reiniciar o Ryujinx agora?",
"DialogUpdaterArchNotSupportedMessage": "Você não está rodando uma arquitetura de sistema suportada!",
"DialogUpdaterArchNotSupportedSubMessage": "(Apenas sistemas x64 são suportados!)",
"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://ryujinx.org/ 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?",
"DialogFirmwareInstallEmbeddedMessage": "Gostaria de instalar o firmware incluso neste jogo? (Firmware {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "Nenhum firmware instalado foi encontrado, mas Ryujinx conseguiu instalar o firmware {0} do jogo fornecido.\nO emulador será reiniciado.",
"DialogFirmwareNoFirmwareInstalledMessage": "Firmware não foi instalado",
"DialogFirmwareInstalledMessage": "Firmware {0} foi instalado",
"DialogOpenSettingsWindowLabel": "Abrir janela de configurações",
"DialogControllerAppletTitle": "Applet de controle",
"DialogMessageDialogErrorExceptionMessage": "Erro ao exibir diálogo de mensagem: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Erro ao exibir teclado virtual: {0}",
"DialogErrorAppletErrorExceptionMessage": "Erro ao exibir applet ErrorApplet: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nPara mais informações sobre como corrigir esse erro, siga nosso Guia de Configuração.",
"DialogUserErrorDialogTitle": "Erro do Ryujinx ({0})",
"DialogAmiiboApiTitle": "API Amiibo",
"DialogAmiiboApiFailFetchMessage": "Um erro ocorreu ao tentar obter informações da API.",
"DialogAmiiboApiConnectErrorMessage": "Não foi possível conectar ao servidor da API Amiibo. O serviço pode estar fora do ar ou você precisa verificar sua conexão com a Internet.",
"DialogProfileInvalidProfileErrorMessage": "Perfil {0} é incompatível com o sistema de configuração de controle atual.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "O perfil Padrão não pode ser substituído",
"DialogProfileDeleteProfileTitle": "Apagando perfil",
"DialogProfileDeleteProfileMessage": "Essa ação é irreversível, tem certeza que deseja continuar?",
"DialogWarning": "Alerta",
"DialogPPTCDeletionMessage": "Você está prestes a apagar o cache PPTC para :\n\n{0}\n\nTem certeza que deseja continuar?",
"DialogPPTCDeletionErrorMessage": "Erro apagando cache PPTC em {0}: {1}",
"DialogShaderDeletionMessage": "Você está prestes a apagar o cache de Shader para :\n\n{0}\n\nTem certeza que deseja continuar?",
"DialogShaderDeletionErrorMessage": "Erro apagando o cache de Shader em {0}: {1}",
"DialogRyujinxErrorMessage": "Ryujinx encontrou um erro",
"DialogInvalidTitleIdErrorMessage": "Erro de interface: O jogo selecionado não tem um ID de título válido",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Um firmware de sistema válido não foi encontrado em {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Instalar firmware {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "A versão do sistema {0} será instalada.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nIsso substituirá a versão do sistema atual {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nDeseja continuar?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Instalando firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versão do sistema {0} instalada com sucesso.",
"DialogUserProfileDeletionWarningMessage": "Não haveria nenhum perfil selecionado se o perfil atual fosse deletado",
"DialogUserProfileDeletionConfirmMessage": "Deseja deletar o perfil selecionado",
"DialogControllerSettingsModifiedConfirmMessage": "As configurações de controle atuais foram atualizadas.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Deseja salvar?",
"DialogDlcLoadNcaErrorMessage": "{0}. Arquivo com erro: {1}",
"DialogDlcNoDlcErrorMessage": "O arquivo especificado não contém DLCs para o título selecionado!",
"DialogPerformanceCheckLoggingEnabledMessage": "Os logs de depuração estão ativos, esse recurso é feito para ser usado apenas por desenvolvedores.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Para melhor performance, é recomendável desabilitar os logs de depuração. Gostaria de desabilitar os logs de depuração agora?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "O despejo de shaders está ativo, esse recurso é feito para ser usado apenas por desenvolvedores.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Para melhor performance, é recomendável desabilitar o despejo de shaders. Gostaria de desabilitar o despejo de shaders agora?",
"DialogLoadAppGameAlreadyLoadedMessage": "Um jogo já foi carregado",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Por favor, pare a emulação ou feche o emulador antes de abrir outro jogo.",
"DialogUpdateAddUpdateErrorMessage": "O arquivo especificado não contém atualizações para o título selecionado!",
"DialogSettingsBackendThreadingWarningTitle": "Alerta - Threading da API gráfica",
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx precisa ser reiniciado após mudar essa opção para que ela tenha efeito. Dependendo da sua plataforma, pode ser preciso desabilitar o multithreading do driver de vídeo quando usar o Ryujinx.",
"SettingsTabGraphicsFeaturesOptions": "Recursos",
"SettingsTabGraphicsBackendMultithreading": "Multithreading da API gráfica:",
"CommonAuto": "Automático",
"CommonOff": "Desligado",
"CommonOn": "Ligado",
"InputDialogYes": "Sim",
"InputDialogNo": "Não",
"DialogProfileInvalidProfileNameErrorMessage": "O nome do arquivo contém caracteres inválidos. Por favor, tente novamente.",
"MenuBarOptionsPauseEmulation": "Pausar",
"MenuBarOptionsResumeEmulation": "Resumir",
"AboutUrlTooltipMessage": "Clique para abrir o site do Ryujinx no seu navegador padrão.",
"AboutDisclaimerMessage": "Ryujinx não é afiliado com a Nintendo™,\nou qualquer um de seus parceiros, de nenhum modo.",
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) é usado\nem nossa emulação de Amiibo.",
"AboutPatreonUrlTooltipMessage": "Clique para abrir a página do Patreon do Ryujinx no seu navegador padrão.",
"AboutGithubUrlTooltipMessage": "Clique para abrir a página do GitHub do Ryujinx no seu navegador padrão.",
"AboutDiscordUrlTooltipMessage": "Clique para abrir um convite ao servidor do Discord do Ryujinx no seu navegador padrão.",
"AboutTwitterUrlTooltipMessage": "Clique para abrir a página do Twitter do Ryujinx no seu navegador padrão.",
"AboutRyujinxAboutTitle": "Sobre:",
"AboutRyujinxAboutContent": "Ryujinx é um emulador de Nintendo Switch™.\nPor favor, nos dê apoio no Patreon.\nFique por dentro de todas as novidades no Twitter ou Discord.\nDesenvolvedores com interesse em contribuir podem conseguir mais informações no GitHub ou Discord.",
"AboutRyujinxMaintainersTitle": "Mantido por:",
"AboutRyujinxMaintainersContentTooltipMessage": "Clique para abrir a página de contribuidores no seu navegador padrão.",
"AboutRyujinxSupprtersTitle": "Apoiado no Patreon por:",
"AmiiboSeriesLabel": "Franquia Amiibo",
"AmiiboCharacterLabel": "Personagem",
"AmiiboScanButtonLabel": "Escanear",
"AmiiboOptionsShowAllLabel": "Exibir todos os Amiibos",
"AmiiboOptionsUsRandomTagLabel": "Hack: Usar Uuid de tag aleatório",
"DlcManagerTableHeadingEnabledLabel": "Habilitado",
"DlcManagerTableHeadingTitleIdLabel": "ID do título",
"DlcManagerTableHeadingContainerPathLabel": "Caminho do container",
"DlcManagerTableHeadingFullPathLabel": "Caminho completo",
"DlcManagerRemoveAllButton": "Remover todos",
"MenuBarOptionsChangeLanguage": "Mudar idioma",
"CommonSort": "Ordenar",
"CommonShowNames": "Exibir nomes",
"CommonFavorite": "Favorito",
"OrderAscending": "Ascendente",
"OrderDescending": "Descendente",
"SettingsTabGraphicsFeatures": "Recursos",
"ErrorWindowTitle": "Janela de erro",
"ToggleDiscordTooltip": "Habilita ou desabilita Discord Rich Presence",
"AddGameDirBoxTooltip": "Escreva um diretório de jogo para adicionar à lista",
"AddGameDirTooltip": "Adicionar um diretório de jogo à lista",
"RemoveGameDirTooltip": "Remover diretório de jogo selecionado",
"CustomThemeCheckTooltip": "Habilita ou desabilita temas customizados na interface gráfica",
"CustomThemePathTooltip": "Diretório do tema customizado",
"CustomThemeBrowseTooltip": "Navegar até um tema customizado",
"DockModeToggleTooltip": "Habilita ou desabilita modo TV",
"DirectKeyboardTooltip": "Habilita ou desabilita \"acesso direto ao teclado (HID)\" (Permite que o jogo acesse o seu teclado como dispositivo de entrada de texto)",
"DirectMouseTooltip": "Habilita ou desabilita \"acesso direto ao mouse (HID)\" (Permite que o jogo acesse o seu mouse como dispositivo apontador)",
"RegionTooltip": "Mudar a região do sistema",
"LanguageTooltip": "Mudar o idioma do sistema",
"TimezoneTooltip": "Mudar o fuso-horário do sistema",
"TimeTooltip": "Mudar a hora do sistema",
"VSyncToggleTooltip": "Habilita ou desabilita a sincronia vertical",
"PptcToggleTooltip": "Habilita ou desabilita PPTC",
"FsIntegrityToggleTooltip": "Habilita ou desabilita verificação de integridade dos arquivos do jogo",
"AudioBackendTooltip": "Mudar biblioteca de áudio",
"MemoryManagerTooltip": "Muda como a memória do sistema convidado é acessada. Tem um grande impacto na performance da CPU emulada.",
"MemoryManagerSoftwareTooltip": "Usar uma tabela de página via software para tradução de endereços. Maior precisão, porém performance mais baixa.",
"MemoryManagerHostTooltip": "Mapeia memória no espaço de endereço hóspede diretamente. Compilação e execução do JIT muito mais rápida.",
"MemoryManagerUnsafeTooltip": "Mapeia memória diretamente, mas sem limitar o endereço ao espaço de endereço do sistema convidado antes de acessar. Mais rápido, porém menos seguro. O aplicativo convidado pode acessar memória de qualquer parte do Ryujinx, então apenas rode programas em que você confia nesse modo.",
"DRamTooltip": "Expande a memória do sistema emulado de 4GB para 6GB",
"IgnoreMissingServicesTooltip": "Habilita ou desabilita a opção de ignorar serviços não implementados",
"GraphicsBackendThreadingTooltip": "Habilita multithreading do backend gráfico",
"GalThreadingTooltip": "Executa comandos do backend gráfico em uma segunda thread. Permite multithreading em tempo de execução da compilação de shader, diminui os travamentos, e melhora performance em drivers sem suporte embutido a multithreading. Pequena variação na performance máxima em drivers com suporte a multithreading. Ryujinx pode precisar ser reiniciado para desabilitar adequadamente o multithreading embutido do driver, ou você pode precisar fazer isso manualmente para ter a melhor performance.",
"ShaderCacheToggleTooltip": "Habilita ou desabilita o cache de shader",
"ResolutionScaleTooltip": "Escala de resolução aplicada às texturas de renderização",
"ResolutionScaleEntryTooltip": "Escala de resolução de ponto flutuante, como 1.5. Valores não inteiros tem probabilidade maior de causar problemas ou quebras.",
"AnisotropyTooltip": "Nível de filtragem anisotrópica (deixe em Auto para usar o valor solicitado pelo jogo)",
"AspectRatioTooltip": "Taxa de proporção aplicada à janela do renderizador.",
"ShaderDumpPathTooltip": "Diretòrio de despejo de shaders",
"FileLogTooltip": "Habilita ou desabilita log para um arquivo no disco",
"StubLogTooltip": "Habilita ou desabilita exibição de mensagens de stub",
"InfoLogTooltip": "Habilita ou desabilita exibição de mensagens informativas",
"WarnLogTooltip": "Habilita ou desabilita exibição de mensagens de alerta",
"ErrorLogTooltip": "Habilita ou desabilita exibição de mensagens de erro",
"TraceLogTooltip": "Habilita ou desabilita exibição de mensagens de rastreamento",
"GuestLogTooltip": "Habilita ou desabilita exibição de mensagens do programa convidado",
"FileAccessLogTooltip": "Habilita ou desabilita exibição de mensagens do acesso de arquivos",
"FSAccessLogModeTooltip": "Habilita exibição de mensagens de acesso ao sistema de arquivos no console. Modos permitidos são 0-3",
"DeveloperOptionTooltip": "Use com cuidado",
"OpenGlLogLevel": "Requer que os níveis de log apropriados estejaam habilitados",
"DebugLogTooltip": "Habilita exibição de mensagens de depuração",
"LoadApplicationFileTooltip": "Abre o navegador de arquivos para seleção de um arquivo do Switch compatível a ser carregado",
"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",
"OpenRyujinxLogsTooltip": "Abre o diretório onde os logs são salvos",
"ExitTooltip": "Sair do Ryujinx",
"OpenSettingsTooltip": "Abrir janela de configurações",
"OpenProfileManagerTooltip": "Abrir janela de gerenciamento de perfis",
"StopEmulationTooltip": "Parar emulação do jogo atual e voltar a seleção de jogos",
"CheckUpdatesTooltip": "Verificar por atualizações para o Ryujinx",
"OpenAboutTooltip": "Abrir janela sobre",
"GridSize": "Tamanho da grade",
"GridSizeTooltip": "Mudar tamanho dos items da grade",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Português do Brasil",
"AboutRyujinxContributorsButtonHeader": "Ver todos os contribuidores",
"SettingsTabSystemAudioVolume": "Volume: ",
"AudioVolumeTooltip": "Mudar volume do áudio",
"SettingsTabSystemEnableInternetAccess": "Habilitar acesso à internet do programa convidado",
"EnableInternetAccessTooltip": "Habilita acesso à internet do programa convidado. Se habilitado, o aplicativo vai se comportar como se o sistema Switch emulado estivesse conectado a Internet. Note que em alguns casos, aplicativos podem acessar a Internet mesmo com essa opção desabilitada",
"GameListContextMenuManageCheatToolTip": "Gerenciar Cheats",
"GameListContextMenuManageCheat": "Gerenciar Cheats",
"ControllerSettingsStickRange": "Intervalo",
"DialogStopEmulationTitle": "Ryujinx - Parar emulação",
"DialogStopEmulationMessage": "Tem certeza que deseja parar a emulação?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "Áudio",
"SettingsTabNetwork": "Rede",
"SettingsTabNetworkConnection": "Conexão de rede",
"SettingsTabGraphicsFrameRate": "Taxa de atualização do hóspede:",
"SettingsTabGraphicsFrameRateTooltip": "Define a taxa de atualização do hóspede. Coloque em 0 para remover o limite.",
"SettingsTabCpuCache": "Cache da CPU",
"SettingsTabCpuMemory": "Memória da CPU",
"DialogUpdaterFlatpakNotSupportedMessage": "Por favor, atualize o Ryujinx pelo FlatHub.",
"UpdaterDisabledWarningTitle": "Atualizador desabilitado!",
"GameListContextMenuOpenSdModsDirectory": "Abrir diretório de mods Atmosphere",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Abre o diretório alternativo Atmosphere no cartão SD que contém mods para o aplicativo",
"ControllerSettingsRotate90": "Rodar 90° sentido horário",
"IconSize": "Tamanho do ícone",
"IconSizeTooltip": "Muda o tamanho do ícone do jogo",
"MenuBarOptionsShowConsole": "Exibir console",
"ShaderCachePurgeError": "Erro ao deletar o shader em {0}: {1}",
"UserErrorNoKeys": "Chaves não encontradas",
"UserErrorNoFirmware": "Firmware não encontrado",
"UserErrorFirmwareParsingFailed": "Erro na leitura do Firmware",
"UserErrorApplicationNotFound": "Aplicativo não encontrado",
"UserErrorUnknown": "Erro desconhecido",
"UserErrorUndefined": "Erro indefinido",
"UserErrorNoKeysDescription": "Ryujinx não conseguiu encontrar o seu arquivo 'prod.keys'",
"UserErrorNoFirmwareDescription": "Ryujinx não conseguiu encontrar nenhum Firmware instalado",
"UserErrorFirmwareParsingFailedDescription": "Ryujinx não conseguiu ler o Firmware fornecido. Geralmente isso é causado por chaves desatualizadas.",
"UserErrorApplicationNotFoundDescription": "Ryujinx não conseguiu encontrar um aplicativo válido no caminho fornecido.",
"UserErrorUnknownDescription": "Um erro desconhecido foi encontrado!",
"UserErrorUndefinedDescription": "Um erro indefinido occoreu! Isso não deveria acontecer, por favor contate um desenvolvedor!",
"OpenSetupGuideMessage": "Abrir o guia de configuração",
"NoUpdate": "Sem atualizações",
"TitleUpdateVersionLabel": "Versão {0} - {1}",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Confirmação",
"FileDialogAllTypes": "Todos os tipos",
"Never": "Nunca",
"SwkbdMinCharacters": "Deve ter pelo menos {0} caracteres",
"SwkbdMinRangeCharacters": "Deve ter entre {0}-{1} caracteres",
"SoftwareKeyboard": "Teclado por Software",
"DialogControllerAppletMessagePlayerRange": "O aplicativo requer {0} jogador(es) com:\n\nTIPOS: {1}\n\nJOGADORES: {2}\n\n{3}Por favor, abra as configurações e reconfigure os controles agora ou clique em Fechar.",
"DialogControllerAppletMessage": "O aplicativo requer exatamente {0} jogador(es) com:\n\nTIPOS: {1}\n\nJOGADORES: {2}\n\n{3}Por favor, abra as configurações e reconfigure os controles agora ou clique em Fechar.",
"DialogControllerAppletDockModeSet": "Modo TV ativado. Portátil também não é válido.\n\n",
"UpdaterRenaming": "Renomeando arquivos antigos...",
"UpdaterRenameFailed": "O atualizador não conseguiu renomear o arquivo: {0}",
"UpdaterAddingFiles": "Adicionando novos arquivos...",
"UpdaterExtracting": "Extraíndo atualização...",
"UpdaterDownloading": "Baixando atualização...",
"Game": "Jogo",
"Docked": "TV",
"Handheld": "Portátil",
"ConnectionError": "Erro de conexão.",
"AboutPageDeveloperListMore": "{0} e mais...",
"ApiError": "Erro de API."
}

View file

@ -0,0 +1,497 @@
{
"MenuBarFileOpenApplet": "Открыть апплет",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Открыть апплет Mii Editor в автономном режиме.",
"SettingsTabInputDirectMouseAccess": "Прямой доступ с помощью мыши",
"SettingsTabSystemMemoryManagerMode": "Режим диспетчера памяти:",
"SettingsTabSystemMemoryManagerModeSoftware": "Программное обеспечение",
"SettingsTabSystemMemoryManagerModeHost": "Хост (быстро)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Хост не установлен (самый быстрый, небезопасный)",
"MenuBarFile": "_Файл",
"MenuBarFileOpenFromFile": "_Загрузить приложение из файла",
"MenuBarFileOpenUnpacked": "Загрузить _Распакованную игру",
"MenuBarFileOpenEmuFolder": "Открыть папку Ryujinx",
"MenuBarFileOpenLogsFolder": "Открыть папку журналов",
"MenuBarFileExit": "_Выход",
"MenuBarOptions": "Опции",
"MenuBarOptionsToggleFullscreen": "Включить полноэкранный режим",
"MenuBarOptionsStartGamesInFullscreen": "Запустить игру в полноэкранном режиме",
"MenuBarOptionsStopEmulation": "Остановить эмуляцию",
"MenuBarOptionsSettings": "_Параметры",
"MenuBarOptionsManageUserProfiles": "_Управление профилями пользователей",
"MenuBarActions": "_Действия",
"MenuBarOptionsSimulateWakeUpMessage": "Имитировать сообщение пробуждения",
"MenuBarActionsScanAmiibo": "Сканировать Amiibo",
"MenuBarTools": "_Инструменты",
"MenuBarToolsInstallFirmware": "Установить прошивку",
"MenuBarFileToolsInstallFirmwareFromFile": "Установить прошивку из XCI или ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Установить прошивку из каталога",
"MenuBarHelp": "Помощь",
"MenuBarHelpCheckForUpdates": "Проверить обновление",
"MenuBarHelpAbout": "О",
"MenuSearch": "Поиск...",
"GameListHeaderFavorite": "Избранные",
"GameListHeaderIcon": "Значок",
"GameListHeaderApplication": "Название",
"GameListHeaderDeveloper": "Разработчик",
"GameListHeaderVersion": "Версия",
"GameListHeaderTimePlayed": "Время воспроизведения",
"GameListHeaderLastPlayed": "Последняя игра",
"GameListHeaderFileExtension": "Расширение файла",
"GameListHeaderFileSize": "Размер файла",
"GameListHeaderPath": "Путь",
"GameListContextMenuOpenUserSaveDirectory": "Открыть каталог сохранений пользователя",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Открывает каталог, содержащий пользовательское сохранение приложения",
"GameListContextMenuOpenUserDeviceDirectory": "Открыть каталог пользовательских устройств",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Открывает каталог, содержащий сохранение устройства приложения",
"GameListContextMenuOpenUserBcatDirectory": "Открыть каталог пользователей BCAT",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Открывает каталог, содержащий BCAT сохранения приложения.",
"GameListContextMenuManageTitleUpdates": "Управление обновлениями заголовков",
"GameListContextMenuManageTitleUpdatesToolTip": "Открывает окно управления обновлением заголовков",
"GameListContextMenuManageDlc": "Управление DLC",
"GameListContextMenuManageDlcToolTip": "Открывает окно управления DLC",
"GameListContextMenuOpenModsDirectory": "Открыть каталог модификаций",
"GameListContextMenuOpenModsDirectoryToolTip": "Открывает каталог, содержащий модификации приложения",
"GameListContextMenuCacheManagement": "Управление кэшем",
"GameListContextMenuCacheManagementPurgePptc": "Очистить кэш PPTC",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Удаляет кэш PPTC приложения",
"GameListContextMenuCacheManagementPurgeShaderCache": "Очистить кэш шейдеров",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Удаляет кеш шейдеров приложения",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Открыть PPTC каталог",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Открывает каталог, содержащий PPTC кэш приложения",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Открыть каталог кэша шейдеров",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Открывает каталог, содержащий кэш шейдеров приложения",
"GameListContextMenuExtractData": "Извлечь данные",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Извлеrftn раздел ExeFS из текущей конфигурации приложения (включая обновления)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Извлекает раздел RomFS из текущей конфигурации приложения (включая обновления)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Извлекает раздел логотипа из текущей конфигурации приложения (включая обновления)",
"StatusBarGamesLoaded": "{0}/{1} Игр загружено",
"StatusBarSystemVersion": "Версия системы: {0}",
"Settings": "Параметры",
"SettingsTabGeneral": "Пользовательский интерфейс",
"SettingsTabGeneralGeneral": "Общее",
"SettingsTabGeneralEnableDiscordRichPresence": "Включить расширенное присутствие Discord",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Проверять наличие обновлений при запуске",
"SettingsTabGeneralShowConfirmExitDialog": "Показать диалоговое окно \"Подтвердить выход\"",
"SettingsTabGeneralHideCursorOnIdle": "Скрыть курсор в режиме ожидания",
"SettingsTabGeneralGameDirectories": "Каталоги игр",
"SettingsTabGeneralAdd": "Добавить",
"SettingsTabGeneralRemove": "Удалить",
"SettingsTabSystem": "Система",
"SettingsTabSystemCore": "Основные настройки",
"SettingsTabSystemSystemRegion": "Регион Системы:",
"SettingsTabSystemSystemRegionJapan": "Япония",
"SettingsTabSystemSystemRegionUSA": "США",
"SettingsTabSystemSystemRegionEurope": "Европа",
"SettingsTabSystemSystemRegionAustralia": "Австралия",
"SettingsTabSystemSystemRegionChina": "Китай",
"SettingsTabSystemSystemRegionKorea": "Корея",
"SettingsTabSystemSystemRegionTaiwan": "Тайвань",
"SettingsTabSystemSystemLanguage": "Язык системы:",
"SettingsTabSystemSystemLanguageJapanese": "Японский",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Английский (США)",
"SettingsTabSystemSystemLanguageFrench": "Французский",
"SettingsTabSystemSystemLanguageGerman": "Германский",
"SettingsTabSystemSystemLanguageItalian": "Итальянский",
"SettingsTabSystemSystemLanguageSpanish": "Испанский",
"SettingsTabSystemSystemLanguageChinese": "Китайский",
"SettingsTabSystemSystemLanguageKorean": "Корейский",
"SettingsTabSystemSystemLanguageDutch": "Нидерландский",
"SettingsTabSystemSystemLanguagePortuguese": "Португальский",
"SettingsTabSystemSystemLanguageRussian": "Русский",
"SettingsTabSystemSystemLanguageTaiwanese": "Тайванский",
"SettingsTabSystemSystemLanguageBritishEnglish": "Английский (Британия)",
"SettingsTabSystemSystemLanguageCanadianFrench": "Французский (Канада)",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Испанский (Латиноамериканский)",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Китайский упрощённый",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Китайский традиционный",
"SettingsTabSystemSystemTimeZone": "Часовой пояс системы:",
"SettingsTabSystemSystemTime": "Время системы:",
"SettingsTabSystemEnableVsync": "Включить вертикальную синхронизацию",
"SettingsTabSystemEnablePptc": "Включить PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "Включить проверку целостности FS",
"SettingsTabSystemAudioBackend": "Аудио бэкэнд:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Хаки",
"SettingsTabSystemHacksNote": " - Эти многие настройки вызывают нестабильность",
"SettingsTabSystemExpandDramSize": "Увеличение размера DRAM до 6GB",
"SettingsTabSystemIgnoreMissingServices": "Игнорировать отсутствующие службы",
"SettingsTabGraphics": "Графика",
"SettingsTabGraphicsEnhancements": "Улучшения",
"SettingsTabGraphicsEnableShaderCache": "Включить кэш шейдеров",
"SettingsTabGraphicsAnisotropicFiltering": "Анизотропная фильтрация:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Автоматически",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Масштаб:",
"SettingsTabGraphicsResolutionScaleCustom": "Пользовательский (не рекомендуется)",
"SettingsTabGraphicsResolutionScaleNative": "Родной (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "Соотношение сторон:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Растянуть до размеров окна",
"SettingsTabGraphicsDeveloperOptions": "Параметры разработчика",
"SettingsTabGraphicsShaderDumpPath": "Путь дампа графического шейдера:",
"SettingsTabLogging": "Журналирование",
"SettingsTabLoggingLogging": "Журналирование",
"SettingsTabLoggingEnableLoggingToFile": "Включить запись в файл",
"SettingsTabLoggingEnableStubLogs": "Включить журналы-заглушки",
"SettingsTabLoggingEnableInfoLogs": "Включить информационные журналы",
"SettingsTabLoggingEnableWarningLogs": "Включить журналы предупреждений",
"SettingsTabLoggingEnableErrorLogs": "Включить журналы ошибок",
"SettingsTabLoggingEnableGuestLogs": "Включить гостевые журналы",
"SettingsTabLoggingEnableFsAccessLogs": "Включить журналы доступа Fs",
"SettingsTabLoggingFsGlobalAccessLogMode": "Режим журнала глобального доступа Fs:",
"SettingsTabLoggingDeveloperOptions": "Параметры разработчика (ВНИМАНИЕ: снизит производительность)",
"SettingsTabLoggingOpenglLogLevel": "Уровень журнала OpenGL:",
"SettingsTabLoggingOpenglLogLevelNone": "Ничего",
"SettingsTabLoggingOpenglLogLevelError": "Ошибка",
"SettingsTabLoggingOpenglLogLevelPerformance": "Замедления",
"SettingsTabLoggingOpenglLogLevelAll": "Всё",
"SettingsTabLoggingEnableDebugLogs": "Включить журналы отладки",
"SettingsTabInput": "Управление",
"SettingsTabInputEnableDockedMode": "Включить режим закрепления",
"SettingsTabInputDirectKeyboardAccess": "Прямой доступ с клавиатуры",
"SettingsButtonSave": "Сохранить",
"SettingsButtonClose": "Закрыть",
"SettingsButtonApply": "Применить",
"ControllerSettingsPlayer": "Игрок",
"ControllerSettingsPlayer1": "Игрок 1",
"ControllerSettingsPlayer2": "Игрок 2",
"ControllerSettingsPlayer3": "Игрок 3",
"ControllerSettingsPlayer4": "Игрок 4",
"ControllerSettingsPlayer5": "Игрок 5",
"ControllerSettingsPlayer6": "Игрок 6",
"ControllerSettingsPlayer7": "Игрок 7",
"ControllerSettingsPlayer8": "Игрок 8",
"ControllerSettingsHandheld": "Портативный",
"ControllerSettingsInputDevice": "Устройство ввода",
"ControllerSettingsRefresh": "Обновить",
"ControllerSettingsDeviceDisabled": "Отключить",
"ControllerSettingsControllerType": "Тип контроллера",
"ControllerSettingsControllerTypeHandheld": "Портативный",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "JoyCon Пара",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Левый",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon Правый",
"ControllerSettingsProfile": "Профиль",
"ControllerSettingsProfileDefault": "По умолчанию",
"ControllerSettingsLoad": "Загрузить",
"ControllerSettingsAdd": "Добавить",
"ControllerSettingsRemove": "Удалить",
"ControllerSettingsButtons": "Кнопки",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Directional Pad",
"ControllerSettingsDPadUp": "Верх",
"ControllerSettingsDPadDown": "Низ",
"ControllerSettingsDPadLeft": "Лево",
"ControllerSettingsDPadRight": "Право",
"ControllerSettingsLStick": "Левый стик",
"ControllerSettingsLStickButton": "Кнопки",
"ControllerSettingsLStickUp": "Верх",
"ControllerSettingsLStickDown": "Низ",
"ControllerSettingsLStickLeft": "Лево",
"ControllerSettingsLStickRight": "Право",
"ControllerSettingsLStickStick": "Стик",
"ControllerSettingsLStickInvertXAxis": "Перевернуть стик X",
"ControllerSettingsLStickInvertYAxis": "Перевернуть стик Y",
"ControllerSettingsLStickDeadzone": "Мёртвая зона:",
"ControllerSettingsRStick": "Правый стик",
"ControllerSettingsRStickButton": "Кнопки",
"ControllerSettingsRStickUp": "Верх",
"ControllerSettingsRStickDown": "Низ",
"ControllerSettingsRStickLeft": "Лево",
"ControllerSettingsRStickRight": "Право",
"ControllerSettingsRStickStick": "Стик",
"ControllerSettingsRStickInvertXAxis": "Перевернуть стик X",
"ControllerSettingsRStickInvertYAxis": "Перевернуть стик Y",
"ControllerSettingsRStickDeadzone": "Мёртвая зона:",
"ControllerSettingsTriggersLeft": "Триггеры слева",
"ControllerSettingsTriggersRight": "Триггеры справа",
"ControllerSettingsTriggersButtonsLeft": "Триггерные кнопки слева",
"ControllerSettingsTriggersButtonsRight": "Триггерные кнопки справа",
"ControllerSettingsTriggers": "Триггеры",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Левый кнопки",
"ControllerSettingsExtraButtonsRight": "Правые кнопки",
"ControllerSettingsMisc": "Разное",
"ControllerSettingsTriggerThreshold": "Порог срабатывания:",
"ControllerSettingsMotion": "Движение",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Включить управление движением",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "Используйте движение, совместимое с CemuHook",
"ControllerSettingsMotionControllerSlot": "Слот контроллера:",
"ControllerSettingsMotionMirrorInput": "Зеркальный ввод",
"ControllerSettingsMotionRightJoyConSlot": "Правый JoyCon слот:",
"ControllerSettingsMotionServerHost": "Хост сервера:",
"ControllerSettingsMotionGyroSensitivity": "Чувствительность гироскопа:",
"ControllerSettingsMotionGyroDeadzone": "Мертвая зона гироскопа:",
"ControllerSettingsSave": "Сохранить",
"ControllerSettingsClose": "Закрыть",
"UserProfilesSelectedUserProfile": "Выбранный пользовательский профиль:",
"UserProfilesSaveProfileName": "Сохранить пользовательский профиль",
"UserProfilesChangeProfileImage": "Изменить изображение профиля",
"UserProfilesAvailableUserProfiles": "Доступные профили пользователей:",
"UserProfilesAddNewProfile": "Добавить новый профиль",
"UserProfilesDeleteSelectedProfile": "Удалить выбранный профиль",
"UserProfilesClose": "Закрыть",
"ProfileImageSelectionTitle": "Выбор изображения профиля",
"ProfileImageSelectionHeader": "Выберите изображение профиля",
"ProfileImageSelectionNote": "Вы можете импортировать собственное изображение профиля или выбрать аватар из системной прошивки.",
"ProfileImageSelectionImportImage": "Импорт файла изображени",
"ProfileImageSelectionSelectAvatar": "Выберите аватар прошивки",
"InputDialogTitle": "Диалоговое окно ввода",
"InputDialogOk": "Да",
"InputDialogCancel": "Закрыть",
"InputDialogAddNewProfileTitle": "Выберите имя профиля",
"InputDialogAddNewProfileHeader": "Пожалуйста, введите имя профиля",
"InputDialogAddNewProfileSubtext": "(Максимальная длина: {0})",
"AvatarChoose": "Выбор",
"AvatarSetBackgroundColor": "Установить цвет фона",
"AvatarClose": "Закрыть",
"ControllerSettingsLoadProfileToolTip": "Загрузить профиль",
"ControllerSettingsAddProfileToolTip": "Добавить профил",
"ControllerSettingsRemoveProfileToolTip": "Удалить профиль",
"ControllerSettingsSaveProfileToolTip": "Сохранить профиль",
"MenuBarFileToolsTakeScreenshot": "Сделать снимок экрана",
"MenuBarFileToolsHideUi": "Спрятать пользовательский интерфейс",
"GameListContextMenuToggleFavorite": "Переключить Избранное",
"GameListContextMenuToggleFavoriteToolTip": "Переключить любимый статус игры",
"SettingsTabGeneralTheme": "Тема",
"SettingsTabGeneralThemeCustomTheme": "Пользовательский путь к теме",
"SettingsTabGeneralThemeBaseStyle": "Базовый стиль",
"SettingsTabGeneralThemeBaseStyleDark": "Тёмная",
"SettingsTabGeneralThemeBaseStyleLight": "Светлая",
"SettingsTabGeneralThemeEnableCustomTheme": "Включить пользовательскую тему",
"ButtonBrowse": "Обзор",
"ControllerSettingsMotionConfigureCemuHookSettings": "Настройка движения CemuHook",
"ControllerSettingsRumble": "Вибрация",
"ControllerSettingsRumbleEnable": "Включить вибрацию",
"ControllerSettingsRumbleStrongMultiplier": "Множитель сильной вибрации",
"ControllerSettingsRumbleWeakMultiplier": "Множитель слабой вибрации",
"DialogMessageSaveNotAvailableMessage": "Нет сохраненных данных для {0} [{1:x16}]",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Хотите создать данные сохранения для этой игры?",
"DialogConfirmationTitle": "Ryujinx - Подтверждение",
"DialogUpdaterTitle": "Ryujinx - Обновление",
"DialogErrorTitle": "Ryujinx - Ошибка",
"DialogWarningTitle": "Ryujinx - Предупреждение",
"DialogExitTitle": "Ryujinx - Выход",
"DialogErrorMessage": "Ryujinx обнаружил ошибку",
"DialogExitMessage": "Вы уверены, что хотите закрыть Ryujinx?",
"DialogExitSubMessage": "Все несохраненные данные будут потеряны!",
"DialogMessageCreateSaveErrorMessage": "Произошла ошибка при создании указанных данных сохранения: {0}",
"DialogMessageFindSaveErrorMessage": "Произошла ошибка при поиске указанных данных сохранения: {0}",
"FolderDialogExtractTitle": "Выберите папку для извлечения",
"DialogNcaExtractionMessage": "Извлечение {0} раздел от {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Экстрактор разделов NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Ошибка извлечения. Основной NCA не присутствовал в выбранном файле.",
"DialogNcaExtractionCheckLogErrorMessage": "Ошибка извлечения. Прочтите файл журнала для получения дополнительной информации.",
"DialogNcaExtractionSuccessMessage": "Извлечение завершено успешно.",
"DialogUpdaterConvertFailedMessage": "Не удалось преобразовать текущую версию Ryujinx.",
"DialogUpdaterCancelUpdateMessage": "Отмена обновления!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "Вы уже используете самую последнюю версию Ryujinx!",
"DialogUpdaterFailedToGetVersionMessage": "Произошла ошибка при попытке получить информацию о выпуске из Github Release. Это может быть вызвано тем, что GitHub Actions компилирует новый выпуск. Повторите попытку через несколько минут.",
"DialogUpdaterConvertFailedGithubMessage": "Не удалось преобразовать полученную версию Ryujinx из Github Release.",
"DialogUpdaterDownloadingMessage": "Загрузка обновления...",
"DialogUpdaterExtractionMessage": "Извлечение обновления...",
"DialogUpdaterRenamingMessage": "Переименование обновления...",
"DialogUpdaterAddingFilesMessage": "Добавление нового обновления...",
"DialogUpdaterCompleteMessage": "Обновление завершено!",
"DialogUpdaterRestartMessage": "Вы хотите перезапустить Ryujinx сейчас?",
"DialogUpdaterArchNotSupportedMessage": "Вы используете не поддерживаемую системную архитектуру!",
"DialogUpdaterArchNotSupportedSubMessage": "(Поддерживаются только системы x64!)",
"DialogUpdaterNoInternetMessage": "Вы не подключены к Интернету!",
"DialogUpdaterNoInternetSubMessage": "Убедитесь, что у вас есть работающее подключение к Интернету!",
"DialogUpdaterDirtyBuildMessage": "Вы не можете обновить Dirty Build Ryujinx!",
"DialogUpdaterDirtyBuildSubMessage": "Загрузите Ryujinx по адресу https://ryujinx.org/ , если вам нужна поддерживаемая версия.",
"DialogRestartRequiredMessage": "Требуется перезагрузка",
"DialogThemeRestartMessage": "Тема сохранена. Для применения темы требуется перезагрузка.",
"DialogThemeRestartSubMessage": "Вы хотите перезапустить?",
"DialogFirmwareInstallEmbeddedMessage": "Хотите установить прошивку, встроенную в эту игру? (Прошивка {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "Установленная прошивка не найдена, но Ryujinx удалось установить прошивку {0} из предоставленной игры.\nЭмулятор запустится.",
"DialogFirmwareNoFirmwareInstalledMessage": "Прошивка не установлена",
"DialogFirmwareInstalledMessage": "Прошивка {0} была установлена",
"DialogOpenSettingsWindowLabel": "Открыть окно настроек",
"DialogControllerAppletTitle": "Апплет контроллера",
"DialogMessageDialogErrorExceptionMessage": "Ошибка отображения диалогового окна сообщений: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Ошибка отображения программной клавиатуры: {0}",
"DialogErrorAppletErrorExceptionMessage": "Ошибка отображения диалогового окна ErrorApplet: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nДля получения дополнительной информации о том, как исправить эту ошибку, следуйте нашему Руководству по установке.",
"DialogUserErrorDialogTitle": "Ошибка Ryujinx! ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "Произошла ошибка при получении информации из API.",
"DialogAmiiboApiConnectErrorMessage": "Не удалось подключиться к серверу Amiibo API. Служба может быть недоступна, или вам может потребоваться проверить, подключено ли ваше интернет-соединение к сети.",
"DialogProfileInvalidProfileErrorMessage": "Профиль {0} несовместим с текущей системой конфигурации ввода.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "Профиль по умолчанию не может быть перезаписан",
"DialogProfileDeleteProfileTitle": "Удаление профиля",
"DialogProfileDeleteProfileMessage": "Это действие необратимо. Вы уверены, что хотите продолжить?",
"DialogWarning": "Внимание",
"DialogPPTCDeletionMessage": "Вы собираетесь удалить кэш PPTC для:\n\n{0}\n\nВы уверены, что хотите продолжить?",
"DialogPPTCDeletionErrorMessage": "Ошибка очистки кэша PPTC в {0}: {1}",
"DialogShaderDeletionMessage": "Вы собираетесь удалить кэш шейдеров для:\n\n{0}\n\nВы уверены, что хотите продолжить?",
"DialogShaderDeletionErrorMessage": "Ошибка очистки кэша шейдеров в {0}: {1}",
"DialogRyujinxErrorMessage": "Ryujinx обнаружил ошибку",
"DialogInvalidTitleIdErrorMessage": "Ошибка пользовательского интерфейса: выбранная игра не имеет действительного идентификатора названия.",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "Действительная системная прошивка не найдена в {0}.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Установить прошивку {0}",
"DialogFirmwareInstallerFirmwareInstallMessage": "Будет установлена версия системы {0}.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nЭто заменит текущую версию системы {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nПродолжить?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Установка прошивки...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Версия системы {0} успешно установлена.",
"DialogUserProfileDeletionWarningMessage": "Если выбранный профиль будет удален, другие профили не будут открываться.",
"DialogUserProfileDeletionConfirmMessage": "Вы хотите удалить выбранный профиль",
"DialogControllerSettingsModifiedConfirmMessage": "Текущие настройки контроллера обновлены.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Вы хотите сохранить?",
"DialogDlcLoadNcaErrorMessage": "{0}. Файл с ошибкой: {1}",
"DialogDlcNoDlcErrorMessage": "Указанный файл не содержит DLC для выбранной игры!",
"DialogPerformanceCheckLoggingEnabledMessage": "У вас включено ведение журнала отладки, предназначенное только для разработчиков.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "Для оптимальной производительности рекомендуется отключить ведение журнала отладки. Вы хотите отключить ведение журнала отладки сейчас?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "У вас включен сброс шейдеров, который предназначен только для разработчиков.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "Для оптимальной производительности рекомендуется отключить сброс шейдеров. Вы хотите отключить сброс шейдеров сейчас?",
"DialogLoadAppGameAlreadyLoadedMessage": "Игра уже загружена",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Пожалуйста, остановите эмуляцию или закройте эмулятор перед запуском другой игры.",
"DialogUpdateAddUpdateErrorMessage": "Указанный файл не содержит обновления для выбранного заголовка!",
"DialogSettingsBackendThreadingWarningTitle": "Предупреждение: многопоточность в бэкенде",
"DialogSettingsBackendThreadingWarningMessage": "Ryujinx необходимо перезапустить после изменения этой опции, чтобы она полностью применилась. В зависимости от вашей платформы вам может потребоваться вручную отключить собственную многопоточность вашего драйвера при использовании Ryujinx.",
"SettingsTabGraphicsFeaturesOptions": "Функции",
"SettingsTabGraphicsBackendMultithreading": "Многопоточность графического бэкенда:",
"CommonAuto": "Автоматически",
"CommonOff": "Выключен",
"CommonOn": "Включен",
"InputDialogYes": "Да",
"InputDialogNo": "Нет",
"DialogProfileInvalidProfileNameErrorMessage": "Имя файла содержит недопустимые символы. Пожалуйста, попробуйте еще раз.",
"MenuBarOptionsPauseEmulation": "Пауза",
"MenuBarOptionsResumeEmulation": "Продолжить",
"AboutUrlTooltipMessage": "Нажмите, чтобы открыть веб-сайт Ryujinx в браузере по умолчанию.",
"AboutDisclaimerMessage": "Ryujinx никоим образом не связан ни с Nintendo™, ни с кем-либо из ее партнеров.",
"AboutAmiiboDisclaimerMessage": "Amiibo API (www.amiibo api.com) используется\n нашей эмуляции Amiibo.",
"AboutPatreonUrlTooltipMessage": "Нажмите, чтобы открыть страницу Ryujinx Patreon в браузере по умолчанию.",
"AboutGithubUrlTooltipMessage": "Нажмите, чтобы открыть страницу Ryujinx GitHub в браузере по умолчанию.",
"AboutDiscordUrlTooltipMessage": "Нажмите, чтобы открыть приглашение на сервер Ryujinx Discord в браузере по умолчанию.",
"AboutTwitterUrlTooltipMessage": "Нажмите, чтобы открыть страницу Ryujinx в Twitter в браузере по умолчанию.",
"AboutRyujinxAboutTitle": "О программе:",
"AboutRyujinxAboutContent": "Ryujinx — это эмулятор Nintendo Switch™.\nПожалуйста, поддержите нас на Patreon.\nУзнавайте все последние новости в нашем Twitter или Discord.\nРазработчики, заинтересованные в участии, могут узнать больше на нашем GitHub или в Discord.",
"AboutRyujinxMaintainersTitle": "Поддерживается:",
"AboutRyujinxMaintainersContentTooltipMessage": "Нажмите, чтобы открыть страницу Contributors в браузере по умолчанию.",
"AboutRyujinxSupprtersTitle": "Поддерживается на Patreon:",
"AmiiboSeriesLabel": "Серия Amiibo",
"AmiiboCharacterLabel": "Персонаж",
"AmiiboScanButtonLabel": "Сканировать",
"AmiiboOptionsShowAllLabel": "Показать все Amiibo",
"AmiiboOptionsUsRandomTagLabel": "Хак: Использовать случайный тег Uuid",
"DlcManagerTableHeadingEnabledLabel": "Велючено",
"DlcManagerTableHeadingTitleIdLabel": "Идентификатор заголовка",
"DlcManagerTableHeadingContainerPathLabel": "Путь к контейнеру",
"DlcManagerTableHeadingFullPathLabel": "Полный путь",
"DlcManagerRemoveAllButton": "Убрать все",
"MenuBarOptionsChangeLanguage": "Изменить язык",
"CommonSort": "Сортировать",
"CommonShowNames": "Показать названия",
"CommonFavorite": "Избранные",
"OrderAscending": "По возрастанию",
"OrderDescending": "По убыванию",
"SettingsTabGraphicsFeatures": "Функции",
"ErrorWindowTitle": "Окно ошибки",
"ToggleDiscordTooltip": "Включает или отключает Discord Rich Presenc",
"AddGameDirBoxTooltip": "Введите каталог игры, чтобы добавить его в список",
"AddGameDirTooltip": "AДобавить папку с игрой в список",
"RemoveGameDirTooltip": "Удалить выбранный каталог игры",
"CustomThemeCheckTooltip": "Включить или отключить пользовательские темы в графическом интерфейсе",
"CustomThemePathTooltip": "Путь к пользовательской теме графического интерфейса",
"CustomThemeBrowseTooltip": "Обзор пользовательской темы графического интерфейса",
"DockModeToggleTooltip": "Включить или отключить режим закрепления",
"DirectKeyboardTooltip": "Включить или отключить «поддержку прямого доступа к клавиатуре (HID)» (предоставляет играм доступ к клавиатуре как к устройству ввода текста)",
"DirectMouseTooltip": "Включить или отключить «поддержку прямого доступа к мыши (HID)» (предоставляет играм доступ к вашей мыши как указывающему устройству)",
"RegionTooltip": "Изменяет регион системы",
"LanguageTooltip": "Изменяет язык системы",
"TimezoneTooltip": "Изменяет часовой пояс системы",
"TimeTooltip": "Изменяет системное время",
"VSyncToggleTooltip": "Включает или отключает Вертикальную Синхронизацию",
"PptcToggleTooltip": "Включает или отключает PPTC",
"FsIntegrityToggleTooltip": "Включает проверку целостности файлов содержимого игры.",
"AudioBackendTooltip": "Изменяет аудио-бэкэнд",
"MemoryManagerTooltip": "Изменяет способ отображения и доступа к гостевой памяти. Сильно влияет на производительность эмулируемого процессора.",
"MemoryManagerSoftwareTooltip": "Использует таблицу страниц программного обеспечения для преобразования адресов. Самая высокая точность, но самая медленная производительность.",
"MemoryManagerHostTooltip": "Непосредственное отображение памяти в адресном пространстве хоста. Значительно более быстрая JIT-компиляция и выполнение.",
"MemoryManagerUnsafeTooltip": "Напрямую сопоставляет память, но не маскируйте адрес в гостевом адресном пространстве перед доступом. Быстрее, но ценой безопасности. Гостевое приложение может получить доступ к памяти из любой точки Ryujinx, поэтому в этом режиме запускайте только те программы, которым вы доверяете.",
"DRamTooltip": "Увеличивает объем памяти в эмулируемой системе с 4 ГБ до 6 ГБ.",
"IgnoreMissingServicesTooltip": "Включает или отключает параметр игнорирования отсутствующих служб",
"GraphicsBackendThreadingTooltip": "Включает многопоточность графического бэкенда",
"GalThreadingTooltip": "Выполняет команды графического бэкэнда во втором потоке. Обеспечивает многопоточность компиляции шейдеров во время выполнения, уменьшает заикание и повышает производительность драйверов без собственной поддержки многопоточности. Немного различается пиковая производительность на драйверах с многопоточностью. Ryujinx может потребоваться перезапустить, чтобы правильно отключить встроенную многопоточность драйвера, или вам может потребоваться сделать это вручную, чтобы получить максимальную производительность.",
"ShaderCacheToggleTooltip": "Включает или отключает кэш шейдеров",
"ResolutionScaleTooltip": "Масштаб разрешения, применяемый к применимым целям рендеринга",
"ResolutionScaleEntryTooltip": "Шкала разрешения с плавающей запятой, например 1,5. Неинтегральные весы с большей вероятностью вызовут проблемы или сбои.",
"AnisotropyTooltip": "Уровень анизотропной фильтрации (установите значение «Авто», чтобы использовать значение, запрошенное игрой)",
"AspectRatioTooltip": "Соотношение сторон, применяемое к окну рендерера.",
"ShaderDumpPathTooltip": "Путь дампа графических шейдеров",
"FileLogTooltip": "Включает или отключает ведение журнала в файл на диске",
"StubLogTooltip": "Включает печать сообщений журнала-заглушки",
"InfoLogTooltip": "Включает печать сообщений информационного журнала",
"WarnLogTooltip": "Включает печать сообщений журнала предупреждений",
"ErrorLogTooltip": "Включает печать сообщений журнала ошибок",
"GuestLogTooltip": "Включает печать сообщений гостевого журнала",
"FileAccessLogTooltip": "Включает печать сообщений журнала доступа к файлам",
"FSAccessLogModeTooltip": "Включает вывод журнала доступа к FS на консоль. Возможные режимы 0-3",
"DeveloperOptionTooltip": "Используйте с осторожностью",
"OpenGlLogLevel": "Требует включения соответствующих уровней ведения журнала",
"DebugLogTooltip": "Включает печать сообщений журнала отладки",
"LoadApplicationFileTooltip": "Загружает средство выбора файлов, чтобы выбрать файл, совместимый с Switch, для загрузки",
"LoadApplicationFolderTooltip": "Загружает средство выбора файлов, чтобы выбрать распакованное приложение, совместимое с Switch, для загрузки",
"OpenRyujinxFolderTooltip": "Открывает папку файловой системы Ryujinx. ",
"OpenRyujinxLogsTooltip": "Открывает папку, в которую записываются журналы",
"ExitTooltip": "Выходит из Ryujinx",
"OpenSettingsTooltip": "Открывает окно настроек",
"OpenProfileManagerTooltip": "Открывает окно диспетчера профилей пользователей",
"StopEmulationTooltip": "Останавливает эмуляцию текущей игры и вовращение к выбору игры",
"CheckUpdatesTooltip": "Проверяет наличие обновлений Ryujinx",
"OpenAboutTooltip": "Открывает окно «О программе»",
"GridSize": "Размер сетки",
"GridSizeTooltip": "Изменение размера элементов сетки",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Португальский язык (Бразилия)",
"AboutRyujinxContributorsButtonHeader": "Посмотреть всех участников",
"SettingsTabSystemAudioVolume": "Громкость: ",
"AudioVolumeTooltip": "Изменяет громкость звука",
"SettingsTabSystemEnableInternetAccess": "Включить гостевой доступ в Интернет",
"EnableInternetAccessTooltip": "Включает гостевой доступ в Интернет. Если этот параметр включен, приложение будет вести себя так, как если бы эмулированная консоль Switch была подключена к Интернету. Обратите внимание, что в некоторых случаях приложения могут по-прежнему получать доступ к Интернету, даже если эта опция отключена.",
"GameListContextMenuManageCheatToolTip" : "Управление читами",
"GameListContextMenuManageCheat" : "Управление читами",
"ControllerSettingsStickRange" : "Диапазон",
"DialogStopEmulationTitle" : "Ryujinx - Остановить эмуляцию",
"DialogStopEmulationMessage": "Вы уверены, что хотите остановить эмуляцию?",
"SettingsTabCpu": "ЦП",
"SettingsTabAudio": "Аудио",
"SettingsTabNetwork": "Сеть",
"SettingsTabNetworkConnection" : "Подключение к сети",
"SettingsTabGraphicsFrameRate" : "Частота обновления хоста:",
"SettingsTabGraphicsFrameRateTooltip" : "Устанавливает частоту обновления хоста. Установите на 0, чтобы снять ограничение.",
"SettingsTabCpuCache" : "Кэш ЦП",
"SettingsTabCpuMemory" : "Память ЦП"
}

View file

@ -0,0 +1,547 @@
{
"MenuBarFileOpenApplet": "Applet'i aç",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Mii Editör Applet'ini Bağımsız Mod'da Aç",
"SettingsTabInputDirectMouseAccess": "Doğrudan Mouse Erişimi",
"SettingsTabSystemMemoryManagerMode": "Hafıza Yönetim Modu:",
"SettingsTabSystemMemoryManagerModeSoftware": "Software",
"SettingsTabSystemMemoryManagerModeHost": "Host (hızlı)",
"SettingsTabSystemMemoryManagerModeHostUnchecked": "Host Unchecked (en hızlısı, tehlikeli)",
"MenuBarFile": "_Dosya",
"MenuBarFileOpenFromFile": "_Dosyadan Uygulama Aç",
"MenuBarFileOpenUnpacked": "_Sıkıştırılmamış Oyun Aç",
"MenuBarFileOpenEmuFolder": "Ryujinx Klasörünü aç",
"MenuBarFileOpenLogsFolder": "Logs Klasörünü aç",
"MenuBarFileExit": "_Çıkış",
"MenuBarOptions": "Seçenekler",
"MenuBarOptionsToggleFullscreen": "Tam ekran modu",
"MenuBarOptionsStartGamesInFullscreen": "Oyunları Tam Ekran Modunda başlat",
"MenuBarOptionsStopEmulation": "Emülasyonu durdur",
"MenuBarOptionsSettings": "_Seçenekler",
"MenuBarOptionsManageUserProfiles": "_Kullanıcı profillerini yönet",
"MenuBarActions": "_Eylemler",
"MenuBarOptionsSimulateWakeUpMessage": "Uyandırma mesajı simüle et",
"MenuBarActionsScanAmiibo": "Amiibo tarama",
"MenuBarTools": "_Aletler",
"MenuBarToolsInstallFirmware": "Firmware yükle",
"MenuBarFileToolsInstallFirmwareFromFile": "Firmware yükle (XCI veya ZIP)",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Firmware yükle (Dizin üzerinden)",
"MenuBarHelp": "Yardım",
"MenuBarHelpCheckForUpdates": "Güncellemeleri denetle",
"MenuBarHelpAbout": "Hakkında",
"MenuSearch": "Arama...",
"GameListHeaderFavorite": "Favori",
"GameListHeaderIcon": "Simge",
"GameListHeaderApplication": "Oyun Adı",
"GameListHeaderDeveloper": "Geliştirici",
"GameListHeaderVersion": "Sürüm",
"GameListHeaderTimePlayed": "Oynama süresi",
"GameListHeaderLastPlayed": "Son oynama tarihi",
"GameListHeaderFileExtension": "Dosya Uzantısı",
"GameListHeaderFileSize": "Dosya boyutu",
"GameListHeaderPath": "Yol",
"GameListContextMenuOpenUserSaveDirectory": "Kullanıcı Kayıt Dosyası Dizinini Aç",
"GameListContextMenuOpenUserSaveDirectoryToolTip": "Uygulamanın Kullanıcı Kaydının bulunduğu dizini açar",
"GameListContextMenuOpenUserDeviceDirectory": "Kullanıcı Cihaz Dizinini Aç",
"GameListContextMenuOpenUserDeviceDirectoryToolTip": "Uygulamanın Kullanıcı Cihaz bulunduğu dizini açar",
"GameListContextMenuOpenUserBcatDirectory": "Kullanıcı BCAT Dizinini Aç",
"GameListContextMenuOpenUserBcatDirectoryToolTip": "Uygulamanın Kullanıcı BCAT Kaydının bulunduğu dizini açar",
"GameListContextMenuManageTitleUpdates": "Oyun Güncellemelerini Yönet",
"GameListContextMenuManageTitleUpdatesToolTip": "Oyun Güncelleme yönetim penceresini açar",
"GameListContextMenuManageDlc": "DLC Yönet",
"GameListContextMenuManageDlcToolTip": "DLC yönetim penceresini açar",
"GameListContextMenuOpenModsDirectory": "Mod Dizinini Aç",
"GameListContextMenuOpenModsDirectoryToolTip": "Uygulamanın Modlarının bulunduğu dizini açar",
"GameListContextMenuCacheManagement": "Cache Yönetimi",
"GameListContextMenuCacheManagementPurgePptc": "PPTC Cache'ini temizle",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Uygulamanın PPTC cache'ini siler",
"GameListContextMenuCacheManagementPurgeShaderCache": "Shader Cache'i temizle",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Uygulamanın shader cache'ini siler",
"GameListContextMenuCacheManagementOpenPptcDirectory": "PPTC Dizinini Aç",
"GameListContextMenuCacheManagementOpenPptcDirectoryToolTip": "Uygulamanın PPTC Cache'inin bulunduğu dizini açar",
"GameListContextMenuCacheManagementOpenShaderCacheDirectory": "Shader Cache Dizinini Aç",
"GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip": "Uygulamanın shader cache'inin bulunduğu dizini açar",
"GameListContextMenuExtractData": "Veri Ayıkla",
"GameListContextMenuExtractDataExeFS": "ExeFS",
"GameListContextMenuExtractDataExeFSToolTip": "Uygulamanın geçerli yapılandırmasından ExeFS kısmını ayıkla (Güncellemeler dahil)",
"GameListContextMenuExtractDataRomFS": "RomFS",
"GameListContextMenuExtractDataRomFSToolTip": "Uygulamanın geçerli yapılandırmasından RomFS kısmını ayıkla (Güncellemeler dahil)",
"GameListContextMenuExtractDataLogo": "Logo",
"GameListContextMenuExtractDataLogoToolTip": "Uygulamanın geçerli yapılandırmasından Logo kısmını ayıkla (Güncellemeler dahil)",
"StatusBarGamesLoaded": "{0}/{1} Oyun Yüklendi",
"StatusBarSystemVersion": "Sistem Sürümü: {0}",
"Settings": "Yapılandırma",
"SettingsTabGeneral": "Kullancı Arayüzü",
"SettingsTabGeneralGeneral": "Genel",
"SettingsTabGeneralEnableDiscordRichPresence": "Discord Rich Presence'i Aç",
"SettingsTabGeneralCheckUpdatesOnLaunch": "Her Açılışta Güncellemeleri Denetle",
"SettingsTabGeneralShowConfirmExitDialog": "\"Çıkışı Onayla\" Diyaloğunu Göster",
"SettingsTabGeneralHideCursorOnIdle": "Hareketsizlik durumunda imleci gizle",
"SettingsTabGeneralGameDirectories": "Oyun Dizinleri",
"SettingsTabGeneralAdd": "Ekle",
"SettingsTabGeneralRemove": "Kaldır",
"SettingsTabSystem": "Sistem",
"SettingsTabSystemCore": "Çekirdek",
"SettingsTabSystemSystemRegion": "Sistem Bölgesi:",
"SettingsTabSystemSystemRegionJapan": "Japonya",
"SettingsTabSystemSystemRegionUSA": "ABD",
"SettingsTabSystemSystemRegionEurope": "Avrupa",
"SettingsTabSystemSystemRegionAustralia": "Avustralya",
"SettingsTabSystemSystemRegionChina": "Çin",
"SettingsTabSystemSystemRegionKorea": "Kore",
"SettingsTabSystemSystemRegionTaiwan": "Tayvan",
"SettingsTabSystemSystemLanguage": "Sistem Dili:",
"SettingsTabSystemSystemLanguageJapanese": "Japonca",
"SettingsTabSystemSystemLanguageAmericanEnglish": "Amerikan İngilizcesi",
"SettingsTabSystemSystemLanguageFrench": "Fransızca",
"SettingsTabSystemSystemLanguageGerman": "Almanca",
"SettingsTabSystemSystemLanguageItalian": "İtalyanca",
"SettingsTabSystemSystemLanguageSpanish": "İspanyolca",
"SettingsTabSystemSystemLanguageChinese": "Çince",
"SettingsTabSystemSystemLanguageKorean": "Korece",
"SettingsTabSystemSystemLanguageDutch": "Flemenkçe",
"SettingsTabSystemSystemLanguagePortuguese": "Portekizce",
"SettingsTabSystemSystemLanguageRussian": "Rusça",
"SettingsTabSystemSystemLanguageTaiwanese": "Tayvanca",
"SettingsTabSystemSystemLanguageBritishEnglish": "İngiliz İngilizcesi",
"SettingsTabSystemSystemLanguageCanadianFrench": "Kanada Fransızcası",
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Latin Amerika İspanyolcası",
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Basitleştirilmiş Çince",
"SettingsTabSystemSystemLanguageTraditionalChinese": "Geleneksel Çince",
"SettingsTabSystemSystemTimeZone": "Sistem Saat Dilimi:",
"SettingsTabSystemSystemTime": "System Time:",
"SettingsTabSystemEnableVsync": "VSync'i Etkinleştir",
"SettingsTabSystemEnablePptc": "PPTC'yi Etkinleştir (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "FS Bütünlük Kontrollerini Etkinleştir",
"SettingsTabSystemAudioBackend": "Ses Motoru:",
"SettingsTabSystemAudioBackendDummy": "Dummy",
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
"SettingsTabSystemAudioBackendSDL2": "SDL2",
"SettingsTabSystemHacks": "Hacklar",
"SettingsTabSystemHacksNote": " - Bunlar birçok dengesizlik oluşturabilir",
"SettingsTabSystemExpandDramSize": "DRAM boyutunu 6GB'a genişlet",
"SettingsTabSystemIgnoreMissingServices": "Eksik Servisleri Görmezden Gel",
"SettingsTabGraphics": "Grafikler",
"SettingsTabGraphicsEnhancements": "İyileştirmeler",
"SettingsTabGraphicsEnableShaderCache": "Shader Cache'i Etkinleştir",
"SettingsTabGraphicsAnisotropicFiltering": "Anisotropic Filtering:",
"SettingsTabGraphicsAnisotropicFilteringAuto": "Otomatik",
"SettingsTabGraphicsAnisotropicFiltering2x": "2x",
"SettingsTabGraphicsAnisotropicFiltering4x": "4x",
"SettingsTabGraphicsAnisotropicFiltering8x": "8x",
"SettingsTabGraphicsAnisotropicFiltering16x": "16x",
"SettingsTabGraphicsResolutionScale": "Resolution Scale:",
"SettingsTabGraphicsResolutionScaleCustom": "Özel (Tavsiye Edilmez)",
"SettingsTabGraphicsResolutionScaleNative": "Yerel (720p/1080p)",
"SettingsTabGraphicsResolutionScale2x": "2x (1440p/2160p)",
"SettingsTabGraphicsResolutionScale3x": "3x (2160p/3240p)",
"SettingsTabGraphicsResolutionScale4x": "4x (2880p/4320p)",
"SettingsTabGraphicsAspectRatio": "En-Boy Oranı:",
"SettingsTabGraphicsAspectRatio4x3": "4:3",
"SettingsTabGraphicsAspectRatio16x9": "16:9",
"SettingsTabGraphicsAspectRatio16x10": "16:10",
"SettingsTabGraphicsAspectRatio21x9": "21:9",
"SettingsTabGraphicsAspectRatio32x9": "32:9",
"SettingsTabGraphicsAspectRatioStretch": "Pencereye Sığdırmak için Genişlet",
"SettingsTabGraphicsDeveloperOptions": "Geliştirici Seçenekleri",
"SettingsTabGraphicsShaderDumpPath": "Grafik Shader Döküm Yolu:",
"SettingsTabLogging": "Loglama",
"SettingsTabLoggingLogging": "Loglama",
"SettingsTabLoggingEnableLoggingToFile": "Logları Dosyaya Kaydetmeyi Etkinleştir",
"SettingsTabLoggingEnableStubLogs": "Stub Loglarını Etkinleştir",
"SettingsTabLoggingEnableInfoLogs": "Bilgi Loglarını Etkinleştir",
"SettingsTabLoggingEnableWarningLogs": "Uyarı Loglarını Etkinleştir",
"SettingsTabLoggingEnableErrorLogs": "Hata Loglarını Etkinleştir",
"SettingsTabLoggingEnableTraceLogs": "Trace Loglarını Etkinleştir",
"SettingsTabLoggingEnableGuestLogs": "Guest Loglarını Etkinleştir",
"SettingsTabLoggingEnableFsAccessLogs": "Fs Erişim Loglarını Etkinleştir",
"SettingsTabLoggingFsGlobalAccessLogMode": "Fs Evrensel Erişim Log Modu:",
"SettingsTabLoggingDeveloperOptions": "Geliştirici Seçenekleri (UYARI: Performansı düşürecektir)",
"SettingsTabLoggingOpenglLogLevel": "OpenGL Log Seviyesi:",
"SettingsTabLoggingOpenglLogLevelNone": "Hiç",
"SettingsTabLoggingOpenglLogLevelError": "Hata",
"SettingsTabLoggingOpenglLogLevelPerformance": "Yavaşlamalar",
"SettingsTabLoggingOpenglLogLevelAll": "Her Şey",
"SettingsTabLoggingEnableDebugLogs": "Hata Ayıklama Loglarını Etkinleştir",
"SettingsTabInput": "Giriş Yöntemi",
"SettingsTabInputEnableDockedMode": "Docked Mode'u Etkinleştir",
"SettingsTabInputDirectKeyboardAccess": "Doğrudan Klavye Erişimi",
"SettingsButtonSave": "Kaydet",
"SettingsButtonClose": "Kapat",
"SettingsButtonApply": "Uygula",
"ControllerSettingsPlayer": "Oyuncu",
"ControllerSettingsPlayer1": "Oyuncu 1",
"ControllerSettingsPlayer2": "Oyuncu 2",
"ControllerSettingsPlayer3": "Oyuncu 3",
"ControllerSettingsPlayer4": "Oyuncu 4",
"ControllerSettingsPlayer5": "Oyuncu 5",
"ControllerSettingsPlayer6": "Oyuncu 6",
"ControllerSettingsPlayer7": "Oyuncu 7",
"ControllerSettingsPlayer8": "Oyuncu 8",
"ControllerSettingsHandheld": "Handheld",
"ControllerSettingsInputDevice": "Giriş Cihazı",
"ControllerSettingsRefresh": "Yenile",
"ControllerSettingsDeviceDisabled": "Devre Dışı",
"ControllerSettingsControllerType": "Kontrolcü Tarzı",
"ControllerSettingsControllerTypeHandheld": "Portatif Mod",
"ControllerSettingsControllerTypeProController": "Pro Controller",
"ControllerSettingsControllerTypeJoyConPair": "JoyCon İkilisi",
"ControllerSettingsControllerTypeJoyConLeft": "JoyCon Sol",
"ControllerSettingsControllerTypeJoyConRight": "JoyCon Sağ",
"ControllerSettingsProfile": "Profil",
"ControllerSettingsProfileDefault": "Varsayılan",
"ControllerSettingsLoad": "Yükle",
"ControllerSettingsAdd": "Ekle",
"ControllerSettingsRemove": "Kaldır",
"ControllerSettingsButtons": "Düğmeler",
"ControllerSettingsButtonA": "A",
"ControllerSettingsButtonB": "B",
"ControllerSettingsButtonX": "X",
"ControllerSettingsButtonY": "Y",
"ControllerSettingsButtonPlus": "+",
"ControllerSettingsButtonMinus": "-",
"ControllerSettingsDPad": "Yön Tuşları",
"ControllerSettingsDPadUp": "Yukarı",
"ControllerSettingsDPadDown": "Aşağı",
"ControllerSettingsDPadLeft": "Sol",
"ControllerSettingsDPadRight": "Sağ",
"ControllerSettingsLStick": "Sol Analog",
"ControllerSettingsLStickButton": "Tıklama",
"ControllerSettingsLStickUp": "Yukarı",
"ControllerSettingsLStickDown": "Aşağı",
"ControllerSettingsLStickLeft": "Sol",
"ControllerSettingsLStickRight": "Sağ",
"ControllerSettingsLStickStick": "Tıklama",
"ControllerSettingsLStickInvertXAxis": "X Eksenini Tersine Çevir",
"ControllerSettingsLStickInvertYAxis": "Y Eksenini Tersine Çevir",
"ControllerSettingsLStickDeadzone": "Ölü Bölge:",
"ControllerSettingsRStick": "Sağ Analog",
"ControllerSettingsRStickButton": "Tıklama",
"ControllerSettingsRStickUp": "Yukarı",
"ControllerSettingsRStickDown": "Aşağı",
"ControllerSettingsRStickLeft": "Sol",
"ControllerSettingsRStickRight": "Sağ",
"ControllerSettingsRStickStick": "Tıklama",
"ControllerSettingsRStickInvertXAxis": "X Eksenini Tersine Çevir",
"ControllerSettingsRStickInvertYAxis": "Y Eksenini Tersine Çevir",
"ControllerSettingsRStickDeadzone": "Ölü Bölge:",
"ControllerSettingsTriggersLeft": "Sol Tetikler",
"ControllerSettingsTriggersRight": "Sağ Tetikler",
"ControllerSettingsTriggersButtonsLeft": "Sol Tetik Tuşları",
"ControllerSettingsTriggersButtonsRight": "Sağ Tetik Tuşları",
"ControllerSettingsTriggers": "Tetikler",
"ControllerSettingsTriggerL": "L",
"ControllerSettingsTriggerR": "R",
"ControllerSettingsTriggerZL": "ZL",
"ControllerSettingsTriggerZR": "ZR",
"ControllerSettingsLeftSL": "SL",
"ControllerSettingsLeftSR": "SR",
"ControllerSettingsRightSL": "SL",
"ControllerSettingsRightSR": "SR",
"ControllerSettingsExtraButtonsLeft": "Sol Tuşlar",
"ControllerSettingsExtraButtonsRight": "Sağ Tuşlar",
"ControllerSettingsMisc": "Misc.",
"ControllerSettingsTriggerThreshold": "Tetik Eşiği:",
"ControllerSettingsMotion": "Hareket",
"ControllerSettingsCemuHook": "CemuHook",
"ControllerSettingsMotionEnableMotionControls": "Hareket Kontrollerini Etkinleştir",
"ControllerSettingsMotionUseCemuhookCompatibleMotion": "CemuHook Uyumlu Hareket",
"ControllerSettingsMotionControllerSlot": "Kontrolcü Yuvası:",
"ControllerSettingsMotionMirrorInput": "Girişi Aynala",
"ControllerSettingsMotionRightJoyConSlot": "Sağ JoyCon Yuvası:",
"ControllerSettingsMotionServerHost": "Server Host:",
"ControllerSettingsMotionGyroSensitivity": "Gyro Hassasiyeti:",
"ControllerSettingsMotionGyroDeadzone": "Gyro Ölü Bölgesi:",
"ControllerSettingsSave": "Kaydet",
"ControllerSettingsClose": "Kapat",
"UserProfilesSelectedUserProfile": "Aktif Kullanıcı Profili:",
"UserProfilesSaveProfileName": "Profil İsmini Kaydet",
"UserProfilesChangeProfileImage": "Profil Resmini Değiştir",
"UserProfilesAvailableUserProfiles": "Mevcut Kullanıcı Profilleri:",
"UserProfilesAddNewProfile": "Yeni Profil Ekle",
"UserProfilesDeleteSelectedProfile": "Seçili Profili Sil",
"UserProfilesClose": "Kapat",
"ProfileImageSelectionTitle": "Profile Resmi Seçimi",
"ProfileImageSelectionHeader": "Profil Resmi Seç",
"ProfileImageSelectionNote": "Özel bir profil resmi içeri aktarabilir veya sistem avatarlarından birini seçebilirsiniz",
"ProfileImageSelectionImportImage": "Resim İçeri Aktar",
"ProfileImageSelectionSelectAvatar": "Sistem Avatarı Seç",
"InputDialogTitle": "Giriş Yöntemi Diyaloğu",
"InputDialogOk": "OK",
"InputDialogCancel": "İptal",
"InputDialogAddNewProfileTitle": "Profil İsmini Seç",
"InputDialogAddNewProfileHeader": "Profil İsmi girin",
"InputDialogAddNewProfileSubtext": "(Maksimum Uzunluk: {0})",
"AvatarChoose": "Seç",
"AvatarSetBackgroundColor": "Arkaplan Rengi Ayarla",
"AvatarClose": "Kapat",
"ControllerSettingsLoadProfileToolTip": "Profil Yükle",
"ControllerSettingsAddProfileToolTip": "Profil Ekle",
"ControllerSettingsRemoveProfileToolTip": "Profil Kaldır",
"ControllerSettingsSaveProfileToolTip": "Profil Kaydet",
"MenuBarFileToolsTakeScreenshot": "Ekran Görüntüsü Al",
"MenuBarFileToolsHideUi": "Kullanıcı Arayüzünü gizle",
"GameListContextMenuToggleFavorite": "Favori Ayarla",
"GameListContextMenuToggleFavoriteToolTip": "Oyunun Favori Durumunu Aç/Kapat",
"SettingsTabGeneralTheme": "Tema",
"SettingsTabGeneralThemeCustomTheme": "Özel Tema Yolu",
"SettingsTabGeneralThemeBaseStyle": "Temel Stil",
"SettingsTabGeneralThemeBaseStyleDark": "Karanlık",
"SettingsTabGeneralThemeBaseStyleLight": "Aydınlık",
"SettingsTabGeneralThemeEnableCustomTheme": "Özel Tema Etkinleştir",
"ButtonBrowse": "Göz At",
"ControllerSettingsMotionConfigureCemuHookSettings": "CemuHook Hareket Ayarla",
"ControllerSettingsRumble": "Titreşim",
"ControllerSettingsRumbleEnable": "Titreşimi Etkinleştir",
"ControllerSettingsRumbleStrongMultiplier": "Güçlü Titreşim Çarpanı",
"ControllerSettingsRumbleWeakMultiplier": "Zayıf Titreşim Çarpanı",
"DialogMessageSaveNotAvailableMessage": "{0} [{1:x16}] için kayıt verisi yok",
"DialogMessageSaveNotAvailableCreateSaveMessage": "Bu oyun için kayıt verisi oluşturmak ister misiniz?",
"DialogConfirmationTitle": "Ryujinx - Onay",
"DialogUpdaterTitle": "Ryujinx - Güncelleyici",
"DialogErrorTitle": "Ryujinx - Hata",
"DialogWarningTitle": "Ryujinx - Uyarı",
"DialogExitTitle": "Ryujinx - Çıkış",
"DialogErrorMessage": "Ryujinx bir hata ile karşılaştı",
"DialogExitMessage": "Ryujinx'i kapatmak istediğinizden emin misiniz?",
"DialogExitSubMessage": "Kaydedilmeyen bütün veriler kaybedilecek!",
"DialogMessageCreateSaveErrorMessage": "Belirtilen kayıt verisi oluşturulurken hata: {0}",
"DialogMessageFindSaveErrorMessage": "Belirtilen kayıt verisi bulunmaya çalışırken hata: {0}",
"FolderDialogExtractTitle": "İçine ayıklanacak klasörü seç",
"DialogNcaExtractionMessage": "{1} den {0} kısmı ayıklanıyor...",
"DialogNcaExtractionTitle": "Ryujinx - NCA Kısmı Ayıklayıcısı",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Ayıklama hatası. Ana NCA seçilen dosyada bulunamadı.",
"DialogNcaExtractionCheckLogErrorMessage": "Ayıklama hatası. Ek bilgi için log dosyasını okuyun.",
"DialogNcaExtractionSuccessMessage": "Ayıklama başarıyla tamamlandı.",
"DialogUpdaterConvertFailedMessage": "Güncel Ryujinx sürümü çevrilemedi.",
"DialogUpdaterCancelUpdateMessage": "Güncelleme iptal ediliyor!",
"DialogUpdaterAlreadyOnLatestVersionMessage": "Zaten Ryujinx'in en güncel sürümünü kullanıyorsunuz!",
"DialogUpdaterFailedToGetVersionMessage": "Github Release'den yayınlama bilgisi alınırken hata oluştu. Bu durum yeni bir sürümün Github Actions tarafından derleniyor olmasından kaynaklanıyor olabilir. Birkaç dakika sonra tekrar deneyin.",
"DialogUpdaterConvertFailedGithubMessage": "Github Release'den alınan Ryujinx sürümü çevrilemedi.",
"DialogUpdaterDownloadingMessage": "Güncelleme indiriliyor...",
"DialogUpdaterExtractionMessage": "Güncelleme ayıklanıyor...",
"DialogUpdaterRenamingMessage": "Güncelleme yeniden adlandırılıyor...",
"DialogUpdaterAddingFilesMessage": "Yeni güncelleme ekleniyor...",
"DialogUpdaterCompleteMessage": "Güncelleme tamamlandı!",
"DialogUpdaterRestartMessage": "Ryujinx'i şimdi yeniden başlatmak istiyor musunuz?",
"DialogUpdaterArchNotSupportedMessage": "Sistem mimariniz desteklenmemektedir!",
"DialogUpdaterArchNotSupportedSubMessage": "(Sadece x64 sistemleri desteklenmektedir!)",
"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 arıyorsanız lütfen Ryujinx'i https://ryujinx.org/ sitesinden indirin.",
"DialogRestartRequiredMessage": "Yeniden Başlatma Gerekli",
"DialogThemeRestartMessage": "Tema kaydedildi. Temayı uygulamak için yeniden başlatma gerekiyor.",
"DialogThemeRestartSubMessage": "Yeniden başlatmak ister misiniz",
"DialogFirmwareInstallEmbeddedMessage": "Bu oyunun içine gömülü olan firmware'i yüklemek ister misiniz? (Firmware {0})",
"DialogFirmwareInstallEmbeddedSuccessMessage": "Yüklü firmware bulunamadı ancak Ryujinx sağlanan oyundan firmware {0} 'ı yükledi.\nRyujinx şimdi başlatılacak.",
"DialogFirmwareNoFirmwareInstalledMessage": "Firmware Yüklü Değil",
"DialogFirmwareInstalledMessage": "Firmware {0} yüklendi",
"DialogOpenSettingsWindowLabel": "Seçenekler Penceresini Aç",
"DialogControllerAppletTitle": "Controller Applet",
"DialogMessageDialogErrorExceptionMessage": "Mesaj Diyaloğu gösterilirken hata: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Mesaj Diyaloğu gösterilirken hata: {0}",
"DialogErrorAppletErrorExceptionMessage": "Applet Diyaloğu gösterilirken hata: {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\nBu hatayı düzeltmek adına daha fazla bilgi için kurulum kılavuzumuzu takip edin.",
"DialogUserErrorDialogTitle": "Ryujinx Hatası ({0})",
"DialogAmiiboApiTitle": "Amiibo API",
"DialogAmiiboApiFailFetchMessage": "API'dan bilgi alırken bir hata oluştu.",
"DialogAmiiboApiConnectErrorMessage": "Amiibo API sunucusuna bağlanılamadı. Sunucu çevrimdışı olabilir veya uygun bir internet bağlantınızın olduğunu kontrol etmeniz gerekebilir.",
"DialogProfileInvalidProfileErrorMessage": "Profil {0} güncel giriş konfigürasyon sistemi ile uyumlu değil.",
"DialogProfileDefaultProfileOverwriteErrorMessage": "Varsayılan Profil'in üstüne yazılamaz",
"DialogProfileDeleteProfileTitle": "Profil Siliniyor",
"DialogProfileDeleteProfileMessage": "Bu eylem geri döndürülemez, devam etmek istediğinizden emin misiniz?",
"DialogWarning": "Uyarı",
"DialogPPTCDeletionMessage": "Belirtilen PPTC cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?",
"DialogPPTCDeletionErrorMessage": "Belirtilen PPTC cache temizlenirken hata {0}: {1}",
"DialogShaderDeletionMessage": "Belirtilen Shader cache silinecek :\n\n{0}\n\nDevam etmek istediğinizden emin misiniz?",
"DialogShaderDeletionErrorMessage": "Belirtilen Shader cache temizlenirken hata {0}: {1}",
"DialogRyujinxErrorMessage": "Ryujinx bir hata ile karşılaştı",
"DialogInvalidTitleIdErrorMessage": "UI hatası: Seçilen oyun geçerli bir title ID'ye sahip değil",
"DialogFirmwareInstallerFirmwareNotFoundErrorMessage": "{0} da geçerli bir sistem firmware'i bulunamadı.",
"DialogFirmwareInstallerFirmwareInstallTitle": "Firmware {0} Yükle",
"DialogFirmwareInstallerFirmwareInstallMessage": "Sistem sürümü {0} yüklenecek.",
"DialogFirmwareInstallerFirmwareInstallSubMessage": "\n\nBu şimdiki sistem sürümünün yerini alacak {0}.",
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\nDevam etmek istiyor musunuz?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Firmware yükleniyor...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Sistem sürümü {0} başarıyla yüklendi.",
"DialogUserProfileDeletionWarningMessage": "Seçilen profil silinirse kullanılabilen başka profil kalmayacak",
"DialogUserProfileDeletionConfirmMessage": "Seçilen profili silmek istiyor musunuz",
"DialogControllerSettingsModifiedConfirmMessage": "Güncel kontrolcü seçenekleri güncellendi.",
"DialogControllerSettingsModifiedConfirmSubMessage": "Kaydetmek istiyor musunuz?",
"DialogDlcLoadNcaErrorMessage": "{0}. Hatalı Dosya: {1}",
"DialogDlcNoDlcErrorMessage": "Belirtilen dosya seçilen oyun için DLC içermiyor!",
"DialogPerformanceCheckLoggingEnabledMessage": "Sadece geliştiriler için dizayn edilen Trace Loglama seçeneği etkin.",
"DialogPerformanceCheckLoggingEnabledConfirmMessage": "En iyi performans için trace loglama'nın devre dışı bırakılması tavsiye edilir. Trace loglama seçeneğini şimdi devre dışı bırakmak ister misiniz?",
"DialogPerformanceCheckShaderDumpEnabledMessage": "Sadece geliştiriler için dizayn edilen Shader Dumping seçeneği etkin.",
"DialogPerformanceCheckShaderDumpEnabledConfirmMessage": "En iyi performans için Shader Dumping'in devre dışı bırakılması tavsiye edilir. Shader Dumping seçeneğini şimdi devre dışı bırakmak ister misiniz?",
"DialogLoadAppGameAlreadyLoadedMessage": "Bir oyun zaten yüklendi",
"DialogLoadAppGameAlreadyLoadedSubMessage": "Lütfen yeni bir oyun açmadan önce emülasyonu durdurun veya emülatörü kapatın.",
"DialogUpdateAddUpdateErrorMessage": "Belirtilen dosya seçilen oyun için güncelleme içermiyor!",
"DialogSettingsBackendThreadingWarningTitle": "Uyarı - Backend Threading",
"DialogSettingsBackendThreadingWarningMessage": "Bu seçeneğin tamamen uygulanması için Ryujinx'in kapatıp açılması gerekir. Kullandığınız işletim sistemine bağlı olarak, Ryujinx'in multithreading'ini kullanırken driver'ınızın multithreading seçeneğini kapatmanız gerekebilir.",
"SettingsTabGraphicsFeaturesOptions": "Özellikler",
"SettingsTabGraphicsBackendMultithreading": "Grafik Backend Multithreading:",
"CommonAuto": "Otomatik",
"CommonOff": "Kapalı",
"CommonOn": "Açık",
"InputDialogYes": "Evet",
"InputDialogNo": "Hayır",
"DialogProfileInvalidProfileNameErrorMessage": "Dosya adı geçerli olmayan karakterler içeriyor. Lütfen tekrar deneyin.",
"MenuBarOptionsPauseEmulation": "Durdur",
"MenuBarOptionsResumeEmulation": "Devam Et",
"AboutUrlTooltipMessage": "Ryujinx'in websitesini varsayılan tarayıcınızda açmak için tıklayın.",
"AboutDisclaimerMessage": "Ryujinx, Nintendo™ veya ortaklarıyla herhangi bir şekilde bağlantılı değildir.",
"AboutAmiiboDisclaimerMessage": "Amiibo emülasyonumuzda \nAmiiboAPI (www.amiiboapi.com) kullanılmaktadır.",
"AboutPatreonUrlTooltipMessage": "Ryujinx'in Patreon sayfasını varsayılan tarayıcınızda açmak için tıklayın.",
"AboutGithubUrlTooltipMessage": "Ryujinx'in GitHub sayfasını varsayılan tarayıcınızda açmak için tıklayın.",
"AboutDiscordUrlTooltipMessage": "Varsayılan tarayıcınızda Ryujinx'in Discord'una bir davet açmak için tıklayın.",
"AboutTwitterUrlTooltipMessage": "Ryujinx'in Twitter sayfasını varsayılan tarayıcınızda açmak için tıklayın.",
"AboutRyujinxAboutTitle": "Hakkında:",
"AboutRyujinxAboutContent": "Ryujinx bir Nintendo Switch™ emülatörüdür.\nLütfen bizi Patreon'da destekleyin.\nEn son haberleri Twitter veya Discord'umuzdan alın.\nKatkıda bulunmak isteyen geliştiriciler GitHub veya Discord üzerinden daha fazla bilgi edinebilir.",
"AboutRyujinxMaintainersTitle": "Geliştiriciler:",
"AboutRyujinxMaintainersContentTooltipMessage": "Varsayılan tarayıcınızda katkıda bulunanlar sayfasını açmak için tıklayın.",
"AboutRyujinxSupprtersTitle": "Patreon Destekleyicileri:",
"AmiiboSeriesLabel": "Amiibo Serisi",
"AmiiboCharacterLabel": "Karakter",
"AmiiboScanButtonLabel": "Tarat",
"AmiiboOptionsShowAllLabel": "Tüm Amiibo'ları Göster",
"AmiiboOptionsUsRandomTagLabel": "Hack: Use Random tag Uuid",
"DlcManagerTableHeadingEnabledLabel": "Etkin",
"DlcManagerTableHeadingTitleIdLabel": "Title ID",
"DlcManagerTableHeadingContainerPathLabel": "Container Yol",
"DlcManagerTableHeadingFullPathLabel": "Tam Yol",
"DlcManagerRemoveAllButton": "Tümünü kaldır",
"MenuBarOptionsChangeLanguage": "Dili Değiştir",
"CommonSort": "Sırala",
"CommonShowNames": "İsimleri Göster",
"CommonFavorite": "Favori",
"OrderAscending": "Artan",
"OrderDescending": "Azalan",
"SettingsTabGraphicsFeatures": "Özellikler",
"ErrorWindowTitle": "Hata Penceresi",
"ToggleDiscordTooltip": "Discord Rich Presence'i Aç/Kapat",
"AddGameDirBoxTooltip": "Listeye eklemek için bir oyun dizini ekleyin",
"AddGameDirTooltip": "Listeye oyun dizini ekle",
"RemoveGameDirTooltip": "Seçilen oyun dizinini kaldır",
"CustomThemeCheckTooltip": "Grafik kullanıcı arayüzünde özel temaları etkinleştir veya devre dışı bırak",
"CustomThemePathTooltip": "Özel grafik kullancı arayüzü teması yolu",
"CustomThemeBrowseTooltip": "Özel grafik kullanıcı arayüzü teması için göz at",
"DockModeToggleTooltip": "Docked Modu etkinleştir veya devre dışı bırak",
"DirectKeyboardTooltip": "Enable or disable \"direct keyboard access (HID) support\" (Provides games access to your keyboard as a text entry device)",
"DirectMouseTooltip": "Enable or disable \"direct mouse access (HID) support\" (Provides games access to your mouse as a pointing device)",
"RegionTooltip": "Sistem Bölgesini Değiştir",
"LanguageTooltip": "Sistem Dilini Değiştir",
"TimezoneTooltip": "Sistem Saat Dilimini Değiştir",
"TimeTooltip": "Sistem Saatini Değiştir",
"VSyncToggleTooltip": "Dikey senkronizasyonu etkinleştirir veya devre dışı bırakır",
"PptcToggleTooltip": "PPTC'yi etkinleştirir veya devre dışı bırakır",
"FsIntegrityToggleTooltip": "Oyun içerik dosyaları için bütünlük kontrollerini etkinleştirir",
"AudioBackendTooltip": "Ses motorunu değiştirir",
"MemoryManagerTooltip": "Change how guest memory is mapped and accessed. Greatly affects emulated CPU performance.",
"MemoryManagerSoftwareTooltip": "Use a software page table for address translation. Highest accuracy but slowest performance.",
"MemoryManagerHostTooltip": "Directly map memory in the host address space. Much faster JIT compilation and execution.",
"MemoryManagerUnsafeTooltip": "Directly map memory, but do not mask the address within the guest address space before access. Faster, but at the cost of safety. The guest application can access memory from anywhere in Ryujinx, so only run programs you trust with this mode.",
"DRamTooltip": "Emüle edilen sistemin hafızasını 4GB'dan 6GB'a yükseltir",
"IgnoreMissingServicesTooltip": "Eksik servisleri görmezden gelme seçeneğini etkinleştir veya devre dışı bırak",
"GraphicsBackendThreadingTooltip": "Graphics Backend Multithreading'i etkinleştir",
"GalThreadingTooltip": "Executes graphics backend commands on a second thread. Allows runtime multithreading of shader compilation, reduces stuttering, and improves performance on drivers without multithreading support of their own. Slightly varying peak performance on drivers with multithreading. Ryujinx may need to be restarted to correctly disable driver built-in multithreading, or you may need to do it manually to get the best performance.",
"ShaderCacheToggleTooltip": "Shader Cache'i etkinleştir veya devre dışı bırak",
"ResolutionScaleTooltip": "Resolution Scale applied to applicable render targets",
"ResolutionScaleEntryTooltip": "Floating point resolution scale, such as 1.5. Non-integral scales are more likely to cause issues or crash.",
"AnisotropyTooltip": "Anisotropic Filtering Seviyesi (Oyun tarafından istenen değeri kullanmak için Otomatik seçeneğini kullanın)",
"AspectRatioTooltip": "Aspect Ratio applied to the renderer window.",
"ShaderDumpPathTooltip": "Graphics Shaders Dump Path",
"FileLogTooltip": "Diskte bir dosyaya loglamayı etkinleştirir veya devre dışı bırakır",
"StubLogTooltip": "Stub log mesajlarını yazdırmayı etkinleştirir",
"InfoLogTooltip": "Bilgi log mesajlarını yazdırmayı etkinleştirir",
"WarnLogTooltip": "Uyarı log mesajlarını yazdırmayı etkinleştirir",
"ErrorLogTooltip": "Hata log mesajlarını yazdırmayı etkinleştirir",
"TraceLogTooltip": "Trace log mesajlarını yazdırmayı etkinleştirir",
"GuestLogTooltip": "Guest log mesajlarını yazdırmayı etkinleştirir",
"FileAccessLogTooltip": "Dosya erişim log mesajlarını yazdırmayı etkinleştirir",
"FSAccessLogModeTooltip": "Enables FS access log output to the console. Possible modes are 0-3",
"DeveloperOptionTooltip": "Dikkatli kullanın",
"OpenGlLogLevel": "Uygun log seviyelerinin etkin olmasını gerektirir",
"DebugLogTooltip": "Debug log mesajlarını yazdırmayı etkinleştirir",
"LoadApplicationFileTooltip": "Switch'e uyumlu bir dosya açmak için bir dosya seçim arayüzü açar",
"LoadApplicationFolderTooltip": "Switch'e uyumlu sıkıştırılmamış uygulama açmak için bir dosya seçim arayüzü açar",
"OpenRyujinxFolderTooltip": "Ryujinx dosya sistemi klasörünü açar",
"OpenRyujinxLogsTooltip": "Log kayıtlarının yazıldığı klasörü açar",
"ExitTooltip": "Ryujinx'i Kapat",
"OpenSettingsTooltip": "Seçenekler penceresini aç",
"OpenProfileManagerTooltip": "Kullanıcı Profil Yönetimi penceresini açar",
"StopEmulationTooltip": "Güncel oyunun emülasyonunu durdurup oyun seçimine geri dönün",
"CheckUpdatesTooltip": "Ryujinx güncellemelerini denetle",
"OpenAboutTooltip": "Hakkında penceresini aç",
"GridSize": "Grid Boyutu",
"GridSizeTooltip": "Grid itemlerinin boyutunu değiştir",
"SettingsTabSystemSystemLanguageBrazilianPortuguese": "Brezilya Portekizcesi",
"AboutRyujinxContributorsButtonHeader": "Tüm katkıda bulunanları gör",
"SettingsTabSystemAudioVolume": "Ses Seviyesi: ",
"AudioVolumeTooltip": "Ses seviyesini değiştir",
"SettingsTabSystemEnableInternetAccess": "Guest Internet Erişimini Etkinleştir",
"EnableInternetAccessTooltip": "Guest internet erişimini etkinleştirir. Etkinleştirilmişse, uygulama emüle edilen Switch konsolu internete bağlıymış gibi davranır. Not: Bazı durumlarda uygulamalar bu seçenek devre dışı olmasına rağmen internete erişebilir",
"GameListContextMenuManageCheatToolTip" : "Hileleri Yönet",
"GameListContextMenuManageCheat" : "Hileleri Yönet",
"ControllerSettingsStickRange" : "Bölge (Range)",
"DialogStopEmulationTitle" : "Ryujinx - Emülasyonu Durdur",
"DialogStopEmulationMessage": "Emülasyonu durdurmak istediğinizden emin misiniz?",
"SettingsTabCpu": "CPU",
"SettingsTabAudio": "Ses",
"SettingsTabNetwork": "Ağ",
"SettingsTabNetworkConnection" : "Ağ Bağlantısı",
"SettingsTabGraphicsFrameRate" : "Host Yenileme Hızı:",
"SettingsTabGraphicsFrameRateTooltip" : "Host yenileme hızını ayarlar. Limiti kaldırmak için 0'ı seçin.",
"SettingsTabCpuCache" : "CPU Cache",
"SettingsTabCpuMemory" : "CPU Hafızası",
"DialogUpdaterFlatpakNotSupportedMessage": "Lütfen Ryujinx'i FlatHub aracılığıyla güncelleyin.",
"UpdaterDisabledWarningTitle": "Güncelleme aracı devre dışı!",
"GameListContextMenuOpenSdModsDirectory": "Atmosphere Modları Dizinini Aç",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Uygulamanın modlarının bulunduğu alternatif atmosphere SD kart dizinini açar",
"ControllerSettingsRotate90": "Saat yönünde 90° döndür",
"IconSize": "Simge Boyutu",
"IconSizeTooltip": "Oyunların simge boyutlarını değiştirir",
"MenuBarOptionsShowConsole": "Konsolu Göster",
"ShaderCachePurgeError" : "Belirtilen shader cache temizlenirken hata {0}: {1}",
"UserErrorNoKeys": "Keys bulunamadı",
"UserErrorNoFirmware": "Firmware bulunamadı",
"UserErrorFirmwareParsingFailed": "Firmware çözümleme hatası",
"UserErrorApplicationNotFound": "Uygulama bulunamadı",
"UserErrorUnknown": "Bilinmeyen hata",
"UserErrorUndefined": "Tanımlanmamış hata",
"UserErrorNoKeysDescription": "Ryujinx 'prod.keys' dosyanızı bulamadı",
"UserErrorNoFirmwareDescription": "Ryujinx yüklü firmware bulamadı",
"UserErrorFirmwareParsingFailedDescription": "Ryujinx verilen firmware'i çözümleyemedi. Bu durum genellikle güncel olmayan key'lerden kaynaklanır.",
"UserErrorApplicationNotFoundDescription": "Ryujinx verilen yolda geçerli bir uygulama bulamadı.",
"UserErrorUnknownDescription": "Bilinmeyen bir hata oluştu!",
"UserErrorUndefinedDescription": "Tanımlanmamış bir hata oluştu! Bu durumla karşılaşılmamalı, lütfen bir geliştirici ile iletişime geçin!",
"OpenSetupGuideMessage": "Kurulum kılavuzunu aç",
"NoUpdate": "Güncelleme Yok",
"TitleUpdateVersionLabel": "Sürüm {0} - {1}",
"RyujinxInfo": "Ryujinx - Bilgi",
"RyujinxConfirm": "Ryujinx - Onay",
"FileDialogAllTypes": "Tüm tarzlar",
"Never": "Hiçbir Zaman",
"SwkbdMinCharacters": "En az {0} karakter uzunluğunda olmalı",
"SwkbdMinRangeCharacters": "En az {0}-{1} karakter uzunluğunda olmalı",
"SoftwareKeyboard": "Software Klavyesi",
"DialogControllerAppletMessagePlayerRange": "Uygulama {0} oyuncu(lar) talep eder player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n",
"UpdaterRenaming": "Eski dosyalar yeniden adlandırılıyor...",
"UpdaterRenameFailed": "Güncelleme aracı belirilen dosyayı yeniden adlandıramadı: {0}",
"UpdaterAddingFiles": "Yeni dosyalar ekleniyor...",
"UpdaterExtracting": "Güncelleme ayıklanıyor...",
"UpdaterDownloading": "Güncelleme indiriliyor...",
"Game": "Oyun",
"Docked": "Docked",
"Handheld": "Handheld",
"ConnectionError": "Bağlantı Hatası.",
"AboutPageDeveloperListMore": "{0} ve daha fazla...",
"ApiError": "API Hatası.",
"LoadingHeading": "Yükleniyor {0}",
"CompilingPPTC": "PTC derleniyor",
"CompilingShaders": "Shaderlar derleniyor"
}

View file

@ -0,0 +1,56 @@
<Styles
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StyleInclude Source="avares://Ryujinx.Ava/Assets/Styles/Styles.xaml" />
<Design.PreviewWith>
<Border Padding="20" Height="2000">
<StackPanel Spacing="5">
<TextBlock Text="Code Font Family" />
<Grid RowDefinitions="*,Auto">
<Menu Grid.Row="1" Width="100">
<MenuItem Header="File">
<MenuItem Header="Test 1" />
<MenuItem Header="Test 2" />
<MenuItem Header="Test 3">
<MenuItem.Icon>
<CheckBox Margin="0" IsChecked="{Binding Checkbox, Mode=TwoWay}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<StackPanel Orientation="Horizontal">
<Button
Name="btnAdd"
HorizontalAlignment="Right"
Content="Add" />
<Button
Name="btnRem"
HorizontalAlignment="Right"
Content="Add" />
<TextBox Width="100" VerticalAlignment="Center" Text="Rrrrr" Watermark="Hello"
UseFloatingWatermark="True" />
<CheckBox>Test Check</CheckBox>
</StackPanel>
</Grid>
</StackPanel>
</Border>
</Design.PreviewWith>
<Styles.Resources>
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
<SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
<Color x:Key="SystemAccentColor">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark1">#FF99b000</Color>
<Color x:Key="SystemAccentColorDark2">#FF006d7d</Color>
<Color x:Key="SystemAccentColorDark3">#FF00525E</Color>
<Color x:Key="SystemAccentColorLight1">#FF00dbff</Color>
<Color x:Key="SystemAccentColorLight2">#FF19dfff</Color>
<Color x:Key="SystemAccentColorLight3">#FF33e3ff</Color>
<Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
<Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color>
<Color x:Key="ThemeControlBorderColor">#FF505050</Color>
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="ThemeForegroundColor">#FFFFFFFF</Color>
</Styles.Resources>
</Styles>

View file

@ -0,0 +1,51 @@
<Styles
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StyleInclude Source="avares://Ryujinx.Ava/Assets/Styles/Styles.xaml" />
<Design.PreviewWith>
<Border Padding="20" Height="2000">
<StackPanel Spacing="5">
<TextBlock Text="Code Font Family" />
<Grid RowDefinitions="*,Auto">
<Menu Grid.Row="1" Width="100">
<MenuItem Header="File">
<MenuItem Header="Test 1" />
<MenuItem Header="Test 2" />
<MenuItem Header="Test 3">
<MenuItem.Icon>
<CheckBox Margin="0" IsChecked="{Binding Checkbox, Mode=TwoWay}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<StackPanel Orientation="Horizontal">
<Button
Name="btnAdd"
HorizontalAlignment="Right"
Content="Add" />
<Button
Name="btnRem"
HorizontalAlignment="Right"
Content="Add" />
<TextBox Width="100" VerticalAlignment="Center" Text="Rrrrr" Watermark="Hello"
UseFloatingWatermark="True" />
<CheckBox>Test Check</CheckBox>
</StackPanel>
</Grid>
</StackPanel>
</Border>
</Design.PreviewWith>
<Styles.Resources>
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
<SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
<Color x:Key="SystemAccentColor">#FF00C3E3</Color>
<Color x:Key="ThemeAccentColor4">#FFe8e8e8</Color>
<Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
<Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color>
<Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color>
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFFFF</Color>
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="ThemeForegroundColor">#FF000000</Color>
</Styles.Resources>
</Styles>

View file

@ -0,0 +1,266 @@
<Styles
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<Design.PreviewWith>
<Border Padding="20" Height="2000">
<StackPanel Spacing="5">
<TextBlock Text="Code Font Family" />
<Grid RowDefinitions="*,Auto">
<Menu Grid.Row="1" Width="100">
<MenuItem Header="File">
<MenuItem Header="Test 1" />
<MenuItem Header="Test 2" />
<MenuItem Header="Test 3">
<MenuItem.Icon>
<CheckBox Margin="0" IsChecked="{Binding Checkbox, Mode=TwoWay}" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<StackPanel Orientation="Horizontal">
<ToggleButton
Name="btnAdd"
HorizontalAlignment="Right"
Height="28"
Content="Addy" />
<Button
Name="btnRem"
HorizontalAlignment="Right"
Content="Add" />
<TextBox Width="100" VerticalAlignment="Center" Text="Rrrrr" Watermark="Hello"
UseFloatingWatermark="True" />
<CheckBox>Test Check</CheckBox>
</StackPanel>
</Grid>
<ui:NumberBox Value="1" />
</StackPanel>
</Border>
</Design.PreviewWith>
<Style Selector="Border.small">
<Setter Property="Width" Value="100" />
</Style>
<Style Selector="Border.normal">
<Setter Property="Width" Value="130" />
</Style>
<Style Selector="Border.large">
<Setter Property="Width" Value="160" />
</Style>
<Style Selector="Border.huge">
<Setter Property="Width" Value="200" />
</Style>
<Style Selector="Image.small">
<Setter Property="Width" Value="50" />
</Style>
<Style Selector="Image.normal">
<Setter Property="Width" Value="80" />
</Style>
<Style Selector="Image.large">
<Setter Property="Width" Value="100" />
</Style>
<Style Selector="Image.huge">
<Setter Property="Width" Value="120" />
</Style>
<Style Selector="RadioButton">
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style Selector="#TitleBarHost > Image">
<Setter Property="Margin" Value="10" />
</Style>
<Style Selector="#TitleBarHost > Label">
<Setter Property="Margin" Value="5" />
<Setter Property="FontSize" Value="14" />
</Style>
<Style Selector="Button.SystemCaption">
<Setter Property="MinWidth" Value="10" />
</Style>
<Style Selector="DataGridColumnHeader">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundBrush}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="{DynamicResource ThemeControlBorderColor}" />
<Setter Property="SeparatorBrush" Value="{DynamicResource ThemeControlBorderColor}" />
<Setter Property="Padding" Value="5" />
<Setter Property="Background" Value="{DynamicResource ThemeContentBackgroundColor}" />
<Setter Property="Template">
<ControlTemplate>
<Grid Background="{TemplateBinding Background}" ColumnDefinitions="*,Auto">
<Grid
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
ColumnDefinitions="*,Auto">
<ContentPresenter Content="{TemplateBinding Content}" />
<Path
Name="SortIcon"
Grid.Column="1"
Width="8"
Margin="4,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z "
Fill="{TemplateBinding Foreground}"
Stretch="Uniform" />
</Grid>
<Rectangle
Name="VerticalSeparator"
Grid.Column="1"
Width="1"
VerticalAlignment="Stretch"
Fill="{TemplateBinding SeparatorBrush}"
IsVisible="{TemplateBinding AreSeparatorsVisible}" />
</Grid>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="DataGrid">
<Setter Property="RowBackground" Value="{DynamicResource ThemeAccentBrush4}" />
<Setter Property="AlternatingRowBackground" Value="#00FFFFFF" />
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderLowColor}" />
<Setter Property="BorderThickness" Value="{DynamicResource ThemeBorderThickness}" />
</Style>
<Style Selector="DataGridRow:selected:focus /template/ Rectangle#BackgroundRectangle">
<Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
<Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedBackgroundOpacity}" />
</Style>
<Style Selector="DataGridRow:pointerover /template/ Rectangle#BackgroundRectangle">
<Setter Property="Fill" Value="{DynamicResource SystemListLowColor}" />
</Style>
<Style Selector="DataGridRow:selected /template/ Rectangle#BackgroundRectangle">
<Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
<Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedUnfocusedBackgroundOpacity}" />
</Style>
<Style Selector="DataGridRow:selected:pointerover /template/ Rectangle#BackgroundRectangle">
<Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
<Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredUnfocusedBackgroundOpacity}" />
</Style>
<Style Selector="DataGridRow:selected:pointerover:focus /template/ Rectangle#BackgroundRectangle">
<Setter Property="Fill" Value="{DynamicResource SystemAccentColor}" />
<Setter Property="Opacity" Value="{DynamicResource DataGridRowSelectedHoveredBackgroundOpacity}" />
</Style>
<Style Selector="DataGridCell">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style Selector="DataGridCell.Left">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<Style Selector="CheckBox">
<Setter Property="BorderThickness" Value="1" />
</Style>
<Style Selector="MenuItem">
<Setter Property="Height" Value="{DynamicResource MenuItemHeight}" />
<Setter Property="Padding" Value="{DynamicResource MenuItemPadding}" />
</Style>
<Style Selector="MenuItem:selected /template/ Border#root">
<Setter Property="Background" Value="{DynamicResource ThemeControlBorderColor}" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeControlBorderColor}" />
</Style>
<Style Selector="TabItem &gt; ScrollViewer">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundColor}" />
<Setter Property="Margin" Value="0,-5,0,0" />
</Style>
<Style Selector="TabItem &gt; ScrollViewer &gt; Border">
<Setter Property="BorderThickness" Value="0,1,0,0" />
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundColor}" />
<Setter Property="BorderBrush" Value="{DynamicResource HighlightBrush}" />
</Style>
<Style Selector="Button">
<Setter Property="MinWidth" Value="80" />
</Style>
<Style Selector="ToggleButton">
<Setter Property="Padding" Value="0,-5,0,0" />
</Style>
<Style Selector="TabItem">
<Setter Property="FontSize" Value="14" />
<Setter Property="BorderThickness" Value="0,0,1,0" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeButtonForegroundColor}" />
<Setter Property="Background" Value="{DynamicResource HighlightColor}" />
</Style>
<Style Selector="TabItem:pointerover">
<Setter Property="Foreground" Value="{DynamicResource ThemeButtonForegroundColor}" />
</Style>
<Style Selector="TabItem:selected">
<Setter Property="Background" Value="{DynamicResource HighlightColor}" />
<Setter Property="Foreground" Value="{DynamicResource ThemeBackgroundColor}" />
</Style>
<Style Selector="TextBlock">
<Setter Property="Margin" Value="{DynamicResource TextMargin}" />
<Setter Property="FontSize" Value="{DynamicResource FontSize}" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style Selector="Separator">
<Setter Property="Background" Value="{DynamicResource ThemeControlBorderColor}" />
<Setter Property="Foreground" Value="{DynamicResource ThemeControlBorderColor}" />
<Setter Property="MinHeight" Value="1" />
</Style>
<Style Selector=":is(Button).DateTimeFlyoutButtonStyle">
<Setter Property="Background" Value="{DynamicResource HighlightColor}" />
<Setter Property="Foreground" Value="{DynamicResource ThemeBackgroundColor}" />
</Style>
<Style Selector="DatePickerPresenter">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{DynamicResource ThemeButtonForegroundColor}" />
</Style>
<Style Selector="DataGridCell">
<Setter Property="FontSize" Value="14" />
</Style>
<Style Selector="CheckBox TextBlock">
<Setter Property="Margin" Value="0,5,0,0" />
</Style>
<Style Selector="ContextMenu">
<Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" />
</Style>
<Style Selector="TextBox.NumberBoxTextBoxStyle">
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
</Style>
<Styles.Resources>
<StaticResource x:Key="ListViewItemBackgroundSelected" ResourceKey="ThemeAccentColorBrush" />
<StaticResource x:Key="ListViewItemBackgroundPressed" ResourceKey="SystemAccentColorDark1" />
<StaticResource x:Key="ListViewItemBackgroundPointerOver" ResourceKey="SystemAccentColorDark2" />
<StaticResource x:Key="ListViewItemBackgroundSelectedPressed" ResourceKey="ThemeAccentColorBrush" />
<StaticResource x:Key="ListViewItemBackgroundSelectedPointerOver" ResourceKey="SystemAccentColorDark2" />
<SolidColorBrush x:Key="DataGridGridLinesBrush"
Color="{DynamicResource SystemBaseMediumLowColor}"
Opacity="0.4" />
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" Color="{DynamicResource DataGridSelectionColor}" />
<SolidColorBrush x:Key="MenuFlyoutPresenterBorderBrush"
Color="{DynamicResource MenuFlyoutPresenterBorderColor}" />
<SolidColorBrush x:Key="ThemeAccentColorBrush" Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="ListBoxBackground" Color="{DynamicResource ThemeContentBackgroundColor}" />
<SolidColorBrush x:Key="ThemeForegroundBrush" Color="{DynamicResource ThemeForegroundColor}" />
<SolidColorBrush x:Key="ThemeAccentBrush4" Color="{DynamicResource ThemeAccentColor4}" />
<SolidColorBrush x:Key="SplitButtonBackgroundChecked" Color="#00E81123" />
<SolidColorBrush x:Key="SplitButtonBackgroundCheckedPointerOver" Color="#00E81123" />
<SolidColorBrush x:Key="SplitButtonBackgroundCheckedPressed" Color="#00E81123" />
<SolidColorBrush x:Key="SplitButtonBackgroundCheckedDisabled" Color="#00E81123" />
<Thickness x:Key="PageMargin">40 0 40 0</Thickness>
<Thickness x:Key="Margin">0 5 0 5</Thickness>
<Thickness x:Key="TextMargin">0 4 0 0</Thickness>
<Thickness x:Key="MenuItemPadding">5 0 5 0</Thickness>
<Color x:Key="MenuFlyoutPresenterBorderColor">#00000000</Color>
<Color x:Key="SystemAccentColor">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark1">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark2">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark3">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight1">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight2">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight3">#FF00C3E3</Color>
<Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
<Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color>
<Color x:Key="ThemeControlBorderColor">#FF505050</Color>
<sys:Double x:Key="ScrollBarThickness">15</sys:Double>
<sys:Double x:Key="FontSizeSmall">8</sys:Double>
<sys:Double x:Key="FontSizeNormal">10</sys:Double>
<sys:Double x:Key="FontSize">12</sys:Double>
<sys:Double x:Key="FontSizeLarge">15</sys:Double>
<sys:Double x:Key="ControlContentThemeFontSize">13</sys:Double>
<x:Double x:Key="MenuItemHeight">26</x:Double>
<x:Double x:Key="TabItemMinHeight">28</x:Double>
</Styles.Resources>
</Styles>

View file

@ -0,0 +1,417 @@
using Avalonia.Controls;
using Avalonia.Threading;
using LibHac;
using LibHac.Account;
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Fs.Shim;
using LibHac.FsSystem;
using LibHac.Ns;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.Ui.Common.Helper;
using System;
using System.Buffers;
using System.IO;
using System.Threading;
using static LibHac.Fs.ApplicationSaveDataManagement;
using Path = System.IO.Path;
namespace Ryujinx.Ava.Common
{
public static class ApplicationHelper
{
private static HorizonClient _horizonClient;
private static AccountManager _accountManager;
private static VirtualFileSystem _virtualFileSystem;
private static StyleableWindow _owner;
public static void Initialize(VirtualFileSystem virtualFileSystem, AccountManager accountManager, HorizonClient horizonClient, StyleableWindow owner)
{
_owner = owner;
_virtualFileSystem = virtualFileSystem;
_horizonClient = horizonClient;
_accountManager = accountManager;
}
private static bool TryFindSaveData(string titleName, ulong titleId,
BlitStruct<ApplicationControlProperty> controlHolder, in SaveDataFilter filter, out ulong saveDataId)
{
saveDataId = default;
Result result = _horizonClient.Fs.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo,
SaveDataSpaceId.User, in filter);
if (ResultFs.TargetNotFound.Includes(result))
{
ref ApplicationControlProperty control = ref controlHolder.Value;
Logger.Info?.Print(LogClass.Application, $"Creating save directory for Title: {titleName} [{titleId:x16}]");
if (Utilities.IsZeros(controlHolder.ByteSpan))
{
// If the current application doesn't have a loaded control property, create a dummy one
// and set the savedata sizes so a user savedata will be created.
control = ref new BlitStruct<ApplicationControlProperty>(1).Value;
// The set sizes don't actually matter as long as they're non-zero because we use directory savedata.
control.UserAccountSaveDataSize = 0x4000;
control.UserAccountSaveDataJournalSize = 0x4000;
Logger.Warning?.Print(LogClass.Application,
"No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
}
Uid user = new Uid((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low);
result = _horizonClient.Fs.EnsureApplicationSaveData(out _, new LibHac.Ncm.ApplicationId(titleId), in control, in user);
if (result.IsFailure())
{
ContentDialogHelper.CreateErrorDialog(_owner,
string.Format(LocaleManager.Instance["DialogMessageCreateSaveErrorMessage"], result.ToStringWithName()));
return false;
}
// Try to find the savedata again after creating it
result = _horizonClient.Fs.FindSaveDataWithFilter(out saveDataInfo, SaveDataSpaceId.User, in filter);
}
if (result.IsSuccess())
{
saveDataId = saveDataInfo.SaveDataId;
return true;
}
ContentDialogHelper.CreateErrorDialog(_owner,
string.Format(LocaleManager.Instance["DialogMessageFindSaveErrorMessage"], result.ToStringWithName()));
return false;
}
public static void OpenSaveDir(in SaveDataFilter saveDataFilter, ulong titleId,
BlitStruct<ApplicationControlProperty> controlData, string titleName)
{
if (!TryFindSaveData(titleName, titleId, controlData, in saveDataFilter, out ulong saveDataId))
{
return;
}
string saveRootPath = Path.Combine(_virtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}");
if (!Directory.Exists(saveRootPath))
{
// Inconsistent state. Create the directory
Directory.CreateDirectory(saveRootPath);
}
string committedPath = Path.Combine(saveRootPath, "0");
string workingPath = Path.Combine(saveRootPath, "1");
// If the committed directory exists, that path will be loaded the next time the savedata is mounted
if (Directory.Exists(committedPath))
{
OpenHelper.OpenFolder(committedPath);
}
else
{
// If the working directory exists and the committed directory doesn't,
// the working directory will be loaded the next time the savedata is mounted
if (!Directory.Exists(workingPath))
{
Directory.CreateDirectory(workingPath);
}
OpenHelper.OpenFolder(workingPath);
}
}
public static async void ExtractSection(NcaSectionType ncaSectionType, string titleFilePath,
int programIndex = 0)
{
OpenFolderDialog folderDialog = new() { Title = LocaleManager.Instance["FolderDialogExtractTitle"] };
string destination = await folderDialog.ShowAsync(_owner);
var cancellationToken = new CancellationTokenSource();
if (!string.IsNullOrWhiteSpace(destination))
{
Thread extractorThread = new(() =>
{
Dispatcher.UIThread.Post(async () =>
{
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
_owner,
string.Format(LocaleManager.Instance["DialogNcaExtractionMessage"], ncaSectionType, Path.GetFileName(titleFilePath)),
"",
"",
LocaleManager.Instance["InputDialogCancel"],
LocaleManager.Instance["DialogNcaExtractionTitle"]);
if (result == UserResult.Cancel)
{
cancellationToken.Cancel();
}
});
Thread.Sleep(1000);
using (FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read))
{
Nca mainNca = null;
Nca patchNca = null;
string extension = Path.GetExtension(titleFilePath).ToLower();
if (extension == ".nsp" || extension == ".pfs0" || extension == ".xci")
{
PartitionFileSystem pfs;
if (extension == ".xci")
{
Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
pfs = xci.OpenPartition(XciPartitionType.Secure);
}
else
{
pfs = new PartitionFileSystem(file.AsStorage());
}
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
{
using var ncaFile = new UniqueRef<IFile>();
pfs.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
if (nca.Header.ContentType == NcaContentType.Program)
{
int dataIndex =
Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.Header.GetFsHeader(dataIndex).IsPatchSection())
{
patchNca = nca;
}
else
{
mainNca = nca;
}
}
}
}
else if (extension == ".nca")
{
mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
}
if (mainNca == null)
{
Logger.Error?.Print(LogClass.Application,
"Extraction failure. The main NCA was not present in the selected file");
Dispatcher.UIThread.InvokeAsync(() =>
{
ContentDialogHelper.CreateErrorDialog(_owner, LocaleManager.Instance["DialogNcaExtractionMainNcaNotFoundErrorMessage"]);
});
return;
}
(Nca updatePatchNca, _) = ApplicationLoader.GetGameUpdateData(_virtualFileSystem,
mainNca.Header.TitleId.ToString("x16"), programIndex, out _);
if (updatePatchNca != null)
{
patchNca = updatePatchNca;
}
int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType);
try
{
IFileSystem ncaFileSystem = patchNca != null
? mainNca.OpenFileSystemWithPatch(patchNca, index, IntegrityCheckLevel.ErrorOnInvalid)
: mainNca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid);
FileSystemClient fsClient = _horizonClient.Fs;
string source = DateTime.Now.ToFileTime().ToString()[10..];
string output = DateTime.Now.ToFileTime().ToString()[10..];
using var uniqueSourceFs = new UniqueRef<IFileSystem>(ncaFileSystem);
using var uniqueOutputFs = new UniqueRef<IFileSystem>(new LocalFileSystem(destination));
fsClient.Register(source.ToU8Span(), ref uniqueSourceFs.Ref());
fsClient.Register(output.ToU8Span(), ref uniqueOutputFs.Ref());
(Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/", cancellationToken.Token);
if (!canceled)
{
if (resultCode.Value.IsFailure())
{
Logger.Error?.Print(LogClass.Application,
$"LibHac returned error code: {resultCode.Value.ErrorCode}");
Dispatcher.UIThread.InvokeAsync(() =>
{
ContentDialogHelper.CreateErrorDialog(_owner, LocaleManager.Instance["DialogNcaExtractionCheckLogErrorMessage"]);
});
}
else if (resultCode.Value.IsSuccess())
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
await ContentDialogHelper.CreateInfoDialog(
_owner,
LocaleManager.Instance["DialogNcaExtractionSuccessMessage"],
"",
LocaleManager.Instance["InputDialogOk"],
"",
LocaleManager.Instance["DialogNcaExtractionTitle"]);
});
}
}
fsClient.Unmount(source.ToU8Span());
fsClient.Unmount(output.ToU8Span());
}
catch (ArgumentException ex)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
ContentDialogHelper.CreateErrorDialog(_owner, ex.Message);
});
}
}
});
extractorThread.Name = "GUI.NcaSectionExtractorThread";
extractorThread.IsBackground = true;
extractorThread.Start();
}
}
public static (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath, CancellationToken token)
{
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All);
if (rc.IsFailure())
{
return (rc, false);
}
using (sourceHandle)
{
foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default))
{
if (token.IsCancellationRequested)
{
return (null, true);
}
string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name));
string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name));
if (entry.Type == DirectoryEntryType.Directory)
{
fs.EnsureDirectoryExists(subDstPath);
(Result? result, bool canceled) = CopyDirectory(fs, subSrcPath, subDstPath, token);
if (canceled || result.Value.IsFailure())
{
return (result, canceled);
}
}
if (entry.Type == DirectoryEntryType.File)
{
fs.CreateOrOverwriteFile(subDstPath, entry.Size);
rc = CopyFile(fs, subSrcPath, subDstPath);
if (rc.IsFailure())
{
return (rc, false);
}
}
}
}
return (Result.Success, false);
}
public static Result CopyFile(FileSystemClient fs, string sourcePath, string destPath)
{
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read);
if (rc.IsFailure())
{
return rc;
}
using (sourceHandle)
{
rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend);
if (rc.IsFailure())
{
return rc;
}
using (destHandle)
{
const int MaxBufferSize = 1024 * 1024;
rc = fs.GetFileSize(out long fileSize, sourceHandle);
if (rc.IsFailure())
{
return rc;
}
int bufferSize = (int)Math.Min(MaxBufferSize, fileSize);
byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
try
{
for (long offset = 0; offset < fileSize; offset += bufferSize)
{
int toRead = (int)Math.Min(fileSize - offset, bufferSize);
Span<byte> buf = buffer.AsSpan(0, toRead);
rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
if (rc.IsFailure())
{
return rc;
}
rc = fs.WriteFile(destHandle, offset, buf, WriteOption.None);
if (rc.IsFailure())
{
return rc;
}
}
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
rc = fs.FlushFile(destHandle);
if (rc.IsFailure())
{
return rc;
}
}
}
return Result.Success;
}
}
}

View file

@ -0,0 +1,15 @@
namespace Ryujinx.Ava.Common
{
internal enum ApplicationSort
{
Title,
TitleId,
Developer,
LastPlayed,
TotalTimePlayed,
FileType,
FileSize,
Path,
Favorite
}
}

View file

@ -0,0 +1,12 @@
namespace Ryujinx.Ava.Common
{
public enum KeyboardHotkeyState
{
None,
ToggleVSync,
Screenshot,
ShowUi,
Pause,
ToggleMute
}
}

View file

@ -0,0 +1,30 @@
using Avalonia.Data;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.MarkupExtensions;
using System;
namespace Ryujinx.Ava.Common.Locale
{
public class LocaleExtension : MarkupExtension
{
public LocaleExtension(string key)
{
Key = key;
}
public string Key { get; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
string keyToUse = Key;
ReflectionBindingExtension binding = new($"[{keyToUse}]")
{
Mode = BindingMode.OneWay,
Source = LocaleManager.Instance
};
return binding.ProvideValue(serviceProvider);
}
}
}

View file

@ -0,0 +1,105 @@
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.Common;
using Ryujinx.Ui.Common.Configuration;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
namespace Ryujinx.Ava.Common.Locale
{
class LocaleManager : BaseModel
{
private const string DefaultLanguageCode = "en_US";
private Dictionary<string, string> _localeStrings;
private ConcurrentDictionary<string, object[]> _dynamicValues;
public static LocaleManager Instance { get; } = new LocaleManager();
public Dictionary<string, string> LocaleStrings { get => _localeStrings; set => _localeStrings = value; }
public LocaleManager()
{
_localeStrings = new Dictionary<string, string>();
_dynamicValues = new ConcurrentDictionary<string, object[]>();
Load();
}
public void Load()
{
string localeLanguageCode = CultureInfo.CurrentCulture.Name.Replace('-', '_');
if (Program.PreviewerDetached)
{
if (!string.IsNullOrEmpty(ConfigurationState.Instance.Ui.LanguageCode.Value))
{
localeLanguageCode = ConfigurationState.Instance.Ui.LanguageCode.Value;
}
}
// Load english first, if the target language translation is incomplete, we default to english.
LoadLanguage(DefaultLanguageCode);
if (localeLanguageCode != DefaultLanguageCode)
{
LoadLanguage(localeLanguageCode);
}
}
public string this[string key]
{
get
{
if (_localeStrings.TryGetValue(key, out string value))
{
if (_dynamicValues.TryGetValue(key, out var dynamicValue))
{
return string.Format(value, dynamicValue);
}
return value;
}
return key;
}
set
{
_localeStrings[key] = value;
OnPropertyChanged();
}
}
public void UpdateDynamicValue(string key, params object[] values)
{
_dynamicValues[key] = values;
OnPropertyChanged("Item");
}
public void LoadLanguage(string languageCode)
{
string languageJson = EmbeddedResources.ReadAllText($"Ryujinx.Ava/Assets/Locales/{languageCode}.json");
if (languageJson == null)
{
return;
}
var strings = JsonSerializer.Deserialize<Dictionary<string, string>>(languageJson);
foreach (var item in strings)
{
this[item.Key] = item.Value;
}
if (Program.PreviewerDetached)
{
ConfigurationState.Instance.Ui.LanguageCode.Value = languageCode;
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
}
}
}
}

View file

@ -0,0 +1,205 @@
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Input;
using System;
using System.Collections.Generic;
using System.Numerics;
using ConfigKey = Ryujinx.Common.Configuration.Hid.Key;
using Key = Ryujinx.Input.Key;
namespace Ryujinx.Ava.Input
{
public class AvaloniaKeyboard : IKeyboard
{
private readonly List<ButtonMappingEntry> _buttonsUserMapping;
private readonly AvaloniaKeyboardDriver _driver;
private readonly object _userMappingLock = new();
private StandardKeyboardInputConfig _configuration;
private bool HasConfiguration => _configuration != null;
public string Id { get; }
public string Name { get; }
public bool IsConnected => true;
public GamepadFeaturesFlag Features => GamepadFeaturesFlag.None;
public AvaloniaKeyboard(AvaloniaKeyboardDriver driver, string id, string name)
{
_driver = driver;
Id = id;
Name = name;
_buttonsUserMapping = new List<ButtonMappingEntry>();
}
public void Dispose() { }
public KeyboardStateSnapshot GetKeyboardStateSnapshot()
{
return IKeyboard.GetStateSnapshot(this);
}
public GamepadStateSnapshot GetMappedStateSnapshot()
{
KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot();
GamepadStateSnapshot result = default;
lock (_userMappingLock)
{
if (!HasConfiguration)
{
return result;
}
foreach (ButtonMappingEntry entry in _buttonsUserMapping)
{
if (entry.From == Key.Unknown || entry.From == Key.Unbound || entry.To == GamepadButtonInputId.Unbound)
{
continue;
}
// Do not touch state of the button already pressed
if (!result.IsPressed(entry.To))
{
result.SetPressed(entry.To, rawState.IsPressed(entry.From));
}
}
(short leftStickX, short leftStickY) = GetStickValues(ref rawState, _configuration.LeftJoyconStick);
(short rightStickX, short rightStickY) = GetStickValues(ref rawState, _configuration.RightJoyconStick);
result.SetStick(StickInputId.Left, ConvertRawStickValue(leftStickX), ConvertRawStickValue(leftStickY));
result.SetStick(StickInputId.Right, ConvertRawStickValue(rightStickX), ConvertRawStickValue(rightStickY));
}
return result;
}
public GamepadStateSnapshot GetStateSnapshot()
{
throw new NotSupportedException();
}
public (float, float) GetStick(StickInputId inputId)
{
throw new NotSupportedException();
}
public bool IsPressed(GamepadButtonInputId inputId)
{
throw new NotSupportedException();
}
public bool IsPressed(Key key)
{
try
{
return _driver.IsPressed(key);
}
catch
{
return false;
}
}
public void SetConfiguration(InputConfig configuration)
{
lock (_userMappingLock)
{
_configuration = (StandardKeyboardInputConfig)configuration;
_buttonsUserMapping.Clear();
// Left joycon
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftStick, (Key)_configuration.LeftJoyconStick.StickButton));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadUp, (Key)_configuration.LeftJoycon.DpadUp));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadDown, (Key)_configuration.LeftJoycon.DpadDown));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadLeft, (Key)_configuration.LeftJoycon.DpadLeft));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadRight, (Key)_configuration.LeftJoycon.DpadRight));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Minus, (Key)_configuration.LeftJoycon.ButtonMinus));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftShoulder, (Key)_configuration.LeftJoycon.ButtonL));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftTrigger, (Key)_configuration.LeftJoycon.ButtonZl));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger0, (Key)_configuration.LeftJoycon.ButtonSr));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger0, (Key)_configuration.LeftJoycon.ButtonSl));
// Finally right joycon
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightStick, (Key)_configuration.RightJoyconStick.StickButton));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.A, (Key)_configuration.RightJoycon.ButtonA));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.B, (Key)_configuration.RightJoycon.ButtonB));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.X, (Key)_configuration.RightJoycon.ButtonX));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Y, (Key)_configuration.RightJoycon.ButtonY));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Plus, (Key)_configuration.RightJoycon.ButtonPlus));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightShoulder, (Key)_configuration.RightJoycon.ButtonR));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightTrigger, (Key)_configuration.RightJoycon.ButtonZr));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger1, (Key)_configuration.RightJoycon.ButtonSr));
_buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger1, (Key)_configuration.RightJoycon.ButtonSl));
}
}
public void SetTriggerThreshold(float triggerThreshold) { }
public void Rumble(float lowFrequency, float highFrequency, uint durationMs) { }
public Vector3 GetMotionData(MotionInputId inputId) => Vector3.Zero;
private static float ConvertRawStickValue(short value)
{
const float ConvertRate = 1.0f / (short.MaxValue + 0.5f);
return value * ConvertRate;
}
private static (short, short) GetStickValues(ref KeyboardStateSnapshot snapshot, JoyconConfigKeyboardStick<ConfigKey> stickConfig)
{
short stickX = 0;
short stickY = 0;
if (snapshot.IsPressed((Key)stickConfig.StickUp))
{
stickY += 1;
}
if (snapshot.IsPressed((Key)stickConfig.StickDown))
{
stickY -= 1;
}
if (snapshot.IsPressed((Key)stickConfig.StickRight))
{
stickX += 1;
}
if (snapshot.IsPressed((Key)stickConfig.StickLeft))
{
stickX -= 1;
}
Vector2 stick = new(stickX, stickY);
stick = Vector2.Normalize(stick);
return ((short)(stick.X * short.MaxValue), (short)(stick.Y * short.MaxValue));
}
public void Clear()
{
_driver?.ResetKeys();
}
private class ButtonMappingEntry
{
public readonly Key From;
public readonly GamepadButtonInputId To;
public ButtonMappingEntry(GamepadButtonInputId to, Key from)
{
To = to;
From = from;
}
}
}
}

View file

@ -0,0 +1,113 @@
using Avalonia.Controls;
using Avalonia.Input;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using AvaKey = Avalonia.Input.Key;
using Key = Ryujinx.Input.Key;
using TextInputEventArgs = OpenTK.Windowing.Common.TextInputEventArgs;
namespace Ryujinx.Ava.Input
{
public class AvaloniaKeyboardDriver : IGamepadDriver
{
private static readonly string[] _keyboardIdentifers = new string[1] { "0" };
private readonly Control _control;
private readonly HashSet<AvaKey> _pressedKeys;
public event EventHandler<KeyEventArgs> KeyPressed;
public event EventHandler<KeyEventArgs> KeyRelease;
public event EventHandler<TextInputEventArgs> TextInput;
public string DriverName => "Avalonia";
public ReadOnlySpan<string> GamepadsIds => _keyboardIdentifers;
public AvaloniaKeyboardDriver(Control control)
{
_control = control;
_pressedKeys = new HashSet<AvaKey>();
_control.KeyDown += OnKeyPress;
_control.KeyUp += OnKeyRelease;
_control.TextInput += Control_TextInput;
}
private void Control_TextInput(object sender, Avalonia.Input.TextInputEventArgs e)
{
TextInput?.Invoke(this, new TextInputEventArgs(e.Text.First()));
}
public event Action<string> OnGamepadConnected
{
add { }
remove { }
}
public event Action<string> OnGamepadDisconnected
{
add { }
remove { }
}
public void Dispose()
{
Dispose(true);
}
public IGamepad GetGamepad(string id)
{
if (!_keyboardIdentifers[0].Equals(id))
{
return null;
}
return new AvaloniaKeyboard(this, _keyboardIdentifers[0], LocaleManager.Instance["AllKeyboards"]);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_control.KeyUp -= OnKeyPress;
_control.KeyDown -= OnKeyRelease;
}
}
protected void OnKeyPress(object sender, KeyEventArgs args)
{
AvaKey key = args.Key;
_pressedKeys.Add(args.Key);
KeyPressed?.Invoke(this, args);
}
protected void OnKeyRelease(object sender, KeyEventArgs args)
{
_pressedKeys.Remove(args.Key);
KeyRelease?.Invoke(this, args);
}
internal bool IsPressed(Key key)
{
if (key == Key.Unbound || key == Key.Unknown)
{
return false;
}
AvaloniaMappingHelper.TryGetAvaKey(key, out var nativeKey);
return _pressedKeys.Contains(nativeKey);
}
public void ResetKeys()
{
_pressedKeys.Clear();
}
}
}

View file

@ -0,0 +1,188 @@
using Ryujinx.Input;
using System;
using System.Collections.Generic;
using AvaKey = Avalonia.Input.Key;
namespace Ryujinx.Ava.Input
{
public static class AvaloniaMappingHelper
{
private static readonly AvaKey[] _keyMapping = new AvaKey[(int)Key.Count]
{
// NOTE: Invalid
AvaKey.None,
AvaKey.LeftShift,
AvaKey.RightShift,
AvaKey.LeftCtrl,
AvaKey.RightCtrl,
AvaKey.LeftAlt,
AvaKey.RightAlt,
AvaKey.LWin,
AvaKey.RWin,
AvaKey.Apps,
AvaKey.F1,
AvaKey.F2,
AvaKey.F3,
AvaKey.F4,
AvaKey.F5,
AvaKey.F6,
AvaKey.F7,
AvaKey.F8,
AvaKey.F9,
AvaKey.F10,
AvaKey.F11,
AvaKey.F12,
AvaKey.F13,
AvaKey.F14,
AvaKey.F15,
AvaKey.F16,
AvaKey.F17,
AvaKey.F18,
AvaKey.F19,
AvaKey.F20,
AvaKey.F21,
AvaKey.F22,
AvaKey.F23,
AvaKey.F24,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.None,
AvaKey.Up,
AvaKey.Down,
AvaKey.Left,
AvaKey.Right,
AvaKey.Return,
AvaKey.Escape,
AvaKey.Space,
AvaKey.Tab,
AvaKey.Back,
AvaKey.Insert,
AvaKey.Delete,
AvaKey.PageUp,
AvaKey.PageDown,
AvaKey.Home,
AvaKey.End,
AvaKey.CapsLock,
AvaKey.Scroll,
AvaKey.Print,
AvaKey.Pause,
AvaKey.NumLock,
AvaKey.Clear,
AvaKey.NumPad0,
AvaKey.NumPad1,
AvaKey.NumPad2,
AvaKey.NumPad3,
AvaKey.NumPad4,
AvaKey.NumPad5,
AvaKey.NumPad6,
AvaKey.NumPad7,
AvaKey.NumPad8,
AvaKey.NumPad9,
AvaKey.Divide,
AvaKey.Multiply,
AvaKey.Subtract,
AvaKey.Add,
AvaKey.Decimal,
AvaKey.Enter,
AvaKey.A,
AvaKey.B,
AvaKey.C,
AvaKey.D,
AvaKey.E,
AvaKey.F,
AvaKey.G,
AvaKey.H,
AvaKey.I,
AvaKey.J,
AvaKey.K,
AvaKey.L,
AvaKey.M,
AvaKey.N,
AvaKey.O,
AvaKey.P,
AvaKey.Q,
AvaKey.R,
AvaKey.S,
AvaKey.T,
AvaKey.U,
AvaKey.V,
AvaKey.W,
AvaKey.X,
AvaKey.Y,
AvaKey.Z,
AvaKey.D0,
AvaKey.D1,
AvaKey.D2,
AvaKey.D3,
AvaKey.D4,
AvaKey.D5,
AvaKey.D6,
AvaKey.D7,
AvaKey.D8,
AvaKey.D9,
AvaKey.OemTilde,
AvaKey.OemTilde,AvaKey.OemMinus,
AvaKey.OemPlus,
AvaKey.OemOpenBrackets,
AvaKey.OemCloseBrackets,
AvaKey.OemSemicolon,
AvaKey.OemQuotes,
AvaKey.OemComma,
AvaKey.OemPeriod,
AvaKey.OemQuestion,
AvaKey.OemBackslash,
// NOTE: invalid
AvaKey.None
};
private static readonly Dictionary<AvaKey, Key> _avaKeyMapping;
static AvaloniaMappingHelper()
{
var inputKeys = Enum.GetValues(typeof(Key));
// Avalonia.Input.Key is not contiguous and quite large, so use a dictionary instead of an array.
_avaKeyMapping = new Dictionary<AvaKey, Key>();
foreach (var key in inputKeys)
{
if (TryGetAvaKey((Key)key, out var index))
{
_avaKeyMapping[index] = (Key)key;
}
}
}
public static bool TryGetAvaKey(Key key, out AvaKey avaKey)
{
var keyExist = (int)key < _keyMapping.Length;
if (keyExist)
{
avaKey = _keyMapping[(int)key];
}
else
{
avaKey = AvaKey.None;
}
return keyExist;
}
public static Key ToInputKey(AvaKey key)
{
return _avaKeyMapping.GetValueOrDefault(key, Key.Unknown);
}
}
}

View file

@ -0,0 +1,90 @@
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Input;
using System;
using System.Drawing;
using System.Numerics;
namespace Ryujinx.Ava.Input
{
public class AvaloniaMouse : IMouse
{
private AvaloniaMouseDriver _driver;
public GamepadFeaturesFlag Features => throw new NotImplementedException();
public string Id => "0";
public string Name => "AvaloniaMouse";
public bool IsConnected => true;
public bool[] Buttons => _driver.PressedButtons;
public AvaloniaMouse(AvaloniaMouseDriver driver)
{
_driver = driver;
}
public Size ClientSize => _driver.GetClientSize();
public Vector2 GetPosition()
{
return _driver.CurrentPosition;
}
public Vector2 GetScroll()
{
return _driver.Scroll;
}
public GamepadStateSnapshot GetMappedStateSnapshot()
{
throw new NotImplementedException();
}
public Vector3 GetMotionData(MotionInputId inputId)
{
throw new NotImplementedException();
}
public GamepadStateSnapshot GetStateSnapshot()
{
throw new NotImplementedException();
}
public (float, float) GetStick(StickInputId inputId)
{
throw new NotImplementedException();
}
public bool IsButtonPressed(MouseButton button)
{
return _driver.IsButtonPressed(button);
}
public bool IsPressed(GamepadButtonInputId inputId)
{
throw new NotImplementedException();
}
public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
throw new NotImplementedException();
}
public void SetConfiguration(InputConfig configuration)
{
throw new NotImplementedException();
}
public void SetTriggerThreshold(float triggerThreshold)
{
throw new NotImplementedException();
}
public void Dispose()
{
_driver = null;
}
}
}

View file

@ -0,0 +1,129 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Threading;
using Ryujinx.Input;
using System;
using System.Numerics;
using MouseButton = Ryujinx.Input.MouseButton;
using Size = System.Drawing.Size;
namespace Ryujinx.Ava.Input
{
public class AvaloniaMouseDriver : IGamepadDriver
{
private Control _widget;
private bool _isDisposed;
public bool[] PressedButtons { get; }
public Vector2 CurrentPosition { get; private set; }
public Vector2 Scroll { get; private set; }
public AvaloniaMouseDriver(Control parent)
{
_widget = parent;
_widget.PointerMoved += Parent_PointerMovedEvent;
_widget.PointerPressed += Parent_PointerPressEvent;
_widget.PointerReleased += Parent_PointerReleaseEvent;
_widget.PointerWheelChanged += Parent_ScrollEvent;
PressedButtons = new bool[(int)MouseButton.Count];
}
private void Parent_ScrollEvent(object o, PointerWheelEventArgs args)
{
Scroll = new Vector2((float)args.Delta.X, (float)args.Delta.Y);
}
private void Parent_PointerReleaseEvent(object o, PointerReleasedEventArgs args)
{
var pointerProperties = args.GetCurrentPoint(_widget).Properties;
PressedButtons[(int)args.InitialPressMouseButton - 1] = false;
}
private void Parent_PointerPressEvent(object o, PointerPressedEventArgs args)
{
var pointerProperties = args.GetCurrentPoint(_widget).Properties;
PressedButtons[(int)pointerProperties.PointerUpdateKind] = true;
}
private void Parent_PointerMovedEvent(object o, PointerEventArgs args)
{
var position = args.GetPosition(_widget);
CurrentPosition = new Vector2((float)position.X, (float)position.Y);
}
public void SetMousePressed(MouseButton button)
{
PressedButtons[(int)button] = true;
}
public void SetMouseReleased(MouseButton button)
{
PressedButtons[(int)button] = false;
}
public void SetPosition(double x, double y)
{
CurrentPosition = new Vector2((float)x, (float)y);
}
public bool IsButtonPressed(MouseButton button)
{
return PressedButtons[(int)button];
}
public Size GetClientSize()
{
Size size = new();
Dispatcher.UIThread.InvokeAsync(() =>
{
size = new Size((int)_widget.Bounds.Width, (int)_widget.Bounds.Height);
}).Wait();
return size;
}
public string DriverName => "Avalonia";
public event Action<string> OnGamepadConnected
{
add { }
remove { }
}
public event Action<string> OnGamepadDisconnected
{
add { }
remove { }
}
public ReadOnlySpan<string> GamepadsIds => new[] { "0" };
public IGamepad GetGamepad(string id)
{
return new AvaloniaMouse(this);
}
public void Dispose()
{
if (_isDisposed)
{
return;
}
_isDisposed = true;
_widget.PointerMoved -= Parent_PointerMovedEvent;
_widget.PointerPressed -= Parent_PointerPressEvent;
_widget.PointerReleased -= Parent_PointerReleaseEvent;
_widget.PointerWheelChanged -= Parent_ScrollEvent;
_widget = null;
}
}
}

View file

@ -0,0 +1,634 @@
using Avalonia.Threading;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
using Newtonsoft.Json.Linq;
using Ryujinx.Ava;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Modules
{
public static class Updater
{
private const string GitHubApiURL = "https://api.github.com";
internal static bool Running;
private static readonly string HomeDir = AppDomain.CurrentDomain.BaseDirectory;
private static readonly string UpdateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
private static readonly string UpdatePublishDir = Path.Combine(UpdateDir, "publish");
private static readonly int ConnectionCount = 4;
private static string _buildVer;
private static string _platformExt;
private static string _buildUrl;
private static long _buildSize;
private static readonly string[] WindowsDependencyDirs = Array.Empty<string>();
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
{
if (Running)
{
return;
}
Running = true;
mainWindow.CanUpdate = false;
// Detect current platform
if (OperatingSystem.IsMacOS())
{
_platformExt = "osx_x64.zip";
}
else if (OperatingSystem.IsWindows())
{
_platformExt = "win_x64.zip";
}
else if (OperatingSystem.IsLinux())
{
_platformExt = "linux_x64.tar.gz";
}
Version newVersion;
Version currentVersion;
try
{
currentVersion = Version.Parse(Program.Version);
}
catch
{
ContentDialogHelper.CreateWarningDialog(mainWindow, LocaleManager.Instance["DialogUpdaterConvertFailedMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
return;
}
// Get latest version number from GitHub API
try
{
using (HttpClient jsonClient = ConstructHttpClient())
{
string buildInfoURL = $"{GitHubApiURL}/repos/{ReleaseInformations.ReleaseChannelOwner}/{ReleaseInformations.ReleaseChannelRepo}/releases/latest";
string fetchedJson = await jsonClient.GetStringAsync(buildInfoURL);
JObject jsonRoot = JObject.Parse(fetchedJson);
JToken assets = jsonRoot["assets"];
_buildVer = (string)jsonRoot["name"];
foreach (JToken asset in assets)
{
string assetName = (string)asset["name"];
string assetState = (string)asset["state"];
string downloadURL = (string)asset["browser_download_url"];
if (assetName.StartsWith("ava-ryujinx") && assetName.EndsWith(_platformExt))
{
_buildUrl = downloadURL;
if (assetState != "uploaded")
{
if (showVersionUpToDate)
{
ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
}
return;
}
break;
}
}
// If build not done, assume no new update are availaible.
if (_buildUrl == null)
{
if (showVersionUpToDate)
{
ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
}
return;
}
}
}
catch (Exception exception)
{
Logger.Error?.Print(LogClass.Application, exception.Message);
ContentDialogHelper.CreateErrorDialog(mainWindow, LocaleManager.Instance["DialogUpdaterFailedToGetVersionMessage"]);
return;
}
try
{
newVersion = Version.Parse(_buildVer);
}
catch
{
ContentDialogHelper.CreateWarningDialog(mainWindow, LocaleManager.Instance["DialogUpdaterConvertFailedGithubMessage"], LocaleManager.Instance["DialogUpdaterCancelUpdateMessage"]);
Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
return;
}
if (newVersion <= currentVersion)
{
if (showVersionUpToDate)
{
ContentDialogHelper.CreateUpdaterInfoDialog(mainWindow, LocaleManager.Instance["DialogUpdaterAlreadyOnLatestVersionMessage"], "");
}
Running = false;
mainWindow.CanUpdate = true;
return;
}
// Fetch build size information to learn chunk sizes.
using (HttpClient buildSizeClient = ConstructHttpClient())
{
try
{
buildSizeClient.DefaultRequestHeaders.Add("Range", "bytes=0-0");
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_buildUrl), HttpCompletionOption.ResponseHeadersRead);
_buildSize = message.Content.Headers.ContentRange.Length.Value;
}
catch (Exception ex)
{
Logger.Warning?.Print(LogClass.Application, ex.Message);
Logger.Warning?.Print(LogClass.Application, "Couldn't determine build size for update, using single-threaded updater");
_buildSize = -1;
}
}
// Show a message asking the user if they want to update
UpdaterWindow updateDialog = new(mainWindow, newVersion, _buildUrl);
await updateDialog.ShowDialog(mainWindow);
}
private static HttpClient ConstructHttpClient()
{
HttpClient result = new HttpClient();
// Required by GitHub to interract with APIs.
result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
return result;
}
public static void UpdateRyujinx(UpdaterWindow updateDialog, string downloadUrl)
{
// Empty update dir, although it shouldn't ever have anything inside it
if (Directory.Exists(UpdateDir))
{
Directory.Delete(UpdateDir, true);
}
Directory.CreateDirectory(UpdateDir);
string updateFile = Path.Combine(UpdateDir, "update.bin");
// Download the update .zip
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterDownloading"];
updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.Maximum = 100;
Task.Run(() =>
{
if (_buildSize >= 0)
{
DoUpdateWithMultipleThreads(updateDialog, downloadUrl, updateFile);
}
else
{
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
}
});
}
private static void DoUpdateWithMultipleThreads(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
{
// Multi-Threaded Updater
long chunkSize = _buildSize / ConnectionCount;
long remainderChunk = _buildSize % ConnectionCount;
int completedRequests = 0;
int totalProgressPercentage = 0;
int[] progressPercentage = new int[ConnectionCount];
List<byte[]> list = new List<byte[]>(ConnectionCount);
List<WebClient> webClients = new List<WebClient>(ConnectionCount);
for (int i = 0; i < ConnectionCount; i++)
{
list.Add(Array.Empty<byte>());
}
for (int i = 0; i < ConnectionCount; i++)
{
#pragma warning disable SYSLIB0014
// TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient.
using (WebClient client = new WebClient())
#pragma warning restore SYSLIB0014
{
webClients.Add(client);
if (i == ConnectionCount - 1)
{
client.Headers.Add("Range", $"bytes={chunkSize * i}-{(chunkSize * (i + 1) - 1) + remainderChunk}");
}
else
{
client.Headers.Add("Range", $"bytes={chunkSize * i}-{chunkSize * (i + 1) - 1}");
}
client.DownloadProgressChanged += (_, args) =>
{
int index = (int)args.UserState;
Interlocked.Add(ref totalProgressPercentage, -1 * progressPercentage[index]);
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
updateDialog.ProgressBar.Value = totalProgressPercentage / ConnectionCount;
};
client.DownloadDataCompleted += (_, args) =>
{
int index = (int)args.UserState;
if (args.Cancelled)
{
webClients[index].Dispose();
return;
}
list[index] = args.Result;
Interlocked.Increment(ref completedRequests);
if (Interlocked.Equals(completedRequests, ConnectionCount))
{
byte[] mergedFileBytes = new byte[_buildSize];
for (int connectionIndex = 0, destinationOffset = 0; connectionIndex < ConnectionCount; connectionIndex++)
{
Array.Copy(list[connectionIndex], 0, mergedFileBytes, destinationOffset, list[connectionIndex].Length);
destinationOffset += list[connectionIndex].Length;
}
File.WriteAllBytes(updateFile, mergedFileBytes);
try
{
InstallUpdate(updateDialog, updateFile);
}
catch (Exception e)
{
Logger.Warning?.Print(LogClass.Application, e.Message);
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
return;
}
}
};
try
{
client.DownloadDataAsync(new Uri(downloadUrl), i);
}
catch (WebException ex)
{
Logger.Warning?.Print(LogClass.Application, ex.Message);
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
for (int j = 0; j < webClients.Count; j++)
{
webClients[j].CancelAsync();
}
DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
return;
}
}
}
}
private static void DoUpdateWithSingleThreadWorker(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
{
using (HttpClient client = new HttpClient())
{
// We do not want to timeout while downloading
client.Timeout = TimeSpan.FromDays(1);
using (HttpResponseMessage response = client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead).Result)
using (Stream remoteFileStream = response.Content.ReadAsStreamAsync().Result)
{
using (Stream updateFileStream = File.Open(updateFile, FileMode.Create))
{
long totalBytes = response.Content.Headers.ContentLength.Value;
long byteWritten = 0;
byte[] buffer = new byte[32 * 1024];
while (true)
{
int readSize = remoteFileStream.Read(buffer);
if (readSize == 0)
{
break;
}
byteWritten += readSize;
updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
updateFileStream.Write(buffer, 0, readSize);
}
}
}
InstallUpdate(updateDialog, updateFile);
}
}
private static void DoUpdateWithSingleThread(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
{
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile));
worker.Name = "Updater.SingleThreadWorker";
worker.Start();
}
[DllImport("libc", SetLastError = true)]
private static extern int chmod(string path, uint mode);
private static void SetUnixPermissions()
{
string ryuBin = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx");
if (!OperatingSystem.IsWindows())
{
chmod(ryuBin, 493);
}
}
private static async void InstallUpdate(UpdaterWindow updateDialog, string updateFile)
{
// Extract Update
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterExtracting"];
updateDialog.ProgressBar.Value = 0;
if (OperatingSystem.IsLinux())
{
using (Stream inStream = File.OpenRead(updateFile))
using (Stream gzipStream = new GZipInputStream(inStream))
using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII))
{
updateDialog.ProgressBar.Maximum = inStream.Length;
await Task.Run(() =>
{
TarEntry tarEntry;
while ((tarEntry = tarStream.GetNextEntry()) != null)
{
if (tarEntry.IsDirectory) continue;
string outPath = Path.Combine(UpdateDir, tarEntry.Name);
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
using (FileStream outStream = File.OpenWrite(outPath))
{
tarStream.CopyEntryContents(outStream);
}
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
TarEntry entry = tarEntry;
Dispatcher.UIThread.Post(() =>
{
updateDialog.ProgressBar.Value += entry.Size;
});
}
});
updateDialog.ProgressBar.Value = inStream.Length;
}
}
else
{
using (Stream inStream = File.OpenRead(updateFile))
using (ZipFile zipFile = new ZipFile(inStream))
{
updateDialog.ProgressBar.Maximum = zipFile.Count;
await Task.Run(() =>
{
foreach (ZipEntry zipEntry in zipFile)
{
if (zipEntry.IsDirectory) continue;
string outPath = Path.Combine(UpdateDir, zipEntry.Name);
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
using (Stream zipStream = zipFile.GetInputStream(zipEntry))
using (FileStream outStream = File.OpenWrite(outPath))
{
zipStream.CopyTo(outStream);
}
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
Dispatcher.UIThread.Post(() =>
{
updateDialog.ProgressBar.Value++;
});
}
});
}
}
// Delete downloaded zip
File.Delete(updateFile);
List<string> allFiles = EnumerateFilesToDelete().ToList();
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterRenaming"];
updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.Maximum = allFiles.Count;
// Replace old files
await Task.Run(() =>
{
foreach (string file in allFiles)
{
try
{
File.Move(file, file + ".ryuold");
Dispatcher.UIThread.Post(() =>
{
updateDialog.ProgressBar.Value++;
});
}
catch
{
Logger.Warning?.Print(LogClass.Application, string.Format(LocaleManager.Instance["UpdaterRenameFailed"], file));
}
}
Dispatcher.UIThread.Post(() =>
{
updateDialog.MainText.Text = LocaleManager.Instance["UpdaterAddingFiles"];
updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.Maximum = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length;
});
MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog);
});
Directory.Delete(UpdateDir, true);
SetUnixPermissions();
updateDialog.MainText.Text = LocaleManager.Instance["DialogUpdaterCompleteMessage"];
updateDialog.SecondaryText.Text = LocaleManager.Instance["DialogUpdaterRestartMessage"];
updateDialog.ProgressBar.IsVisible = false;
updateDialog.ButtonBox.IsVisible = true;
}
public static bool CanUpdate(bool showWarnings, StyleableWindow parent)
{
#if !DISABLE_UPDATER
if (RuntimeInformation.OSArchitecture != Architecture.X64)
{
if (showWarnings)
{
ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterArchNotSupportedMessage"],
LocaleManager.Instance["DialogUpdaterArchNotSupportedSubMessage"]);
}
return false;
}
if (!NetworkInterface.GetIsNetworkAvailable())
{
if (showWarnings)
{
ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterNoInternetMessage"],
LocaleManager.Instance["DialogUpdaterNoInternetSubMessage"]);
}
return false;
}
if (Program.Version.Contains("dirty") || !ReleaseInformations.IsValid())
{
if (showWarnings)
{
ContentDialogHelper.CreateWarningDialog(parent, LocaleManager.Instance["DialogUpdaterDirtyBuildMessage"],
LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
}
return false;
}
return true;
#else
if (showWarnings)
{
if (ReleaseInformations.IsFlatHubBuild())
{
ContentDialogHelper.CreateWarningDialog(parent,
LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterFlatpakNotSupportedMessage"]);
}
else
{
ContentDialogHelper.CreateWarningDialog(parent,
LocaleManager.Instance["UpdaterDisabledWarningTitle"], LocaleManager.Instance["DialogUpdaterDirtyBuildSubMessage"]);
}
}
return false;
#endif
}
// NOTE: This method should always reflect the latest build layout.s
private static IEnumerable<string> EnumerateFilesToDelete()
{
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
if (OperatingSystem.IsWindows())
{
foreach (string dir in WindowsDependencyDirs)
{
string dirPath = Path.Combine(HomeDir, dir);
if (Directory.Exists(dirPath))
{
files = files.Concat(Directory.EnumerateFiles(dirPath, "*", SearchOption.AllDirectories));
}
}
}
return files;
}
private static void MoveAllFilesOver(string root, string dest, UpdaterWindow dialog)
{
foreach (string directory in Directory.GetDirectories(root))
{
string dirName = Path.GetFileName(directory);
if (!Directory.Exists(Path.Combine(dest, dirName)))
{
Directory.CreateDirectory(Path.Combine(dest, dirName));
}
MoveAllFilesOver(directory, Path.Combine(dest, dirName), dialog);
}
foreach (string file in Directory.GetFiles(root))
{
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
Dispatcher.UIThread.InvokeAsync(() =>
{
dialog.ProgressBar.Value++;
});
}
}
public static void CleanupUpdate()
{
foreach (string file in Directory.GetFiles(HomeDir, "*.ryuold", SearchOption.AllDirectories))
{
File.Delete(file);
}
}
}
}

275
Ryujinx.Ava/Program.cs Normal file
View file

@ -0,0 +1,275 @@
using ARMeilleure.Translation.PTC;
using Avalonia;
using Avalonia.OpenGL;
using Avalonia.Rendering;
using Avalonia.Threading;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.Logging;
using Ryujinx.Common.System;
using Ryujinx.Common.SystemInfo;
using Ryujinx.Modules;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace Ryujinx.Ava
{
internal class Program
{
public static double WindowScaleFactor { get; set; }
public static string Version { get; private set; }
public static string ConfigurationPath { get; private set; }
public static string CommandLineProfile { get; set; }
public static bool PreviewerDetached { get; private set; }
public static RenderTimer RenderTimer { get; private set; }
[DllImport("user32.dll", SetLastError = true)]
public static extern int MessageBoxA(IntPtr hWnd, string text, string caption, uint type);
private const uint MB_ICONWARNING = 0x30;
public static void Main(string[] args)
{
Version = ReleaseInformations.GetVersion();
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
{
MessageBoxA(IntPtr.Zero, "You are running an outdated version of Windows.\n\nStarting on June 1st 2022, Ryujinx will only support Windows 10 1803 and newer.\n", $"Ryujinx {Version}", MB_ICONWARNING);
}
PreviewerDetached = true;
Initialize(args);
RenderTimer = new RenderTimer();
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
RenderTimer.Dispose();
}
public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
.UsePlatformDetect()
.With(new X11PlatformOptions
{
EnableMultiTouch = true,
EnableIme = true,
UseEGL = false,
UseGpu = true,
GlProfiles = new List<GlVersion>()
{
new GlVersion(GlProfileType.OpenGL, 4, 3)
}
})
.With(new Win32PlatformOptions
{
EnableMultitouch = true,
UseWgl = true,
WglProfiles = new List<GlVersion>()
{
new GlVersion(GlProfileType.OpenGL, 4, 3)
},
AllowEglInitialization = false,
CompositionBackdropCornerRadius = 8f,
})
.UseSkia()
.AfterSetup(_ =>
{
AvaloniaLocator.CurrentMutable
.Bind<IRenderTimer>().ToConstant(RenderTimer)
.Bind<IRenderLoop>().ToConstant(new RenderLoop(RenderTimer, Dispatcher.UIThread));
})
.LogToTrace();
}
private static void Initialize(string[] args)
{
// Parse Arguments.
string launchPathArg = null;
string baseDirPathArg = null;
bool startFullscreenArg = false;
for (int i = 0; i < args.Length; ++i)
{
string arg = args[i];
if (arg == "-r" || arg == "--root-data-dir")
{
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
baseDirPathArg = args[++i];
}
else if (arg == "-p" || arg == "--profile")
{
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
CommandLineProfile = args[++i];
}
else if (arg == "-f" || arg == "--fullscreen")
{
startFullscreenArg = true;
}
else
{
launchPathArg = arg;
}
}
// Make process DPI aware for proper window sizing on high-res screens.
ForceDpiAware.Windows();
WindowScaleFactor = ForceDpiAware.GetWindowScaleFactor();
// Delete backup files after updating.
Task.Run(Updater.CleanupUpdate);
Console.Title = $"Ryujinx Console {Version}";
// Hook unhandled exception and process exit events.
AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit();
// Setup base data directory.
AppDataManager.Initialize(baseDirPathArg);
// Initialize the configuration.
ConfigurationState.Initialize();
// Initialize the logger system.
LoggerModule.Initialize();
// Initialize Discord integration.
DiscordIntegrationModule.Initialize();
ReloadConfig();
// Logging system information.
PrintSystemInfo();
// Enable OGL multithreading on the driver, when available.
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
DriverUtilities.ToggleOGLThreading(threadingMode == BackendThreading.Off);
// Check if keys exists.
bool hasSystemProdKeys = File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"));
if (!hasSystemProdKeys)
{
if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"))))
{
MainWindow.ShowKeyErrorOnLoad = true;
}
}
if (launchPathArg != null)
{
MainWindow.DeferLoadApplication(launchPathArg, startFullscreenArg);
}
}
private static void ReloadConfig()
{
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, "Config.json");
// Now load the configuration as the other subsystems are now registered
if (File.Exists(localConfigurationPath))
{
ConfigurationPath = localConfigurationPath;
}
else if (File.Exists(appDataConfigurationPath))
{
ConfigurationPath = appDataConfigurationPath;
}
if (ConfigurationPath == null)
{
// No configuration, we load the default values and save it to disk
ConfigurationPath = appDataConfigurationPath;
ConfigurationState.Instance.LoadDefault();
ConfigurationState.Instance.ToFileFormat().SaveConfig(ConfigurationPath);
}
else
{
if (ConfigurationFileFormat.TryLoad(ConfigurationPath, out ConfigurationFileFormat configurationFileFormat))
{
ConfigurationState.Instance.Load(configurationFileFormat, ConfigurationPath);
}
else
{
ConfigurationState.Instance.LoadDefault();
Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location {ConfigurationPath}");
}
}
}
private static void PrintSystemInfo()
{
Logger.Notice.Print(LogClass.Application, $"Ryujinx Version: {Version}");
SystemInfo.Gather().Print();
var enabledLogs = Logger.GetEnabledLevels();
Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(enabledLogs.Count == 0 ? "<None>" : string.Join(", ", enabledLogs))}");
if (AppDataManager.Mode == AppDataManager.LaunchMode.Custom)
{
Logger.Notice.Print(LogClass.Application, $"Launch Mode: Custom Path {AppDataManager.BaseDirPath}");
}
else
{
Logger.Notice.Print(LogClass.Application, $"Launch Mode: {AppDataManager.Mode}");
}
}
private static void ProcessUnhandledException(Exception ex, bool isTerminating)
{
Ptc.Close();
PtcProfiler.Stop();
string message = $"Unhandled exception caught: {ex}";
Logger.Error?.PrintMsg(LogClass.Application, message);
if (Logger.Error == null)
{
Logger.Notice.PrintMsg(LogClass.Application, message);
}
if (isTerminating)
{
Exit();
}
}
public static void Exit()
{
DiscordIntegrationModule.Exit();
Ptc.Dispose();
PtcProfiler.Dispose();
Logger.Shutdown();
}
}
}

View file

@ -0,0 +1,141 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>1.0.0-dirty</Version>
<RootNamespace>Ryujinx.Ava</RootNamespace>
<ApplicationIcon>Ryujinx.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ContentWithTargetPath Include="..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>alsoft.ini</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="..\distribution\legal\THIRDPARTY.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>THIRDPARTY.md</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="..\Ryujinx.Audio\LICENSE.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>LICENSE-Ryujinx.Audio.txt</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
<ItemGroup>
<AvaloniaResource Include="Ui\**\*.xaml">
<SubType>Designer</SubType>
</AvaloniaResource>
<None Remove="Assets\Locales\el_GR.json" />
<None Remove="Assets\Locales\ru_RU.json" />
<AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
</ItemGroup>
<ItemGroup>
<None Remove="Assets\Styles\BaseDark.xaml" />
<None Remove="Assets\Styles\BaseLight.xaml" />
</ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\Styles\BaseLight.xaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaResource>
<AvaloniaResource Include="Assets\Styles\BaseDark.xaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaResource>
<AvaloniaResource Include="Assets\Styles\Styles.xaml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Controls.DataGrid" Version="0.10.14" />
<PackageReference Include="Avalonia.Markup.Xaml.Loader" Version="0.10.14" />
<PackageReference Include="Avalonia.Svg" Version="0.10.13" />
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.13" />
<PackageReference Include="DynamicData" Version="7.7.1" />
<PackageReference Include="FluentAvaloniaUI" Version="1.3.4" />
<PackageReference Include="Crc32.NET" Version="1.2.0" />
<PackageReference Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
<PackageReference Include="OpenTK" Version="4.6.3" />
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="4.4.0-build9" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="Avalonia" Version="0.10.14" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.14" />
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.14" />
<PackageReference Include="Silk.NET.Vulkan" Version="2.2.0" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.2.0" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.2.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="SPB" Version="0.0.4-build17" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\Locales\el_GR.json" />
<EmbeddedResource Include="Assets\Locales\en_US.json" />
<EmbeddedResource Include="Assets\Locales\es_ES.json" />
<EmbeddedResource Include="Assets\Locales\fr_FR.json" />
<EmbeddedResource Include="Assets\Locales\de_DE.json" />
<EmbeddedResource Include="Assets\Locales\it_IT.json" />
<EmbeddedResource Include="Assets\Locales\ko_KR.json" />
<EmbeddedResource Include="Assets\Locales\pt_BR.json" />
<EmbeddedResource Include="Assets\Locales\ru_RU.json" />
<EmbeddedResource Include="Assets\Locales\tr_TR.json" />
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
<ProjectReference Include="..\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj" />
<ProjectReference Include="..\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj" />
<ProjectReference Include="..\Ryujinx.Audio.Backends.SoundIo\Ryujinx.Audio.Backends.SoundIo.csproj" />
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
<ProjectReference Include="..\Ryujinx.Ui.Common\Ryujinx.Ui.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="App.axaml.cs">
<DependentUpon>App.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Ui\Windows\MainWindow.axaml.cs">
<DependentUpon>MainWindow.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Ui\Windows\AboutWindow.axaml.cs">
<DependentUpon>AboutWindow.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Ui\Applet\ErrorAppletWindow.axaml.cs">
<DependentUpon>ProfileWindow.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Ui\Applet\SwkbdAppletWindow.axaml.cs">
<DependentUpon>ProfileWindow.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Ui\Controls\InputDialog.axaml.cs">
<DependentUpon>InputDialog.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Ui\Windows\ContentDialogOverlay.xaml.cs">
<DependentUpon>ContentDialogOverlay.xaml</DependentUpon>
</Compile>
<Compile Update="Ui\Controls\GameListView.axaml.cs">
<DependentUpon>GameListView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project>

BIN
Ryujinx.Ava/Ryujinx.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View file

@ -0,0 +1,149 @@
using Avalonia.Controls;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
using Ryujinx.HLE.Ui;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Applet
{
internal class AvaHostUiHandler : IHostUiHandler
{
private readonly MainWindow _parent;
public IHostUiTheme HostUiTheme { get; }
public AvaHostUiHandler(MainWindow parent)
{
_parent = parent;
HostUiTheme = new AvaloniaHostUiTheme(parent);
}
public bool DisplayMessageDialog(ControllerAppletUiArgs args)
{
string playerCount = args.PlayerCountMin == args.PlayerCountMax
? args.PlayerCountMin.ToString()
: $"{args.PlayerCountMin}-{args.PlayerCountMax}";
string key = args.PlayerCountMin == args.PlayerCountMax ? "DialogControllerAppletMessage" : "DialogControllerAppletMessagePlayerRange";
string message = string.Format(LocaleManager.Instance[key],
playerCount,
args.SupportedStyles,
string.Join(", ", args.SupportedPlayers),
args.IsDocked ? LocaleManager.Instance["DialogControllerAppletDockModeSet"] : "");
return DisplayMessageDialog(LocaleManager.Instance["DialogControllerAppletTitle"], message);
}
public bool DisplayMessageDialog(string title, string message)
{
// TODO : Show controller applet. Needs settings window to be implemented.
Dispatcher.UIThread.InvokeAsync(() =>
{
ContentDialogHelper.ShowNotAvailableMessage(_parent);
});
return true;
}
public bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText)
{
ManualResetEvent dialogCloseEvent = new(false);
bool okPressed = false;
bool error = false;
string inputText = args.InitialText ?? "";
Dispatcher.UIThread.Post(async () =>
{
try
{
var response = await SwkbdAppletDialog.ShowInputDialog(_parent, LocaleManager.Instance["SoftwareKeyboard"], args);
if (response.Result == UserResult.Ok)
{
inputText = response.Input;
okPressed = true;
}
}
catch (Exception ex)
{
error = true;
ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogSoftwareKeyboardErrorExceptionMessage"], ex));
}
finally
{
dialogCloseEvent.Set();
}
});
dialogCloseEvent.WaitOne();
userText = error ? null : inputText;
return error || okPressed;
}
public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value)
{
device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value);
if (_parent.AppHost != null)
{
_parent.AppHost.Stop();
}
}
public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
{
ManualResetEvent dialogCloseEvent = new(false);
bool showDetails = false;
Dispatcher.UIThread.Post(async () =>
{
try
{
ErrorAppletWindow msgDialog = new(_parent, buttons, message)
{
Title = title,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Width = 400
};
object response = await msgDialog.Run();
if (response != null && buttons.Length > 1 && (int)response != buttons.Length - 1)
{
showDetails = true;
}
dialogCloseEvent.Set();
msgDialog.Close();
}
catch (Exception ex)
{
dialogCloseEvent.Set();
ContentDialogHelper.CreateErrorDialog(_parent, string.Format(LocaleManager.Instance["DialogErrorAppletErrorExceptionMessage"], ex));
}
});
dialogCloseEvent.WaitOne();
return showDetails;
}
public IDynamicTextInputHandler CreateDynamicTextInputHandler()
{
return new AvaloniaDynamicTextInputHandler(_parent);
}
}
}

View file

@ -0,0 +1,162 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Threading;
using OpenTK.Windowing.Common;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.HLE.Ui;
using System;
using System.Threading;
namespace Ryujinx.Ava.Ui.Applet
{
class AvaloniaDynamicTextInputHandler : IDynamicTextInputHandler
{
private MainWindow _parent;
private OffscreenTextBox _hiddenTextBox;
private bool _canProcessInput;
private IDisposable _textChangedSubscription;
private IDisposable _selectionStartChangedSubscription;
private IDisposable _selectionEndtextChangedSubscription;
public AvaloniaDynamicTextInputHandler(MainWindow parent)
{
_parent = parent;
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed += AvaloniaDynamicTextInputHandler_KeyPressed;
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease += AvaloniaDynamicTextInputHandler_KeyRelease;
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput += AvaloniaDynamicTextInputHandler_TextInput;
_hiddenTextBox = _parent.HiddenTextBox;
Dispatcher.UIThread.Post(() =>
{
_textChangedSubscription = _hiddenTextBox.GetObservable(TextBox.TextProperty).Subscribe(TextChanged);
_selectionStartChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionStartProperty).Subscribe(SelectionChanged);
_selectionEndtextChangedSubscription = _hiddenTextBox.GetObservable(TextBox.SelectionEndProperty).Subscribe(SelectionChanged);
});
}
private void TextChanged(string text)
{
TextChangedEvent?.Invoke(text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true);
}
private void SelectionChanged(int selection)
{
if (_hiddenTextBox.SelectionEnd < _hiddenTextBox.SelectionStart)
{
_hiddenTextBox.SelectionStart = _hiddenTextBox.SelectionEnd;
}
TextChangedEvent?.Invoke(_hiddenTextBox.Text ?? string.Empty, _hiddenTextBox.SelectionStart, _hiddenTextBox.SelectionEnd, true);
}
private void AvaloniaDynamicTextInputHandler_TextInput(object sender, TextInputEventArgs e)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
if (_canProcessInput)
{
_hiddenTextBox.SendText(e.AsString);
}
});
}
private void AvaloniaDynamicTextInputHandler_KeyRelease(object sender, Avalonia.Input.KeyEventArgs e)
{
var key = (Key)AvaloniaMappingHelper.ToInputKey(e.Key);
if (!(KeyReleasedEvent?.Invoke(key)).GetValueOrDefault(true))
{
return;
}
e.RoutedEvent = _hiddenTextBox.GetKeyUpRoutedEvent();
Dispatcher.UIThread.InvokeAsync(() =>
{
if (_canProcessInput)
{
_hiddenTextBox.SendKeyUpEvent(e);
}
});
}
private void AvaloniaDynamicTextInputHandler_KeyPressed(object sender, Avalonia.Input.KeyEventArgs e)
{
var key = (Key)AvaloniaMappingHelper.ToInputKey(e.Key);
if (!(KeyPressedEvent?.Invoke(key)).GetValueOrDefault(true))
{
return;
}
e.RoutedEvent = _hiddenTextBox.GetKeyUpRoutedEvent();
Dispatcher.UIThread.InvokeAsync(() =>
{
if (_canProcessInput)
{
_hiddenTextBox.SendKeyDownEvent(e);
}
});
}
public bool TextProcessingEnabled
{
get
{
return Volatile.Read(ref _canProcessInput);
}
set
{
Volatile.Write(ref _canProcessInput, value);
}
}
public event DynamicTextChangedHandler TextChangedEvent;
public event KeyPressedHandler KeyPressedEvent;
public event KeyReleasedHandler KeyReleasedEvent;
public void Dispose()
{
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyPressed -= AvaloniaDynamicTextInputHandler_KeyPressed;
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).KeyRelease -= AvaloniaDynamicTextInputHandler_KeyRelease;
(_parent.InputManager.KeyboardDriver as AvaloniaKeyboardDriver).TextInput -= AvaloniaDynamicTextInputHandler_TextInput;
_textChangedSubscription?.Dispose();
_selectionStartChangedSubscription?.Dispose();
_selectionEndtextChangedSubscription?.Dispose();
Dispatcher.UIThread.Post(() =>
{
_hiddenTextBox.Clear();
_parent.GlRenderer.Focus();
_parent = null;
});
}
public void SetText(string text, int cursorBegin)
{
Dispatcher.UIThread.Post(() =>
{
_hiddenTextBox.Text = text;
_hiddenTextBox.CaretIndex = cursorBegin;
});
}
public void SetText(string text, int cursorBegin, int cursorEnd)
{
Dispatcher.UIThread.Post(() =>
{
_hiddenTextBox.Text = text;
_hiddenTextBox.SelectionStart = cursorBegin;
_hiddenTextBox.SelectionEnd = cursorEnd;
});
}
}
}

View file

@ -0,0 +1,43 @@
using Avalonia.Media;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.HLE.Ui;
using System;
namespace Ryujinx.Ava.Ui.Applet
{
class AvaloniaHostUiTheme : IHostUiTheme
{
public AvaloniaHostUiTheme(MainWindow parent)
{
FontFamily = OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000, 0) ? "Segoe UI Variable" : parent.FontFamily.Name;
DefaultBackgroundColor = BrushToThemeColor(parent.Background);
DefaultForegroundColor = BrushToThemeColor(parent.Foreground);
DefaultBorderColor = BrushToThemeColor(parent.BorderBrush);
SelectionBackgroundColor = BrushToThemeColor(parent.SearchBox.SelectionBrush);
SelectionForegroundColor = BrushToThemeColor(parent.SearchBox.SelectionForegroundBrush);
}
public string FontFamily { get; }
public ThemeColor DefaultBackgroundColor { get; }
public ThemeColor DefaultForegroundColor { get; }
public ThemeColor DefaultBorderColor { get; }
public ThemeColor SelectionBackgroundColor { get; }
public ThemeColor SelectionForegroundColor { get; }
private ThemeColor BrushToThemeColor(IBrush brush)
{
if (brush is SolidColorBrush solidColor)
{
return new ThemeColor((float)solidColor.Color.A / 255,
(float)solidColor.Color.R / 255,
(float)solidColor.Color.G / 255,
(float)solidColor.Color.B / 255);
}
else
{
return new ThemeColor();
}
}
}
}

View file

@ -0,0 +1,31 @@
<Window xmlns="https://github.com/avaloniaui"
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:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.Ui.Applet.ErrorAppletWindow"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
CanResize="False"
SizeToContent="Height"
Width="450"
Height="340"
Title="{locale:Locale ErrorWindowTitle}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Row="1" Grid.RowSpan="2" Margin="5, 10, 20 , 10" Grid.Column="0"
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" Height="80" MinWidth="50" />
<TextBlock Grid.Row="1" Margin="10" Grid.Column="1" VerticalAlignment="Stretch" TextWrapping="Wrap"
Text="{Binding Message}" />
<StackPanel Name="ButtonStack" Margin="10" Spacing="10" Grid.Row="2" Grid.Column="1"
HorizontalAlignment="Right" Orientation="Horizontal" />
</Grid>
</Window>

View file

@ -0,0 +1,89 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Windows;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Applet
{
public class ErrorAppletWindow : StyleableWindow
{
private readonly Window _owner;
private object _buttonResponse;
public ErrorAppletWindow(Window owner, string[] buttons, string message)
{
_owner = owner;
Message = message;
DataContext = this;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
int responseId = 0;
if (buttons != null)
{
foreach (string buttonText in buttons)
{
AddButton(buttonText, responseId);
responseId++;
}
}
else
{
AddButton(LocaleManager.Instance["InputDialogOk"], 0);
}
}
public ErrorAppletWindow()
{
DataContext = this;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
public string Message { get; set; }
public StackPanel ButtonStack { get; set; }
private void AddButton(string label, object tag)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
Button button = new() { Content = label, Tag = tag };
button.Click += Button_Click;
ButtonStack.Children.Add(button);
});
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (sender is Button button)
{
_buttonResponse = button.Tag;
}
Close();
}
public async Task<object> Run()
{
await ShowDialog(_owner);
return _buttonResponse;
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
ButtonStack = this.FindControl<StackPanel>("ButtonStack");
}
}
}

View file

@ -0,0 +1,32 @@
<UserControl xmlns="https://github.com/avaloniaui"
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:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.Ui.Controls.SwkbdAppletDialog"
Width="400">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Row="1" VerticalAlignment="Center" Grid.RowSpan="5" Margin="5, 10, 20 , 10"
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" Height="80"
MinWidth="50" />
<TextBlock Grid.Row="1" Margin="5" Grid.Column="1" Text="{Binding MainText}" TextWrapping="Wrap" />
<TextBlock Grid.Row="2" Margin="5" Grid.Column="1" Text="{Binding SecondaryText}" TextWrapping="Wrap" />
<TextBox Name="Input" KeyUp="Message_KeyUp" UseFloatingWatermark="True" TextInput="Message_TextInput"
Text="{Binding Message}" Grid.Row="2"
Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap" />
<TextBlock Name="Error" Margin="5" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Stretch"
TextWrapping="Wrap" />
</Grid>
</UserControl>

View file

@ -0,0 +1,152 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.HLE.HOS.Applets;
using System;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls
{
public class SwkbdAppletDialog : UserControl
{
private Predicate<int> _checkLength;
private int _inputMax;
private int _inputMin;
private string _placeholder;
private ContentDialog _host;
public SwkbdAppletDialog(string mainText, string secondaryText, string placeholder)
{
MainText = mainText;
SecondaryText = secondaryText;
DataContext = this;
_placeholder = placeholder;
InitializeComponent();
SetInputLengthValidation(0, int.MaxValue); // Disable by default.
}
public SwkbdAppletDialog()
{
DataContext = this;
InitializeComponent();
}
public string Message { get; set; } = "";
public string MainText { get; set; } = "";
public string SecondaryText { get; set; } = "";
public TextBlock Error { get; private set; }
public TextBox Input { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
Error = this.FindControl<TextBlock>("Error");
Input = this.FindControl<TextBox>("Input");
Input.Watermark = _placeholder;
Input.AddHandler(TextInputEvent, Message_TextInput, RoutingStrategies.Tunnel, true);
}
public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, SoftwareKeyboardUiArgs args)
{
ContentDialog contentDialog = window.ContentDialog;
UserResult result = UserResult.Cancel;
SwkbdAppletDialog content = new SwkbdAppletDialog(args.HeaderText, args.SubtitleText, args.GuideText)
{
Message = args.InitialText ?? ""
};
string input = string.Empty;
content.SetInputLengthValidation(args.StringLengthMin, args.StringLengthMax);
if (contentDialog != null)
{
content._host = contentDialog;
contentDialog.Title = title;
contentDialog.PrimaryButtonText = args.SubmitText;
contentDialog.IsPrimaryButtonEnabled = content._checkLength(content.Message.Length);
contentDialog.SecondaryButtonText = "";
contentDialog.CloseButtonText = LocaleManager.Instance["InputDialogCancel"];
contentDialog.Content = content;
TypedEventHandler<ContentDialog, ContentDialogClosedEventArgs> handler = (sender, eventArgs) =>
{
if (eventArgs.Result == ContentDialogResult.Primary)
{
result = UserResult.Ok;
input = content.Input.Text;
}
};
contentDialog.Closed += handler;
await contentDialog.ShowAsync();
contentDialog.Closed -= handler;
}
return (result, input);
}
public void SetInputLengthValidation(int min, int max)
{
_inputMin = Math.Min(min, max);
_inputMax = Math.Max(min, max);
Error.IsVisible = false;
Error.FontStyle = FontStyle.Italic;
if (_inputMin <= 0 && _inputMax == int.MaxValue) // Disable.
{
Error.IsVisible = false;
_checkLength = length => true;
}
else if (_inputMin > 0 && _inputMax == int.MaxValue)
{
Error.IsVisible = true;
Error.Text = string.Format(LocaleManager.Instance["SwkbdMinCharacters"], _inputMin);
_checkLength = length => _inputMin <= length;
}
else
{
Error.IsVisible = true;
Error.Text = string.Format(LocaleManager.Instance["SwkbdMinRangeCharacters"], _inputMin, _inputMax);
_checkLength = length => _inputMin <= length && length <= _inputMax;
}
Message_TextInput(this, new TextInputEventArgs());
}
private void Message_TextInput(object sender, TextInputEventArgs e)
{
if (_host != null)
{
_host.IsPrimaryButtonEnabled = _checkLength(Message.Length);
}
}
private void Message_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && _host.IsPrimaryButtonEnabled)
{
_host.Hide(ContentDialogResult.Primary);
}
else
{
_host.IsPrimaryButtonEnabled = _checkLength(Message.Length);
}
}
}
}

View file

@ -0,0 +1,16 @@
using Avalonia.Interactivity;
using Ryujinx.Ui.App.Common;
namespace Ryujinx.Ava.Ui.Controls
{
public class ApplicationOpenedEventArgs : RoutedEventArgs
{
public ApplicationData Application { get; }
public ApplicationOpenedEventArgs(ApplicationData application, RoutedEvent routedEvent)
{
Application = application;
RoutedEvent = routedEvent;
}
}
}

View file

@ -0,0 +1,16 @@
using SPB.Graphics;
using System;
using System.Runtime.Versioning;
namespace Ryujinx.Ava.Ui.Controls
{
[SupportedOSPlatform("linux")]
public class AvaloniaGlxContext : SPB.Platform.GLX.GLXOpenGLContext
{
public AvaloniaGlxContext(IntPtr handle)
: base(FramebufferFormat.Default, 0, 0, 0, false, null)
{
ContextHandle = handle;
}
}
}

View file

@ -0,0 +1,16 @@
using SPB.Graphics;
using System;
using System.Runtime.Versioning;
namespace Ryujinx.Ava.Ui.Controls
{
[SupportedOSPlatform("windows")]
public class AvaloniaWglContext : SPB.Platform.WGL.WGLOpenGLContext
{
public AvaloniaWglContext(IntPtr handle)
: base(FramebufferFormat.Default, 0, 0, 0, false, null)
{
ContextHandle = handle;
}
}
}

View file

@ -0,0 +1,35 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using System;
using System.Globalization;
using System.IO;
namespace Ryujinx.Ava.Ui.Controls
{
public class BitmapArrayValueConverter : IValueConverter
{
public static BitmapArrayValueConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
if (value is byte[] buffer && targetType == typeof(IImage))
{
MemoryStream mem = new(buffer);
return new Bitmap(mem);
}
throw new NotSupportedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}

View file

@ -0,0 +1,357 @@
using Avalonia.Controls;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Common.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls
{
public static class ContentDialogHelper
{
private static bool _isChoiceDialogOpen;
private async static Task<UserResult> ShowContentDialog(
StyleableWindow window,
string title,
string primaryText,
string secondaryText,
string primaryButton,
string secondaryButton,
string closeButton,
int iconSymbol,
UserResult primaryButtonResult = UserResult.Ok)
{
UserResult result = UserResult.None;
ContentDialog contentDialog = window.ContentDialog;
await ShowDialog();
async Task ShowDialog()
{
if (contentDialog != null)
{
contentDialog.Title = title;
contentDialog.PrimaryButtonText = primaryButton;
contentDialog.SecondaryButtonText = secondaryButton;
contentDialog.CloseButtonText = closeButton;
contentDialog.Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol);
contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
{
result = primaryButtonResult;
});
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
{
result = UserResult.No;
});
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
{
result = UserResult.Cancel;
});
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
};
}
return result;
}
public async static Task<UserResult> ShowDeferredContentDialog(
StyleableWindow window,
string title,
string primaryText,
string secondaryText,
string primaryButton,
string secondaryButton,
string closeButton,
int iconSymbol,
ManualResetEvent deferResetEvent,
Func<Window, Task> doWhileDeferred = null)
{
bool startedDeferring = false;
UserResult result = UserResult.None;
ContentDialog contentDialog = window.ContentDialog;
Window overlay = window;
if (contentDialog != null)
{
contentDialog.PrimaryButtonClick += DeferClose;
contentDialog.Title = title;
contentDialog.PrimaryButtonText = primaryButton;
contentDialog.SecondaryButtonText = secondaryButton;
contentDialog.CloseButtonText = closeButton;
contentDialog.Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol);
contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
{
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
});
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
{
result = UserResult.No;
});
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
{
result = UserResult.Cancel;
});
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
};
return result;
async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
if (startedDeferring)
{
return;
}
startedDeferring = true;
var deferral = args.GetDeferral();
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
contentDialog.PrimaryButtonClick -= DeferClose;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(() =>
{
deferResetEvent.WaitOne();
Dispatcher.UIThread.Post(() =>
{
deferral.Complete();
});
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
if (doWhileDeferred != null)
{
await doWhileDeferred(overlay);
deferResetEvent.Set();
}
}
}
private static Grid CreateDialogTextContent(string primaryText, string secondaryText, int symbol)
{
Grid content = new Grid();
content.RowDefinitions = new RowDefinitions() { new RowDefinition(), new RowDefinition() };
content.ColumnDefinitions = new ColumnDefinitions() { new ColumnDefinition(GridLength.Auto), new ColumnDefinition() };
content.MinHeight = 80;
SymbolIcon icon = new SymbolIcon { Symbol = (Symbol)symbol, Margin = new Avalonia.Thickness(10) };
icon.FontSize = 40;
icon.VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center;
Grid.SetColumn(icon, 0);
Grid.SetRowSpan(icon, 2);
Grid.SetRow(icon, 0);
TextBlock primaryLabel = new TextBlock()
{
Text = primaryText,
Margin = new Avalonia.Thickness(5),
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
MaxWidth = 450
};
TextBlock secondaryLabel = new TextBlock()
{
Text = secondaryText,
Margin = new Avalonia.Thickness(5),
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
MaxWidth = 450
};
Grid.SetColumn(primaryLabel, 1);
Grid.SetColumn(secondaryLabel, 1);
Grid.SetRow(primaryLabel, 0);
Grid.SetRow(secondaryLabel, 1);
content.Children.Add(icon);
content.Children.Add(primaryLabel);
content.Children.Add(secondaryLabel);
return content;
}
public static async Task<UserResult> CreateInfoDialog(
StyleableWindow window,
string primary,
string secondaryText,
string acceptButton,
string closeButton,
string title)
{
return await ShowContentDialog(
window,
title,
primary,
secondaryText,
acceptButton,
"",
closeButton,
(int)Symbol.Important);
}
internal static async Task<UserResult> CreateConfirmationDialog(
StyleableWindow window,
string primaryText,
string secondaryText,
string acceptButtonText,
string cancelButtonText,
string title,
UserResult primaryButtonResult = UserResult.Yes)
{
return await ShowContentDialog(
window,
string.IsNullOrWhiteSpace(title) ? LocaleManager.Instance["DialogConfirmationTitle"] : title,
primaryText,
secondaryText,
acceptButtonText,
"",
cancelButtonText,
(int)Symbol.Help,
primaryButtonResult);
}
internal static UpdateWaitWindow CreateWaitingDialog(string mainText, string secondaryText)
{
return new(mainText, secondaryText);
}
internal static async void CreateUpdaterInfoDialog(StyleableWindow window, string primary, string secondaryText)
{
await ShowContentDialog(
window,
LocaleManager.Instance["DialogUpdaterTitle"],
primary,
secondaryText,
"",
"",
LocaleManager.Instance["InputDialogOk"],
(int)Symbol.Important);
}
internal static async void ShowNotAvailableMessage(StyleableWindow window)
{
// Temporary placeholder for features to be added
await ShowContentDialog(
window,
"Feature Not Available",
"The selected feature is not available in this version.",
"",
"",
"",
LocaleManager.Instance["InputDialogOk"],
(int)Symbol.Important);
}
internal static async void CreateWarningDialog(StyleableWindow window, string primary, string secondaryText)
{
await ShowContentDialog(
window,
LocaleManager.Instance["DialogWarningTitle"],
primary,
secondaryText,
"",
"",
LocaleManager.Instance["InputDialogOk"],
(int)Symbol.Important);
}
internal static async void CreateErrorDialog(StyleableWindow owner, string errorMessage, string secondaryErrorMessage = "")
{
Logger.Error?.Print(LogClass.Application, errorMessage);
await ShowContentDialog(
owner,
LocaleManager.Instance["DialogErrorTitle"],
LocaleManager.Instance["DialogErrorMessage"],
errorMessage,
secondaryErrorMessage,
"",
LocaleManager.Instance["InputDialogOk"],
(int)Symbol.Dismiss);
}
internal static async Task<bool> CreateChoiceDialog(StyleableWindow window, string title, string primary, string secondaryText)
{
if (_isChoiceDialogOpen)
{
return false;
}
_isChoiceDialogOpen = true;
UserResult response =
await ShowContentDialog(
window,
title,
primary,
secondaryText,
LocaleManager.Instance["InputDialogYes"],
"",
LocaleManager.Instance["InputDialogNo"],
(int)Symbol.Help,
UserResult.Yes);
_isChoiceDialogOpen = false;
return response == UserResult.Yes;
}
internal static async Task<bool> CreateExitDialog(StyleableWindow owner)
{
return await CreateChoiceDialog(
owner,
LocaleManager.Instance["DialogExitTitle"],
LocaleManager.Instance["DialogExitMessage"],
LocaleManager.Instance["DialogExitSubMessage"]);
}
internal static async Task<bool> CreateStopEmulationDialog(StyleableWindow owner)
{
return await CreateChoiceDialog(
owner,
LocaleManager.Instance["DialogStopEmulationTitle"],
LocaleManager.Instance["DialogStopEmulationMessage"],
LocaleManager.Instance["DialogExitSubMessage"]);
}
internal static async Task<string> CreateInputDialog(
string title,
string mainText,
string subText,
StyleableWindow owner,
uint maxLength = int.MaxValue,
string input = "")
{
var result = await InputDialog.ShowInputDialog(
owner,
title,
mainText,
input,
subText,
maxLength);
if (result.Result == UserResult.Ok)
{
return result.Input;
}
return string.Empty;
}
}
}

View file

@ -0,0 +1,188 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.Ui.Controls.GameGridView">
<UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
<MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened">
<MenuItem
Command="{Binding ToggleFavorite}"
Header="{locale:Locale GameListContextMenuToggleFavorite}"
ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
<Separator />
<MenuItem
Command="{Binding OpenUserSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenDeviceSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserDeviceDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserDeviceDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenBcatSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserBcatDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserBcatDirectoryToolTip}" />
<Separator />
<MenuItem
Command="{Binding OpenTitleUpdateManager}"
Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
<MenuItem
Command="{Binding OpenDlcManager}"
Header="{locale:Locale GameListContextMenuManageDlc}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
<MenuItem
Command="{Binding OpenCheatManager}"
Header="{locale:Locale GameListContextMenuManageCheat}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
<MenuItem
Command="{Binding OpenModsDirectory}"
Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenSdModsDirectory}"
Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
<Separator />
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
<MenuItem
Command="{Binding PurgePtcCache}"
Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
<MenuItem
Command="{Binding PurgeShaderCache}"
Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
<MenuItem
Command="{Binding OpenPtcDirectory}"
Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenShaderCacheDirectory}"
Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
</MenuItem>
<MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
<MenuItem
Command="{Binding ExtractExeFs}"
Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
<MenuItem
Command="{Binding ExtractRomFs}"
Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
<MenuItem
Command="{Binding ExtractLogo}"
Header="{locale:Locale GameListContextMenuExtractDataLogo}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
</MenuItem>
</MenuFlyout>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0"
Padding="8"
HorizontalAlignment="Stretch"
DoubleTapped="GameList_DoubleTapped"
SelectionChanged="GameList_SelectionChanged"
ContextFlyout="{StaticResource GameContextMenu}"
VerticalAlignment="Stretch"
Items="{Binding AppsObservableList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<flex:FlexPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" JustifyContent="Center"
AlignContent="FlexStart" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="5" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="Background" Value="{DynamicResource SystemAccentColorDark3}" />
<Style.Animations>
<Animation Duration="0:0:0.7">
<KeyFrame Cue="0%">
<Setter Property="MaxWidth" Value="0"/>
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="MaxWidth" Value="1000"/>
<Setter Property="Opacity" Value="0.3"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="MaxWidth" Value="1000"/>
<Setter Property="Opacity" Value="1.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.Styles>
<Style Selector="ui|SymbolIcon.small.icon">
<Setter Property="FontSize" Value="15" />
</Style>
<Style Selector="ui|SymbolIcon.normal.icon">
<Setter Property="FontSize" Value="19" />
</Style>
<Style Selector="ui|SymbolIcon.large.icon">
<Setter Property="FontSize" Value="23" />
</Style>
<Style Selector="ui|SymbolIcon.huge.icon">
<Setter Property="FontSize" Value="26" />
</Style>
</Grid.Styles>
<Border
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
HorizontalAlignment="Stretch"
Padding="{Binding $parent[UserControl].DataContext.GridItemPadding}" CornerRadius="5"
VerticalAlignment="Stretch" Margin="0" ClipToBounds="True">
<Grid Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0" Grid.Row="0"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
<StackPanel IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}"
Height="50" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Margin="5" Grid.Row="1">
<TextBlock Text="{Binding TitleName}" TextAlignment="Center" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
</StackPanel>
</Grid>
</Border>
<ui:SymbolIcon Classes.icon="true" Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
Foreground="Yellow" Symbol="StarFilled"
IsVisible="{Binding Favorite}" Margin="5" VerticalAlignment="Top"
HorizontalAlignment="Left" />
<ui:SymbolIcon Classes.icon="true" Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
Foreground="Black" Symbol="Star"
IsVisible="{Binding Favorite}" Margin="5" VerticalAlignment="Top"
HorizontalAlignment="Left" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

View file

@ -0,0 +1,82 @@
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using LibHac.Common;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.Ui.App.Common;
using System;
namespace Ryujinx.Ava.Ui.Controls
{
public partial class GameGridView : UserControl
{
private ApplicationData _selectedApplication;
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
RoutedEvent.Register<GameGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
{
add { AddHandler(ApplicationOpenedEvent, value); }
remove { RemoveHandler(ApplicationOpenedEvent, value); }
}
public void GameList_DoubleTapped(object sender, RoutedEventArgs args)
{
if (sender is ListBox listBox)
{
if (listBox.SelectedItem is ApplicationData selected)
{
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
}
}
}
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
{
if (sender is ListBox listBox)
{
var selected = listBox.SelectedItem as ApplicationData;
_selectedApplication = selected;
}
}
public ApplicationData SelectedApplication => _selectedApplication;
public GameGridView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
{
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
}
private void MenuBase_OnMenuOpened(object sender, EventArgs e)
{
var selection = SelectedApplication;
if (selection != null)
{
if (sender is ContextMenu menu)
{
bool canHaveUserSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.UserAccountSaveDataSize > 0;
bool canHaveDeviceSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.DeviceSaveDataSize > 0;
bool canHaveBcatSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
((menu.Items as AvaloniaList<object>)[2] as MenuItem).IsEnabled = canHaveUserSave;
((menu.Items as AvaloniaList<object>)[3] as MenuItem).IsEnabled = canHaveDeviceSave;
((menu.Items as AvaloniaList<object>)[4] as MenuItem).IsEnabled = canHaveBcatSave;
}
}
}
}
}

View file

@ -0,0 +1,188 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.Ui.Controls.GameListView">
<UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
<MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened">
<MenuItem
Command="{Binding ToggleFavorite}"
Header="{locale:Locale GameListContextMenuToggleFavorite}"
ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
<Separator />
<MenuItem
Command="{Binding OpenUserSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenDeviceSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserDeviceDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserDeviceDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenBcatSaveDirectory}"
Header="{locale:Locale GameListContextMenuOpenUserBcatDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserBcatDirectoryToolTip}" />
<Separator />
<MenuItem
Command="{Binding OpenTitleUpdateManager}"
Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
<MenuItem
Command="{Binding OpenDlcManager}"
Header="{locale:Locale GameListContextMenuManageDlc}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
<MenuItem
Command="{Binding OpenCheatManager}"
Header="{locale:Locale GameListContextMenuManageCheat}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
<MenuItem
Command="{Binding OpenModsDirectory}"
Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenSdModsDirectory}"
Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
<Separator />
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
<MenuItem
Command="{Binding PurgePtcCache}"
Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
<MenuItem
Command="{Binding PurgeShaderCache}"
Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
<MenuItem
Command="{Binding OpenPtcDirectory}"
Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
<MenuItem
Command="{Binding OpenShaderCacheDirectory}"
Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
</MenuItem>
<MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
<MenuItem
Command="{Binding ExtractExeFs}"
Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
<MenuItem
Command="{Binding ExtractRomFs}"
Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
<MenuItem
Command="{Binding ExtractLogo}"
Header="{locale:Locale GameListContextMenuExtractDataLogo}"
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
</MenuItem>
</MenuFlyout>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0"
Padding="8"
HorizontalAlignment="Stretch"
DoubleTapped="GameList_DoubleTapped"
SelectionChanged="GameList_SelectionChanged"
ContextFlyout="{StaticResource GameContextMenu}"
VerticalAlignment="Stretch"
Name="GameListBox"
Items="{Binding AppsObservableList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Vertical" Spacing="2" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColorDark3}" />
<Setter Property="BorderThickness" Value="2" />
<Style.Animations>
<Animation Duration="0:0:0.7">
<KeyFrame Cue="0%">
<Setter Property="MaxHeight" Value="0"/>
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="50%">
<Setter Property="MaxHeight" Value="1000"/>
<Setter Property="Opacity" Value="0.3"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="MaxHeight" Value="1000"/>
<Setter Property="Opacity" Value="1.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border HorizontalAlignment="Stretch"
Padding="10" CornerRadius="5"
VerticalAlignment="Stretch" Margin="0" ClipToBounds="True">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Image
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
Grid.RowSpan="3" Grid.Column="0" Margin="0"
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
<StackPanel Orientation="Vertical" Spacing="5" VerticalAlignment="Top" HorizontalAlignment="Left"
Grid.Column="2">
<TextBlock Text="{Binding TitleName}" TextAlignment="Left" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
<TextBlock Text="{Binding Developer}" TextAlignment="Left" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
<TextBlock Text="{Binding Version}" TextAlignment="Left" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
</StackPanel>
<StackPanel Orientation="Vertical" Spacing="5" VerticalAlignment="Top" HorizontalAlignment="Right"
Grid.Column="3">
<TextBlock Text="{Binding TimePlayed}" TextAlignment="Right" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
<TextBlock Text="{Binding LastPlayed}" TextAlignment="Right" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
<TextBlock Text="{Binding FileSize}" TextAlignment="Right" TextWrapping="Wrap"
HorizontalAlignment="Stretch" />
</StackPanel>
<ui:SymbolIcon Grid.Row="0" Grid.Column="0" FontSize="20"
Foreground="Yellow"
Symbol="StarFilled"
IsVisible="{Binding Favorite}" Margin="-5, -5, 0, 0" VerticalAlignment="Top"
HorizontalAlignment="Left" />
<ui:SymbolIcon Grid.Row="0" Grid.Column="0" FontSize="20"
Foreground="Black"
Symbol="Star"
IsVisible="{Binding Favorite}" Margin="-5, -5, 0, 0" VerticalAlignment="Top"
HorizontalAlignment="Left" />
</Grid>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

View file

@ -0,0 +1,82 @@
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using LibHac.Common;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.Ui.App.Common;
using System;
namespace Ryujinx.Ava.Ui.Controls
{
public partial class GameListView : UserControl
{
private ApplicationData _selectedApplication;
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
RoutedEvent.Register<GameGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
{
add { AddHandler(ApplicationOpenedEvent, value); }
remove { RemoveHandler(ApplicationOpenedEvent, value); }
}
public void GameList_DoubleTapped(object sender, RoutedEventArgs args)
{
if (sender is ListBox listBox)
{
if (listBox.SelectedItem is ApplicationData selected)
{
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
}
}
}
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
{
if (sender is ListBox listBox)
{
var selected = listBox.SelectedItem as ApplicationData;
_selectedApplication = selected;
}
}
public ApplicationData SelectedApplication => _selectedApplication;
public GameListView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
{
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
}
private void MenuBase_OnMenuOpened(object sender, EventArgs e)
{
var selection = SelectedApplication;
if (selection != null)
{
if (sender is ContextMenu menu)
{
bool canHaveUserSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.UserAccountSaveDataSize > 0;
bool canHaveDeviceSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.DeviceSaveDataSize > 0;
bool canHaveBcatSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
((menu.Items as AvaloniaList<object>)[2] as MenuItem).IsEnabled = canHaveUserSave;
((menu.Items as AvaloniaList<object>)[3] as MenuItem).IsEnabled = canHaveDeviceSave;
((menu.Items as AvaloniaList<object>)[4] as MenuItem).IsEnabled = canHaveBcatSave;
}
}
}
}
}

View file

@ -0,0 +1,9 @@
namespace Ryujinx.Ava.Ui.Controls
{
public enum Glyph : int
{
List,
Grid,
Chip
}
}

View file

@ -0,0 +1,49 @@
using Avalonia.Data;
using Avalonia.Markup.Xaml;
using FluentAvalonia.UI.Controls;
using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.Ui.Controls
{
public class GlyphValueConverter : MarkupExtension
{
private string _key;
private static Dictionary<Glyph, string> _glyphs = new Dictionary<Glyph, string>
{
{ Glyph.List, char.ConvertFromUtf32((int)Symbol.List).ToString() },
{ Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll).ToString() },
{ Glyph.Chip, char.ConvertFromUtf32(59748).ToString() }
};
public GlyphValueConverter(string key)
{
_key = key;
}
public string this[string key]
{
get
{
if (_glyphs.TryGetValue(Enum.Parse<Glyph>(key), out var val))
{
return val;
}
return string.Empty;
}
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension binding = new($"[{_key}]")
{
Mode = BindingMode.OneWay,
Source = this
};
return binding.ProvideValue(serviceProvider);
}
}
}

View file

@ -0,0 +1,52 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using System;
using System.Windows.Input;
namespace Ryujinx.Ava.Ui.Controls
{
public class HotKeyControl : ContentControl, ICommandSource
{
public static readonly StyledProperty<object> CommandParameterProperty =
AvaloniaProperty.Register<HotKeyControl, object>(nameof(CommandParameter));
public static readonly DirectProperty<HotKeyControl, ICommand> CommandProperty =
AvaloniaProperty.RegisterDirect<HotKeyControl, ICommand>(nameof(Command),
control => control.Command, (control, command) => control.Command = command, enableDataValidation: true);
public static readonly StyledProperty<KeyGesture> HotKeyProperty = HotKeyManager.HotKeyProperty.AddOwner<Button>();
private ICommand _command;
private bool _commandCanExecute;
public ICommand Command
{
get { return _command; }
set { SetAndRaise(CommandProperty, ref _command, value); }
}
public KeyGesture HotKey
{
get { return GetValue(HotKeyProperty); }
set { SetValue(HotKeyProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public void CanExecuteChanged(object sender, EventArgs e)
{
var canExecute = Command == null || Command.CanExecute(CommandParameter);
if (canExecute != _commandCanExecute)
{
_commandCanExecute = canExecute;
UpdateIsEffectivelyEnabled();
}
}
}
}

View file

@ -0,0 +1,25 @@
using Avalonia.OpenGL;
using SPB.Graphics.OpenGL;
using System;
namespace Ryujinx.Ava.Ui.Controls
{
public static class IGlContextExtension
{
public static OpenGLContextBase AsOpenGLContextBase(this IGlContext context)
{
var handle = (IntPtr)context.GetType().GetProperty("Handle").GetValue(context);
if (OperatingSystem.IsWindows())
{
return new AvaloniaWglContext(handle);
}
else if (OperatingSystem.IsLinux())
{
return new AvaloniaGlxContext(handle);
}
return null;
}
}
}

View file

@ -0,0 +1,18 @@
<UserControl xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.Ui.Controls.InputDialog">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="5,10,5, 5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" Text="{Binding Message}" />
<TextBox MaxLength="{Binding MaxLength}" Grid.Row="1" Margin="10" Width="300" HorizontalAlignment="Center"
Text="{Binding Input, Mode=TwoWay}" />
<TextBlock Grid.Row="2" Margin="5, 5, 5, 10" HorizontalAlignment="Center" Text="{Binding SubMessage}" />
</Grid>
</UserControl>

View file

@ -0,0 +1,67 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.Windows;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls
{
public class InputDialog : UserControl
{
public string Message { get; set; }
public string Input { get; set; }
public string SubMessage { get; set; }
public uint MaxLength { get; }
public InputDialog(string message, string input = "", string subMessage = "", uint maxLength = int.MaxValue)
{
Message = message;
Input = input;
SubMessage = subMessage;
MaxLength = maxLength;
DataContext = this;
InitializeComponent();
}
public InputDialog()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
public static async Task<(UserResult Result, string Input)> ShowInputDialog(StyleableWindow window, string title, string message, string input = "", string subMessage = "", uint maxLength = int.MaxValue)
{
ContentDialog contentDialog = window.ContentDialog;
UserResult result = UserResult.Cancel;
InputDialog content = new InputDialog(message, input = "", subMessage = "", maxLength);
if (contentDialog != null)
{
contentDialog.Title = title;
contentDialog.PrimaryButtonText = LocaleManager.Instance["InputDialogOk"];
contentDialog.SecondaryButtonText = "";
contentDialog.CloseButtonText = LocaleManager.Instance["InputDialogCancel"];
contentDialog.Content = content;
contentDialog.PrimaryButtonCommand = MiniCommand.Create(() =>
{
result = UserResult.Ok;
input = content.Input;
});
await contentDialog.ShowAsync();
}
return (result, input);
}
}
}

View file

@ -0,0 +1,46 @@
using Avalonia.Data.Converters;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using System;
using System.Globalization;
namespace Ryujinx.Ava.Ui.Controls
{
public class KeyValueConverter : IValueConverter
{
public static KeyValueConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
object key = null;
if (value != null)
{
if (targetType == typeof(Key))
{
key = Enum.Parse<Key>(value.ToString());
}
else if (targetType == typeof(GamepadInputId))
{
key = Enum.Parse<GamepadInputId>(value.ToString());
}
else if (targetType == typeof(StickInputId))
{
key = Enum.Parse<StickInputId>(value.ToString());
}
}
return key;
}
}
}

View file

@ -0,0 +1,71 @@
using System;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Ryujinx.Ava.Ui.Models
{
public sealed class MiniCommand<T> : MiniCommand, ICommand
{
private readonly Action<T> _callback;
private bool _busy;
private Func<T, Task> _asyncCallback;
public MiniCommand(Action<T> callback)
{
_callback = callback;
}
public MiniCommand(Func<T, Task> callback)
{
_asyncCallback = callback;
}
private bool Busy
{
get => _busy;
set
{
_busy = value;
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
public override event EventHandler CanExecuteChanged;
public override bool CanExecute(object parameter) => !_busy;
public override async void Execute(object parameter)
{
if (Busy)
{
return;
}
try
{
Busy = true;
if (_callback != null)
{
_callback((T)parameter);
}
else
{
await _asyncCallback((T)parameter);
}
}
finally
{
Busy = false;
}
}
}
public abstract class MiniCommand : ICommand
{
public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
public abstract bool CanExecute(object parameter);
public abstract void Execute(object parameter);
public abstract event EventHandler CanExecuteChanged;
}
}

View file

@ -0,0 +1,40 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
namespace Ryujinx.Ava.Ui.Controls
{
public class OffscreenTextBox : TextBox
{
public RoutedEvent<KeyEventArgs> GetKeyDownRoutedEvent()
{
return KeyDownEvent;
}
public RoutedEvent<KeyEventArgs> GetKeyUpRoutedEvent()
{
return KeyUpEvent;
}
public void SendKeyDownEvent(KeyEventArgs keyEvent)
{
OnKeyDown(keyEvent);
}
public void SendKeyUpEvent(KeyEventArgs keyEvent)
{
OnKeyUp(keyEvent);
}
public void SendText(string text)
{
OnTextInput(new TextInputEventArgs()
{
Text = text,
Device = KeyboardDevice.Instance,
Source = this,
RoutedEvent = TextInputEvent
});
}
}
}

View file

@ -0,0 +1,20 @@
using OpenTK;
using System;
namespace Ryujinx.Ava.Ui.Controls
{
public class OpenToolkitBindingsContext : IBindingsContext
{
private readonly Func<string, IntPtr> _getProcAddress;
public OpenToolkitBindingsContext(Func<string, IntPtr> getProcAddress)
{
_getProcAddress = getProcAddress;
}
public IntPtr GetProcAddress(string procName)
{
return _getProcAddress(procName);
}
}
}

View file

@ -0,0 +1,100 @@
using Avalonia.Rendering;
using System;
using System.Threading;
using System.Timers;
namespace Ryujinx.Ava.Ui.Controls
{
internal class RenderTimer : IRenderTimer, IDisposable
{
public event Action<TimeSpan> Tick
{
add
{
_tick += value;
if (_subscriberCount++ == 0)
{
Start();
}
}
remove
{
if (--_subscriberCount == 0)
{
Stop();
}
_tick -= value;
}
}
private Thread _tickThread;
private readonly System.Timers.Timer _timer;
private Action<TimeSpan> _tick;
private int _subscriberCount;
private bool _isRunning;
private AutoResetEvent _resetEvent;
public RenderTimer()
{
_timer = new System.Timers.Timer(15);
_resetEvent = new AutoResetEvent(true);
_timer.Elapsed += Timer_Elapsed;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
TickNow();
}
public void Start()
{
_timer.Start();
if (_tickThread == null)
{
_tickThread = new Thread(RunTick);
_tickThread.Name = "RenderTimerTickThread";
_tickThread.IsBackground = true;
_isRunning = true;
_tickThread.Start();
}
}
public void RunTick()
{
while (_isRunning)
{
_resetEvent.WaitOne();
_tick?.Invoke(TimeSpan.FromMilliseconds(Environment.TickCount));
}
}
public void TickNow()
{
lock (_timer)
{
_resetEvent.Set();
}
}
public void Stop()
{
_timer.Stop();
}
public void Dispose()
{
_timer.Elapsed -= Timer_Elapsed;
_timer.Stop();
_isRunning = false;
_resetEvent.Set();
_tickThread.Join();
_resetEvent.Dispose();
}
}
}

View file

@ -0,0 +1,273 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Media;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph;
using Avalonia.Skia;
using Avalonia.Threading;
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Configuration;
using SkiaSharp;
using SPB.Graphics;
using SPB.Graphics.OpenGL;
using SPB.Platform;
using SPB.Windowing;
using System;
namespace Ryujinx.Ava.Ui.Controls
{
public class RendererControl : Control
{
private int _image;
static RendererControl()
{
AffectsRender<RendererControl>(ImageProperty);
}
public readonly static StyledProperty<int> ImageProperty =
AvaloniaProperty.Register<RendererControl, int>(nameof(Image), 0, inherits: true, defaultBindingMode: BindingMode.TwoWay);
protected int Image
{
get => _image;
set => SetAndRaise(ImageProperty, ref _image, value);
}
public event EventHandler<EventArgs> GlInitialized;
public event EventHandler<Size> SizeChanged;
protected Size RenderSize { get; private set; }
public bool IsStarted { get; private set; }
public int Major { get; }
public int Minor { get; }
public GraphicsDebugLevel DebugLevel { get; }
public OpenGLContextBase GameContext { get; set; }
public static OpenGLContextBase PrimaryContext => AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>().PrimaryContext.AsOpenGLContextBase();
private SwappableNativeWindowBase _gameBackgroundWindow;
private bool _isInitialized;
private IntPtr _fence;
private GlDrawOperation _glDrawOperation;
public RendererControl(int major, int minor, GraphicsDebugLevel graphicsDebugLevel)
{
Major = major;
Minor = minor;
DebugLevel = graphicsDebugLevel;
IObservable<Rect> resizeObservable = this.GetObservable(BoundsProperty);
resizeObservable.Subscribe(Resized);
Focusable = true;
}
private void Resized(Rect rect)
{
SizeChanged?.Invoke(this, rect.Size);
RenderSize = rect.Size * Program.WindowScaleFactor;
_glDrawOperation?.Dispose();
_glDrawOperation = new GlDrawOperation(this);
}
public override void Render(DrawingContext context)
{
if (!_isInitialized)
{
CreateWindow();
OnGlInitialized();
_isInitialized = true;
}
if (GameContext == null || !IsStarted || Image == 0)
{
return;
}
if (_glDrawOperation != null)
{
context.Custom(_glDrawOperation);
}
base.Render(context);
}
protected void OnGlInitialized()
{
GlInitialized?.Invoke(this, EventArgs.Empty);
}
public void QueueRender()
{
Program.RenderTimer.TickNow();
}
internal void Present(object image)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
Image = (int)image;
}).Wait();
if (_fence != IntPtr.Zero)
{
GL.DeleteSync(_fence);
}
_fence = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None);
QueueRender();
_gameBackgroundWindow.SwapBuffers();
}
internal void Start()
{
IsStarted = true;
QueueRender();
}
internal void Stop()
{
IsStarted = false;
}
public void DestroyBackgroundContext()
{
_image = 0;
if (_fence != IntPtr.Zero)
{
_glDrawOperation.Dispose();
GL.DeleteSync(_fence);
}
GlDrawOperation.DeleteFramebuffer();
GameContext?.Dispose();
_gameBackgroundWindow?.Dispose();
}
internal void MakeCurrent()
{
GameContext.MakeCurrent(_gameBackgroundWindow);
}
internal void MakeCurrent(SwappableNativeWindowBase window)
{
GameContext.MakeCurrent(window);
}
protected void CreateWindow()
{
var flags = OpenGLContextFlags.Compat;
if (DebugLevel != GraphicsDebugLevel.None)
{
flags |= OpenGLContextFlags.Debug;
}
_gameBackgroundWindow = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100);
_gameBackgroundWindow.Hide();
GameContext = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, Major, Minor, flags, shareContext: PrimaryContext);
GameContext.Initialize(_gameBackgroundWindow);
}
private class GlDrawOperation : ICustomDrawOperation
{
private static int _framebuffer;
public Rect Bounds { get; }
private readonly RendererControl _control;
public GlDrawOperation(RendererControl control)
{
_control = control;
Bounds = _control.Bounds;
}
public void Dispose() { }
public static void DeleteFramebuffer()
{
if (_framebuffer == 0)
{
GL.DeleteFramebuffer(_framebuffer);
}
_framebuffer = 0;
}
public bool Equals(ICustomDrawOperation other)
{
return other is GlDrawOperation operation && Equals(this, operation) && operation.Bounds == Bounds;
}
public bool HitTest(Point p)
{
return Bounds.Contains(p);
}
private void CreateRenderTarget()
{
_framebuffer = GL.GenFramebuffer();
}
public void Render(IDrawingContextImpl context)
{
if (_control.Image == 0)
{
return;
}
if (_framebuffer == 0)
{
CreateRenderTarget();
}
int currentFramebuffer = GL.GetInteger(GetPName.FramebufferBinding);
var image = _control.Image;
var fence = _control._fence;
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebuffer);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, image, 0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, currentFramebuffer);
if (context is not ISkiaDrawingContextImpl skiaDrawingContextImpl)
{
return;
}
var imageInfo = new SKImageInfo((int)_control.RenderSize.Width, (int)_control.RenderSize.Height, SKColorType.Rgba8888);
var glInfo = new GRGlFramebufferInfo((uint)_framebuffer, SKColorType.Rgba8888.ToGlSizedFormat());
GL.WaitSync(fence, WaitSyncFlags.None, ulong.MaxValue);
using var backendTexture = new GRBackendRenderTarget(imageInfo.Width, imageInfo.Height, 1, 0, glInfo);
using var surface = SKSurface.Create(skiaDrawingContextImpl.GrContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
if (surface == null)
{
return;
}
var rect = new Rect(new Point(), _control.RenderSize);
using var snapshot = surface.Snapshot();
skiaDrawingContextImpl.SkCanvas.DrawImage(snapshot, rect.ToSKRect(), _control.Bounds.ToSKRect(), new SKPaint());
}
}
}
}

View file

@ -0,0 +1,47 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.OpenGL;
using SPB.Graphics;
using SPB.Graphics.OpenGL;
using SPB.Platform;
using SPB.Windowing;
namespace Ryujinx.Ava.Ui.Controls
{
class SPBOpenGLContext : IOpenGLContext
{
private OpenGLContextBase _context;
private NativeWindowBase _window;
private SPBOpenGLContext(OpenGLContextBase context, NativeWindowBase window)
{
_context = context;
_window = window;
}
public void Dispose()
{
_context.Dispose();
_window.Dispose();
}
public void MakeCurrent()
{
_context.MakeCurrent(_window);
}
public static SPBOpenGLContext CreateBackgroundContext(OpenGLContextBase sharedContext)
{
OpenGLContextBase context = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, 3, 3, OpenGLContextFlags.Compat, true, sharedContext);
NativeWindowBase window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100);
context.Initialize(window);
context.MakeCurrent(window);
GL.LoadBindings(new OpenToolkitBindingsContext(context.GetProcAddress));
context.MakeCurrent(null);
return new SPBOpenGLContext(context, window);
}
}
}

View file

@ -0,0 +1,28 @@
<Window xmlns="https://github.com/avaloniaui"
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:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.Ui.Controls.UpdateWaitWindow"
WindowStartupLocation="CenterOwner"
SizeToContent="WidthAndHeight"
Title="Ryujinx - Waiting">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Row="1" Margin="5, 10, 20 , 10" Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common"
Height="70"
MinWidth="50" />
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Orientation="Vertical">
<TextBlock Margin="5" Name="PrimaryText" />
<TextBlock VerticalAlignment="Center" Name="SecondaryText" Margin="5" />
</StackPanel>
</Grid>
</Window>

View file

@ -0,0 +1,35 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Ui.Windows;
namespace Ryujinx.Ava.Ui.Controls
{
public class UpdateWaitWindow : StyleableWindow
{
public UpdateWaitWindow(string primaryText, string secondaryText) : this()
{
PrimaryText.Text = primaryText;
SecondaryText.Text = secondaryText;
WindowStartupLocation = WindowStartupLocation.CenterOwner;
}
public UpdateWaitWindow()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
}
public TextBlock PrimaryText { get; private set; }
public TextBlock SecondaryText { get; private set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
PrimaryText = this.FindControl<TextBlock>("PrimaryText");
SecondaryText = this.FindControl<TextBlock>("SecondaryText");
}
}
}

View file

@ -0,0 +1,91 @@
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Windows;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Helper;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls
{
internal class UserErrorDialog
{
private const string SetupGuideUrl = "https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide";
private static string GetErrorCode(UserError error)
{
return $"RYU-{(uint)error:X4}";
}
private static string GetErrorTitle(UserError error)
{
return error switch
{
UserError.NoKeys => LocaleManager.Instance["UserErrorNoKeys"],
UserError.NoFirmware => LocaleManager.Instance["UserErrorNoFirmware"],
UserError.FirmwareParsingFailed => LocaleManager.Instance["UserErrorFirmwareParsingFailed"],
UserError.ApplicationNotFound => LocaleManager.Instance["UserErrorApplicationNotFound"],
UserError.Unknown => LocaleManager.Instance["UserErrorUnknown"],
_ => LocaleManager.Instance["UserErrorUndefined"]
};
}
private static string GetErrorDescription(UserError error)
{
return error switch
{
UserError.NoKeys => LocaleManager.Instance["UserErrorNoKeysDescription"],
UserError.NoFirmware => LocaleManager.Instance["UserErrorNoFirmwareDescription"],
UserError.FirmwareParsingFailed => LocaleManager.Instance["UserErrorFirmwareParsingFailedDescription"],
UserError.ApplicationNotFound => LocaleManager.Instance["UserErrorApplicationNotFoundDescription"],
UserError.Unknown => LocaleManager.Instance["UserErrorUnknownDescription"],
_ => LocaleManager.Instance["UserErrorUndefinedDescription"]
};
}
private static bool IsCoveredBySetupGuide(UserError error)
{
return error switch
{
UserError.NoKeys or
UserError.NoFirmware or
UserError.FirmwareParsingFailed => true,
_ => false
};
}
private static string GetSetupGuideUrl(UserError error)
{
if (!IsCoveredBySetupGuide(error))
{
return null;
}
return error switch
{
UserError.NoKeys => SetupGuideUrl + "#initial-setup---placement-of-prodkeys",
UserError.NoFirmware => SetupGuideUrl + "#initial-setup-continued---installation-of-firmware",
_ => SetupGuideUrl
};
}
public static async Task ShowUserErrorDialog(UserError error, StyleableWindow owner)
{
string errorCode = GetErrorCode(error);
bool isInSetupGuide = IsCoveredBySetupGuide(error);
string setupButtonLabel = isInSetupGuide ? LocaleManager.Instance["OpenSetupGuideMessage"] : "";
var result = await ContentDialogHelper.CreateInfoDialog(owner,
string.Format(LocaleManager.Instance["DialogUserErrorDialogMessage"], errorCode, GetErrorTitle(error)),
GetErrorDescription(error) + (isInSetupGuide
? LocaleManager.Instance["DialogUserErrorDialogInfoMessage"]
: ""), setupButtonLabel, LocaleManager.Instance["InputDialogOk"],
string.Format(LocaleManager.Instance["DialogUserErrorDialogTitle"], errorCode));
if (result == UserResult.Ok)
{
OpenHelper.OpenUrl(GetSetupGuideUrl(error));
}
}
}
}

View file

@ -0,0 +1,12 @@
namespace Ryujinx.Ava.Ui.Controls
{
public enum UserResult
{
Ok,
Yes,
No,
Abort,
Cancel,
None,
}
}

View file

@ -0,0 +1,45 @@
using Ryujinx.Ui.App.Common;
using System.Collections;
namespace Ryujinx.Ava.Ui.Models
{
public class FileSizeSortComparer : IComparer
{
public int Compare(object x, object y)
{
string aValue = (x as ApplicationData).TimePlayed;
string bValue = (y as ApplicationData).TimePlayed;
if (aValue[^2..] == "GB")
{
aValue = (float.Parse(aValue[0..^2]) * 1024).ToString();
}
else
{
aValue = aValue[0..^2];
}
if (bValue[^2..] == "GB")
{
bValue = (float.Parse(bValue[0..^2]) * 1024).ToString();
}
else
{
bValue = bValue[0..^2];
}
if (float.Parse(aValue) > float.Parse(bValue))
{
return -1;
}
else if (float.Parse(bValue) > float.Parse(aValue))
{
return 1;
}
else
{
return 0;
}
}
}
}

View file

@ -0,0 +1,50 @@
using Ryujinx.Ui.App.Common;
using System.Collections.Generic;
namespace Ryujinx.Ava.Ui.Models.Generic
{
public class FileSizeSortComparer : IComparer<ApplicationData>
{
public FileSizeSortComparer() { }
public FileSizeSortComparer(bool isAscending) { _order = isAscending ? 1 : -1; }
private int _order;
public int Compare(ApplicationData x, ApplicationData y)
{
string aValue = x.FileSize;
string bValue = y.FileSize;
if (aValue[^2..] == "GB")
{
aValue = (float.Parse(aValue[0..^2]) * 1024).ToString();
}
else
{
aValue = aValue[0..^2];
}
if (bValue[^2..] == "GB")
{
bValue = (float.Parse(bValue[0..^2]) * 1024).ToString();
}
else
{
bValue = bValue[0..^2];
}
if (float.Parse(aValue) > float.Parse(bValue))
{
return -1 * _order;
}
else if (float.Parse(bValue) > float.Parse(aValue))
{
return 1 * _order;
}
else
{
return 0;
}
}
}
}

View file

@ -0,0 +1,33 @@
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ui.App.Common;
using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.Ui.Models.Generic
{
public class LastPlayedSortComparer : IComparer<ApplicationData>
{
public LastPlayedSortComparer() { }
public LastPlayedSortComparer(bool isAscending) { IsAscending = isAscending; }
public bool IsAscending { get; }
public int Compare(ApplicationData x, ApplicationData y)
{
string aValue = x.LastPlayed;
string bValue = y.LastPlayed;
if (aValue == LocaleManager.Instance["Never"])
{
aValue = DateTime.UnixEpoch.ToString();
}
if (bValue == LocaleManager.Instance["Never"])
{
bValue = DateTime.UnixEpoch.ToString();
}
return (IsAscending ? 1 : -1) * DateTime.Compare(DateTime.Parse(bValue), DateTime.Parse(aValue));
}
}
}

View file

@ -0,0 +1,66 @@
using Ryujinx.Ui.App.Common;
using System.Collections.Generic;
namespace Ryujinx.Ava.Ui.Models.Generic
{
public class TimePlayedSortComparer : IComparer<ApplicationData>
{
public TimePlayedSortComparer() { }
public TimePlayedSortComparer(bool isAscending) { _order = isAscending ? 1 : -1; }
private int _order;
public int Compare(ApplicationData x, ApplicationData y)
{
string aValue = x.TimePlayed;
string bValue = y.TimePlayed;
if (aValue.Length > 4 && aValue[^4..] == "mins")
{
aValue = (float.Parse(aValue[0..^5]) * 60).ToString();
}
else if (aValue.Length > 3 && aValue[^3..] == "hrs")
{
aValue = (float.Parse(aValue[0..^4]) * 3600).ToString();
}
else if (aValue.Length > 4 && aValue[^4..] == "days")
{
aValue = (float.Parse(aValue[0..^5]) * 86400).ToString();
}
else
{
aValue = aValue[0..^1];
}
if (bValue.Length > 4 && bValue[^4..] == "mins")
{
bValue = (float.Parse(bValue[0..^5]) * 60).ToString();
}
else if (bValue.Length > 3 && bValue[^3..] == "hrs")
{
bValue = (float.Parse(bValue[0..^4]) * 3600).ToString();
}
else if (bValue.Length > 4 && bValue[^4..] == "days")
{
bValue = (float.Parse(bValue[0..^5]) * 86400).ToString();
}
else
{
bValue = bValue[0..^1];
}
if (float.Parse(aValue) > float.Parse(bValue))
{
return -1 * _order;
}
else if (float.Parse(bValue) > float.Parse(aValue))
{
return 1 * _order;
}
else
{
return 0;
}
}
}
}

View file

@ -0,0 +1,456 @@
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using System;
namespace Ryujinx.Ava.Ui.Models
{
public class InputConfiguration<Key, Stick> : BaseModel
{
private float _deadzoneRight;
private float _triggerThreshold;
private float _deadzoneLeft;
private double _gyroDeadzone;
private int _sensitivity;
private bool enableMotion;
private float weakRumble;
private float strongRumble;
private float _rangeLeft;
private float _rangeRight;
public InputBackendType Backend { get; set; }
/// <summary>
/// Controller id
/// </summary>
public string Id { get; set; }
/// <summary>
/// Controller's Type
/// </summary>
public ControllerType ControllerType { get; set; }
/// <summary>
/// Player's Index for the controller
/// </summary>
public PlayerIndex PlayerIndex { get; set; }
public Stick LeftJoystick { get; set; }
public bool LeftInvertStickX { get; set; }
public bool LeftInvertStickY { get; set; }
public bool RightRotate90 { get; set; }
public Key LeftControllerStickButton { get; set; }
public Stick RightJoystick { get; set; }
public bool RightInvertStickX { get; set; }
public bool RightInvertStickY { get; set; }
public bool LeftRotate90 { get; set; }
public Key RightControllerStickButton { get; set; }
public float DeadzoneLeft
{
get => _deadzoneLeft;
set
{
_deadzoneLeft = MathF.Round(value, 3);
OnPropertyChanged();
}
}
public float RangeLeft
{
get => _rangeLeft;
set
{
_rangeLeft = MathF.Round(value, 3);
OnPropertyChanged();
}
}
public float DeadzoneRight
{
get => _deadzoneRight;
set
{
_deadzoneRight = MathF.Round(value, 3);
OnPropertyChanged();
}
}
public float RangeRight
{
get => _rangeRight;
set
{
_rangeRight = MathF.Round(value, 3);
OnPropertyChanged();
}
}
public float TriggerThreshold
{
get => _triggerThreshold;
set
{
_triggerThreshold = MathF.Round(value, 3);
OnPropertyChanged();
}
}
public MotionInputBackendType MotionBackend { get; set; }
public Key ButtonMinus { get; set; }
public Key ButtonL { get; set; }
public Key ButtonZl { get; set; }
public Key LeftButtonSl { get; set; }
public Key LeftButtonSr { get; set; }
public Key DpadUp { get; set; }
public Key DpadDown { get; set; }
public Key DpadLeft { get; set; }
public Key DpadRight { get; set; }
public Key ButtonPlus { get; set; }
public Key ButtonR { get; set; }
public Key ButtonZr { get; set; }
public Key RightButtonSl { get; set; }
public Key RightButtonSr { get; set; }
public Key ButtonX { get; set; }
public Key ButtonB { get; set; }
public Key ButtonY { get; set; }
public Key ButtonA { get; set; }
public Key LeftStickUp { get; set; }
public Key LeftStickDown { get; set; }
public Key LeftStickLeft { get; set; }
public Key LeftStickRight { get; set; }
public Key LeftKeyboardStickButton { get; set; }
public Key RightStickUp { get; set; }
public Key RightStickDown { get; set; }
public Key RightStickLeft { get; set; }
public Key RightStickRight { get; set; }
public Key RightKeyboardStickButton { get; set; }
public int Sensitivity
{
get => _sensitivity;
set
{
_sensitivity = value;
OnPropertyChanged();
}
}
public double GyroDeadzone
{
get => _gyroDeadzone;
set
{
_gyroDeadzone = Math.Round(value, 3);
OnPropertyChanged();
}
}
public bool EnableMotion
{
get => enableMotion; set
{
enableMotion = value;
OnPropertyChanged();
}
}
public bool EnableCemuHookMotion { get; set; }
public int Slot { get; set; }
public int AltSlot { get; set; }
public bool MirrorInput { get; set; }
public string DsuServerHost { get; set; }
public int DsuServerPort { get; set; }
public bool EnableRumble { get; set; }
public float WeakRumble
{
get => weakRumble; set
{
weakRumble = value;
OnPropertyChanged();
}
}
public float StrongRumble
{
get => strongRumble; set
{
strongRumble = value;
OnPropertyChanged();
}
}
public InputConfiguration(InputConfig config)
{
if (config != null)
{
Backend = config.Backend;
Id = config.Id;
ControllerType = config.ControllerType;
PlayerIndex = config.PlayerIndex;
if (config is StandardKeyboardInputConfig keyboardConfig)
{
LeftStickUp = (Key)(object)keyboardConfig.LeftJoyconStick.StickUp;
LeftStickDown = (Key)(object)keyboardConfig.LeftJoyconStick.StickDown;
LeftStickLeft = (Key)(object)keyboardConfig.LeftJoyconStick.StickLeft;
LeftStickRight = (Key)(object)keyboardConfig.LeftJoyconStick.StickRight;
LeftKeyboardStickButton = (Key)(object)keyboardConfig.LeftJoyconStick.StickButton;
RightStickUp = (Key)(object)keyboardConfig.RightJoyconStick.StickUp;
RightStickDown = (Key)(object)keyboardConfig.RightJoyconStick.StickDown;
RightStickLeft = (Key)(object)keyboardConfig.RightJoyconStick.StickLeft;
RightStickRight = (Key)(object)keyboardConfig.RightJoyconStick.StickRight;
RightKeyboardStickButton = (Key)(object)keyboardConfig.RightJoyconStick.StickButton;
ButtonA = (Key)(object)keyboardConfig.RightJoycon.ButtonA;
ButtonB = (Key)(object)keyboardConfig.RightJoycon.ButtonB;
ButtonX = (Key)(object)keyboardConfig.RightJoycon.ButtonX;
ButtonY = (Key)(object)keyboardConfig.RightJoycon.ButtonY;
ButtonR = (Key)(object)keyboardConfig.RightJoycon.ButtonR;
RightButtonSl = (Key)(object)keyboardConfig.RightJoycon.ButtonSl;
RightButtonSr = (Key)(object)keyboardConfig.RightJoycon.ButtonSr;
ButtonZr = (Key)(object)keyboardConfig.RightJoycon.ButtonZr;
ButtonPlus = (Key)(object)keyboardConfig.RightJoycon.ButtonPlus;
DpadUp = (Key)(object)keyboardConfig.LeftJoycon.DpadUp;
DpadDown = (Key)(object)keyboardConfig.LeftJoycon.DpadDown;
DpadLeft = (Key)(object)keyboardConfig.LeftJoycon.DpadLeft;
DpadRight = (Key)(object)keyboardConfig.LeftJoycon.DpadRight;
ButtonMinus = (Key)(object)keyboardConfig.LeftJoycon.ButtonMinus;
LeftButtonSl = (Key)(object)keyboardConfig.LeftJoycon.ButtonSl;
LeftButtonSr = (Key)(object)keyboardConfig.LeftJoycon.ButtonSr;
ButtonZl = (Key)(object)keyboardConfig.LeftJoycon.ButtonZl;
ButtonL = (Key)(object)keyboardConfig.LeftJoycon.ButtonL;
}
else if (config is StandardControllerInputConfig controllerConfig)
{
LeftJoystick = (Stick)(object)controllerConfig.LeftJoyconStick.Joystick;
LeftInvertStickX = controllerConfig.LeftJoyconStick.InvertStickX;
LeftInvertStickY = controllerConfig.LeftJoyconStick.InvertStickY;
LeftRotate90 = controllerConfig.LeftJoyconStick.Rotate90CW;
LeftControllerStickButton = (Key)(object)controllerConfig.LeftJoyconStick.StickButton;
RightJoystick = (Stick)(object)controllerConfig.RightJoyconStick.Joystick;
RightInvertStickX = controllerConfig.RightJoyconStick.InvertStickX;
RightInvertStickY = controllerConfig.RightJoyconStick.InvertStickY;
RightRotate90 = controllerConfig.RightJoyconStick.Rotate90CW;
RightControllerStickButton = (Key)(object)controllerConfig.RightJoyconStick.StickButton;
ButtonA = (Key)(object)controllerConfig.RightJoycon.ButtonA;
ButtonB = (Key)(object)controllerConfig.RightJoycon.ButtonB;
ButtonX = (Key)(object)controllerConfig.RightJoycon.ButtonX;
ButtonY = (Key)(object)controllerConfig.RightJoycon.ButtonY;
ButtonR = (Key)(object)controllerConfig.RightJoycon.ButtonR;
RightButtonSl = (Key)(object)controllerConfig.RightJoycon.ButtonSl;
RightButtonSr = (Key)(object)controllerConfig.RightJoycon.ButtonSr;
ButtonZr = (Key)(object)controllerConfig.RightJoycon.ButtonZr;
ButtonPlus = (Key)(object)controllerConfig.RightJoycon.ButtonPlus;
DpadUp = (Key)(object)controllerConfig.LeftJoycon.DpadUp;
DpadDown = (Key)(object)controllerConfig.LeftJoycon.DpadDown;
DpadLeft = (Key)(object)controllerConfig.LeftJoycon.DpadLeft;
DpadRight = (Key)(object)controllerConfig.LeftJoycon.DpadRight;
ButtonMinus = (Key)(object)controllerConfig.LeftJoycon.ButtonMinus;
LeftButtonSl = (Key)(object)controllerConfig.LeftJoycon.ButtonSl;
LeftButtonSr = (Key)(object)controllerConfig.LeftJoycon.ButtonSr;
ButtonZl = (Key)(object)controllerConfig.LeftJoycon.ButtonZl;
ButtonL = (Key)(object)controllerConfig.LeftJoycon.ButtonL;
DeadzoneLeft = controllerConfig.DeadzoneLeft;
DeadzoneRight = controllerConfig.DeadzoneRight;
RangeLeft = controllerConfig.RangeLeft;
RangeRight = controllerConfig.RangeRight;
TriggerThreshold = controllerConfig.TriggerThreshold;
if (controllerConfig.Motion != null)
{
EnableMotion = controllerConfig.Motion.EnableMotion;
MotionBackend = controllerConfig.Motion.MotionBackend;
GyroDeadzone = controllerConfig.Motion.GyroDeadzone;
Sensitivity = controllerConfig.Motion.Sensitivity;
if (controllerConfig.Motion is CemuHookMotionConfigController cemuHook)
{
EnableCemuHookMotion = true;
DsuServerHost = cemuHook.DsuServerHost;
DsuServerPort = cemuHook.DsuServerPort;
Slot = cemuHook.Slot;
AltSlot = cemuHook.AltSlot;
MirrorInput = cemuHook.MirrorInput;
}
if (controllerConfig.Rumble != null)
{
EnableRumble = controllerConfig.Rumble.EnableRumble;
WeakRumble = controllerConfig.Rumble.WeakRumble;
StrongRumble = controllerConfig.Rumble.StrongRumble;
}
}
}
}
}
public InputConfiguration()
{
}
public InputConfig GetConfig()
{
if (Backend == InputBackendType.WindowKeyboard)
{
return new StandardKeyboardInputConfig()
{
Id = Id,
Backend = Backend,
PlayerIndex = PlayerIndex,
ControllerType = ControllerType,
LeftJoycon = new LeftJoyconCommonConfig<Ryujinx.Common.Configuration.Hid.Key>()
{
DpadUp = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadUp,
DpadDown = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadDown,
DpadLeft = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadLeft,
DpadRight = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadRight,
ButtonL = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonL,
ButtonZl = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonZl,
ButtonSl = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftButtonSl,
ButtonSr = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftButtonSr,
ButtonMinus = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonMinus
},
RightJoycon = new RightJoyconCommonConfig<Ryujinx.Common.Configuration.Hid.Key>()
{
ButtonA = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonA,
ButtonB = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonB,
ButtonX = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonX,
ButtonY = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonY,
ButtonPlus = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonPlus,
ButtonSl = (Ryujinx.Common.Configuration.Hid.Key)(object)RightButtonSl,
ButtonSr = (Ryujinx.Common.Configuration.Hid.Key)(object)RightButtonSr,
ButtonR = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonR,
ButtonZr = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonZr
},
LeftJoyconStick = new JoyconConfigKeyboardStick<Ryujinx.Common.Configuration.Hid.Key>()
{
StickUp = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickUp,
StickDown = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickDown,
StickRight = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickRight,
StickLeft = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickLeft,
StickButton = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftKeyboardStickButton
},
RightJoyconStick = new JoyconConfigKeyboardStick<Ryujinx.Common.Configuration.Hid.Key>()
{
StickUp = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickUp,
StickDown = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickDown,
StickLeft = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickLeft,
StickRight = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickRight,
StickButton = (Ryujinx.Common.Configuration.Hid.Key)(object)RightKeyboardStickButton
},
Version = InputConfig.CurrentVersion
};
}
else if (Backend == InputBackendType.GamepadSDL2)
{
var config = new StandardControllerInputConfig()
{
Id = Id,
Backend = Backend,
PlayerIndex = PlayerIndex,
ControllerType = ControllerType,
LeftJoycon = new LeftJoyconCommonConfig<GamepadInputId>()
{
DpadUp = (GamepadInputId)(object)DpadUp,
DpadDown = (GamepadInputId)(object)DpadDown,
DpadLeft = (GamepadInputId)(object)DpadLeft,
DpadRight = (GamepadInputId)(object)DpadRight,
ButtonL = (GamepadInputId)(object)ButtonL,
ButtonZl = (GamepadInputId)(object)ButtonZl,
ButtonSl = (GamepadInputId)(object)LeftButtonSl,
ButtonSr = (GamepadInputId)(object)LeftButtonSr,
ButtonMinus = (GamepadInputId)(object)ButtonMinus,
},
RightJoycon = new RightJoyconCommonConfig<GamepadInputId>()
{
ButtonA = (GamepadInputId)(object)ButtonA,
ButtonB = (GamepadInputId)(object)ButtonB,
ButtonX = (GamepadInputId)(object)ButtonX,
ButtonY = (GamepadInputId)(object)ButtonY,
ButtonPlus = (GamepadInputId)(object)ButtonPlus,
ButtonSl = (GamepadInputId)(object)RightButtonSl,
ButtonSr = (GamepadInputId)(object)RightButtonSr,
ButtonR = (GamepadInputId)(object)ButtonR,
ButtonZr = (GamepadInputId)(object)ButtonZr,
},
LeftJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>()
{
Joystick = (StickInputId)(object)LeftJoystick,
InvertStickX = LeftInvertStickX,
InvertStickY = LeftInvertStickY,
Rotate90CW = LeftRotate90,
StickButton = (GamepadInputId)(object)LeftControllerStickButton,
},
RightJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>()
{
Joystick = (StickInputId)(object)RightJoystick,
InvertStickX = RightInvertStickX,
InvertStickY = RightInvertStickY,
Rotate90CW = RightRotate90,
StickButton = (GamepadInputId)(object)RightControllerStickButton,
},
Rumble = new RumbleConfigController()
{
EnableRumble = EnableRumble,
WeakRumble = WeakRumble,
StrongRumble = StrongRumble
},
Version = InputConfig.CurrentVersion,
DeadzoneLeft = DeadzoneLeft,
DeadzoneRight = DeadzoneRight,
RangeLeft = RangeLeft,
RangeRight = RangeRight,
TriggerThreshold = TriggerThreshold,
Motion = EnableCemuHookMotion
? new CemuHookMotionConfigController()
{
DsuServerHost = DsuServerHost,
DsuServerPort = DsuServerPort,
Slot = Slot,
AltSlot = AltSlot,
MirrorInput = MirrorInput,
MotionBackend = MotionInputBackendType.CemuHook
}
: new StandardMotionConfigController()
{
MotionBackend = MotionInputBackendType.GamepadDriver
}
};
config.Motion.Sensitivity = Sensitivity;
config.Motion.EnableMotion = EnableMotion;
config.Motion.GyroDeadzone = GyroDeadzone;
return config;
}
return null;
}
}
}

View file

@ -0,0 +1,27 @@
using Ryujinx.Ui.App.Common;
using System;
using System.Collections;
namespace Ryujinx.Ava.Ui.Models
{
public class LastPlayedSortComparer : IComparer
{
public int Compare(object x, object y)
{
string aValue = (x as ApplicationData).LastPlayed;
string bValue = (y as ApplicationData).LastPlayed;
if (aValue == "Never")
{
aValue = DateTime.UnixEpoch.ToString();
}
if (bValue == "Never")
{
bValue = DateTime.UnixEpoch.ToString();
}
return DateTime.Compare(DateTime.Parse(bValue), DateTime.Parse(aValue));
}
}
}

View file

@ -0,0 +1,14 @@
namespace Ryujinx.Ava.Ui.Models
{
public class ProfileImageModel
{
public ProfileImageModel(string name, byte[] data)
{
Name = name;
Data = data;
}
public string Name { get; set; }
public byte[] Data { get; set; }
}
}

View file

@ -0,0 +1,26 @@
using System;
namespace Ryujinx.Ava.Ui.Models
{
public class StatusUpdatedEventArgs : EventArgs
{
public bool VSyncEnabled { get; }
public float Volume { get; }
public string AspectRatio { get; }
public string DockedMode { get; }
public string FifoStatus { get; }
public string GameStatus { get; }
public string GpuName { get; }
public StatusUpdatedEventArgs(bool vSyncEnabled, float volume, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, string gpuName)
{
VSyncEnabled = vSyncEnabled;
Volume = volume;
DockedMode = dockedMode;
AspectRatio = aspectRatio;
GameStatus = gameStatus;
FifoStatus = fifoStatus;
GpuName = gpuName;
}
}
}

View file

@ -0,0 +1,61 @@
using Ryujinx.Ui.App.Common;
using System.Collections;
namespace Ryujinx.Ava.Ui.Models
{
public class TimePlayedSortComparer : IComparer
{
public int Compare(object x, object y)
{
string aValue = (x as ApplicationData).TimePlayed;
string bValue = (y as ApplicationData).TimePlayed;
if (aValue.Length > 4 && aValue[^4..] == "mins")
{
aValue = (float.Parse(aValue[0..^5]) * 60).ToString();
}
else if (aValue.Length > 3 && aValue[^3..] == "hrs")
{
aValue = (float.Parse(aValue[0..^4]) * 3600).ToString();
}
else if (aValue.Length > 4 && aValue[^4..] == "days")
{
aValue = (float.Parse(aValue[0..^5]) * 86400).ToString();
}
else
{
aValue = aValue[0..^1];
}
if (bValue.Length > 4 && bValue[^4..] == "mins")
{
bValue = (float.Parse(bValue[0..^5]) * 60).ToString();
}
else if (bValue.Length > 3 && bValue[^3..] == "hrs")
{
bValue = (float.Parse(bValue[0..^4]) * 3600).ToString();
}
else if (bValue.Length > 4 && bValue[^4..] == "days")
{
bValue = (float.Parse(bValue[0..^5]) * 86400).ToString();
}
else
{
bValue = bValue[0..^1];
}
if (float.Parse(aValue) > float.Parse(bValue))
{
return -1;
}
else if (float.Parse(bValue) > float.Parse(aValue))
{
return 1;
}
else
{
return 0;
}
}
}
}

View file

@ -0,0 +1,22 @@
using LibHac.Ns;
using Ryujinx.Ava.Common.Locale;
namespace Ryujinx.Ava.Ui.Models
{
public class TitleUpdateModel
{
public bool IsEnabled { get; set; }
public bool IsNoUpdate { get; }
public ApplicationControlProperty Control { get; }
public string Path { get; }
public string Label => IsNoUpdate ? LocaleManager.Instance["NoUpdate"] :
string.Format(LocaleManager.Instance["TitleUpdateVersionLabel"], Control.DisplayVersionString.ToString(), Path);
public TitleUpdateModel(ApplicationControlProperty control, string path, bool isNoUpdate = false)
{
Control = control;
Path = path;
IsNoUpdate = isNoUpdate;
}
}
}

View file

@ -0,0 +1,15 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Ryujinx.Ava.Ui.ViewModels
{
public class BaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,163 @@
<window:StyleableWindow xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
x:Class="Ryujinx.Ava.Ui.Windows.AboutWindow"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
CanResize="False"
WindowStartupLocation="CenterOwner"
Width="850" MinHeight="550" Height="550"
SizeToContent="Width"
MinWidth="500"
Title="Ryujinx - About">
<Grid Margin="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Margin="20" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Margin="5, 10, 20 , 10"
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" Height="110" MinWidth="50" />
<TextBlock FontSize="35" TextAlignment="Center" Grid.Row="0" Grid.Column="1" Text="Ryujinx"
Margin="0,20,0,0" />
<TextBlock FontSize="16" TextAlignment="Center" Grid.Row="1" Grid.Column="1" Text="(REE-YOU-JINX)"
Margin="0,0,0,0" />
<Button Grid.Column="1" Background="Transparent" HorizontalAlignment="Center" Margin="0" Grid.Row="2"
Tag="https://www.ryujinx.org/"
Click="Button_OnClick">
<TextBlock ToolTip.Tip="{locale:Locale AboutUrlTooltipMessage}"
TextAlignment="Center" TextDecorations="Underline" Text="www.ryujinx.org" />
</Button>
</Grid>
<TextBlock TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"
Text="{Binding Version}" Grid.Row="1" />
<TextBlock Grid.Row="2" TextAlignment="Center" HorizontalAlignment="Center" Margin="20"
Text="{locale:Locale AboutDisclaimerMessage}"
MaxLines="2" />
<TextBlock Grid.Row="3" TextAlignment="Center" HorizontalAlignment="Center" Margin="20"
Text="{locale:Locale AboutAmiiboDisclaimerMessage}"
Name="AmiiboLabel"
PointerPressed="AmiiboLabel_OnPointerPressed"
MaxLines="2" />
<StackPanel Spacing="10" Orientation="Horizontal" Grid.Row="4" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical"
ToolTip.Tip="{locale:Locale AboutPatreonUrlTooltipMessage}">
<Button Height="65" Background="Transparent" Tag="https://www.patreon.com/ryujinx"
Click="Button_OnClick">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Patreon.png?assembly=Ryujinx.Ui.Common" />
<TextBlock Grid.Row="1" Margin="0,5,0,0" Text="Patreon" HorizontalAlignment="Center" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical"
ToolTip.Tip="{locale:Locale AboutGithubUrlTooltipMessage}">
<Button Height="65" Background="Transparent" Tag="https://github.com/Ryujinx/Ryujinx"
Click="Button_OnClick">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_GitHub.png?assembly=Ryujinx.Ui.Common" />
<TextBlock Grid.Row="1" Margin="0,5,0,0" Text="GitHub" HorizontalAlignment="Center" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical"
ToolTip.Tip="{locale:Locale AboutDiscordUrlTooltipMessage}">
<Button Height="65" Background="Transparent" Tag="https://discordapp.com/invite/N2FmfVc"
Click="Button_OnClick">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Discord.png?assembly=Ryujinx.Ui.Common" />
<TextBlock Grid.Row="1" Margin="0,5,0,0" Text="Discord" HorizontalAlignment="Center" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical"
ToolTip.Tip="{locale:Locale AboutTwitterUrlTooltipMessage}">
<Button Height="65" Background="Transparent" Tag="https://twitter.com/RyujinxEmu"
Click="Button_OnClick">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Twitter.png?assembly=Ryujinx.Ui.Common" />
<TextBlock Grid.Row="1" Margin="0,5,0,0" Text="Twitter" HorizontalAlignment="Center" />
</Grid>
</Button>
</StackPanel>
</StackPanel>
</Grid>
<Border Grid.Row="1" Grid.Column="1" VerticalAlignment="Stretch" Margin="5" Width="2" BorderBrush="White"
BorderThickness="1,0,0,0">
<Separator Width="0" />
</Border>
<Grid Grid.Row="1" Margin="20" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{locale:Locale AboutRyujinxAboutTitle}" FontWeight="Bold" TextDecorations="Underline" />
<TextBlock LineHeight="20" Grid.Row="1" Margin="20,5,5,5"
Text="{locale:Locale AboutRyujinxAboutContent}" />
<TextBlock Grid.Row="2" Margin="0,10,0,0" Text="{locale:Locale AboutRyujinxMaintainersTitle}"
FontWeight="Bold"
TextDecorations="Underline" />
<TextBlock LineHeight="20" Grid.Row="3" Margin="20,5,5,5"
Text="{Binding Developers}" />
<Button Background="Transparent" HorizontalAlignment="Right" Grid.Row="4"
Tag="https://github.com/Ryujinx/Ryujinx/graphs/contributors?type=a" Click="Button_OnClick">
<TextBlock ToolTip.Tip="{locale:Locale AboutRyujinxMaintainersContentTooltipMessage}"
TextAlignment="Right" TextDecorations="Underline"
Text="{locale:Locale AboutRyujinxContributorsButtonHeader}" />
</Button>
<TextBlock Grid.Row="5" Margin="0,0,0,0" Text="{locale:Locale AboutRyujinxSupprtersTitle}"
FontWeight="Bold"
TextDecorations="Underline" />
<Border Width="460" Grid.Row="6" VerticalAlignment="Stretch" Height="200" BorderThickness="1" Margin="20,5"
BorderBrush="White" Padding="5">
<TextBlock TextWrapping="Wrap" VerticalAlignment="Top" Name="SupportersTextBlock"
Text="{Binding Supporters}" />
</Border>
</Grid>
</Grid>
</window:StyleableWindow>

View file

@ -0,0 +1,92 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Utilities;
using Ryujinx.Ui.Common.Helper;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Windows
{
public class AboutWindow : StyleableWindow
{
public AboutWindow()
{
if (Program.PreviewerDetached)
{
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["MenuBarHelpAbout"];
}
Version = Program.Version;
DataContext = this;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
_ = DownloadPatronsJson();
}
public string Supporters { get; set; }
public string Version { get; set; }
public string Developers => string.Format(LocaleManager.Instance["AboutPageDeveloperListMore"], "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD«");
public TextBlock SupportersTextBlock { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
SupportersTextBlock = this.FindControl<TextBlock>("SupportersTextBlock");
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
if (sender is Button button)
{
OpenHelper.OpenUrl(button.Tag.ToString());
}
}
private async Task DownloadPatronsJson()
{
if (!NetworkInterface.GetIsNetworkAvailable())
{
Supporters = LocaleManager.Instance["ConnectionError"];
return;
}
HttpClient httpClient = new();
try
{
string patreonJsonString = await httpClient.GetStringAsync("https://patreon.ryujinx.org/");
Supporters = string.Join(", ", JsonHelper.Deserialize<string[]>(patreonJsonString));
}
catch
{
Supporters = LocaleManager.Instance["ApiError"];
}
await Dispatcher.UIThread.InvokeAsync(() => SupportersTextBlock.Text = Supporters);
}
private void AmiiboLabel_OnPointerPressed(object sender, PointerPressedEventArgs e)
{
if (sender is TextBlock)
{
OpenHelper.OpenUrl("https://amiiboapi.com");
}
}
}
}

View file

@ -0,0 +1,192 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.Ui.Windows
{
static class IconColorPicker
{
private const int ColorsPerLine = 64;
private const int TotalColors = ColorsPerLine * ColorsPerLine;
private const int UvQuantBits = 3;
private const int UvQuantShift = BitsPerComponent - UvQuantBits;
private const int SatQuantBits = 5;
private const int SatQuantShift = BitsPerComponent - SatQuantBits;
private const int BitsPerComponent = 8;
private const int CutOffLuminosity = 64;
private struct PaletteColor
{
public int Qck { get; }
public byte R { get; }
public byte G { get; }
public byte B { get; }
public PaletteColor(int qck, byte r, byte g, byte b)
{
Qck = qck;
R = r;
G = g;
B = b;
}
}
public static Color GetFilteredColor(Image<Bgra32> image)
{
var color = GetColor(image).ToPixel<Bgra32>();
// We don't want colors that are too dark.
// If the color is too dark, make it brighter by reducing the range
// and adding a constant color.
int luminosity = GetColorApproximateLuminosity(color.R, color.G, color.B);
if (luminosity < CutOffLuminosity)
{
color = Color.FromRgb(
(byte)Math.Min(CutOffLuminosity + color.R, byte.MaxValue),
(byte)Math.Min(CutOffLuminosity + color.G, byte.MaxValue),
(byte)Math.Min(CutOffLuminosity + color.B, byte.MaxValue));
}
return color;
}
public static Color GetColor(Image<Bgra32> image)
{
var colors = new PaletteColor[TotalColors];
var dominantColorBin = new Dictionary<int, int>();
var buffer = GetBuffer(image);
int w = image.Width;
int w8 = w << 8;
int h8 = image.Height << 8;
int xStep = w8 / ColorsPerLine;
int yStep = h8 / ColorsPerLine;
int i = 0;
int maxHitCount = 0;
for (int y = 0; y < image.Height; y++)
{
int yOffset = y * image.Width;
for (int x = 0; x < image.Width && i < TotalColors; x++)
{
int offset = x + yOffset;
byte cb = buffer[offset].B;
byte cg = buffer[offset].G;
byte cr = buffer[offset].R;
var qck = GetQuantizedColorKey(cr, cg, cb);
if (dominantColorBin.TryGetValue(qck, out int hitCount))
{
dominantColorBin[qck] = hitCount + 1;
if (maxHitCount < hitCount)
{
maxHitCount = hitCount;
}
}
else
{
dominantColorBin.Add(qck, 1);
}
colors[i++] = new PaletteColor(qck, cr, cg, cb);
}
}
int highScore = -1;
PaletteColor bestCandidate = default;
for (i = 0; i < TotalColors; i++)
{
var score = GetColorScore(dominantColorBin, maxHitCount, colors[i]);
if (highScore < score)
{
highScore = score;
bestCandidate = colors[i];
}
}
return Color.FromRgb(bestCandidate.R, bestCandidate.G, bestCandidate.B);
}
public static Bgra32[] GetBuffer(Image<Bgra32> image)
{
return image.TryGetSinglePixelSpan(out var data) ? data.ToArray() : new Bgra32[0];
}
private static int GetColorScore(Dictionary<int, int> dominantColorBin, int maxHitCount, PaletteColor color)
{
var hitCount = dominantColorBin[color.Qck];
var balancedHitCount = BalanceHitCount(hitCount, maxHitCount);
var quantSat = (GetColorSaturation(color) >> SatQuantShift) << SatQuantShift;
var value = GetColorValue(color);
// If the color is rarely used on the image,
// then chances are that theres a better candidate, even if the saturation value
// is high. By multiplying the saturation value with a weight, we can lower
// it if the color is almost never used (hit count is low).
var satWeighted = quantSat;
var satWeight = balancedHitCount << 5;
if (satWeight < 0x100)
{
satWeighted = (satWeighted * satWeight) >> 8;
}
// Compute score from saturation and dominance of the color.
// We prefer more vivid colors over dominant ones, so give more weight to the saturation.
var score = ((satWeighted << 1) + balancedHitCount) * value;
return score;
}
private static int BalanceHitCount(int hitCount, int maxHitCount)
{
return (hitCount << 8) / maxHitCount;
}
private static int GetColorApproximateLuminosity(byte r, byte g, byte b)
{
return (r + g + b) / 3;
}
private static int GetColorSaturation(PaletteColor color)
{
int cMax = Math.Max(Math.Max(color.R, color.G), color.B);
if (cMax == 0)
{
return 0;
}
int cMin = Math.Min(Math.Min(color.R, color.G), color.B);
int delta = cMax - cMin;
return (delta << 8) / cMax;
}
private static int GetColorValue(PaletteColor color)
{
return Math.Max(Math.Max(color.R, color.G), color.B);
}
private static int GetQuantizedColorKey(byte r, byte g, byte b)
{
int u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
int v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
return (v >> UvQuantShift) | ((u >> UvQuantShift) << UvQuantBits);
}
}
}

View file

@ -0,0 +1,639 @@
<window:StyleableWindow
x:Class="Ryujinx.Ava.Ui.Windows.MainWindow"
xmlns="https://github.com/avaloniaui"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:models="clr-namespace:Ryujinx.Ava.Ui.Models"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
Title="Ryujinx"
Height="785"
Width="1280"
d:DesignHeight="720"
d:DesignWidth="1280"
MinWidth="1024"
MinHeight="680"
WindowStartupLocation="CenterScreen"
x:CompileBindings="True"
x:DataType="viewModels:MainWindowViewModel"
mc:Ignorable="d">
<Window.Styles>
<Style Selector="TitleBar:fullscreen">
<Setter Property="Background" Value="#000000" />
</Style>
</Window.Styles>
<Design.DataContext>
<viewModels:MainWindowViewModel />
</Design.DataContext>
<Window.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
</Window.Resources>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:OffscreenTextBox Name="HiddenTextBox" Grid.Row="0" />
<ContentControl Grid.Row="1"
Focusable="False"
IsVisible="False"
KeyboardNavigation.IsTabStop="False">
<ui:ContentDialog Name="ContentDialog"
KeyboardNavigation.IsTabStop="False"
IsPrimaryButtonEnabled="True"
IsSecondaryButtonEnabled="True"
IsVisible="True" />
</ContentControl>
<StackPanel IsVisible="False" Grid.Row="0">
<controls:HotKeyControl Name="FullscreenHotKey" Command="{ReflectionBinding ToggleFullscreen}" />
<controls:HotKeyControl Name="FullscreenHotKey2" Command="{ReflectionBinding ToggleFullscreen}" />
<controls:HotKeyControl Name="DockToggleHotKey" Command="{ReflectionBinding ToggleDockMode}" />
<controls:HotKeyControl Name="ExitHotKey" Command="{ReflectionBinding ExitCurrentState}" />
</StackPanel>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Grid.Row="0"
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding ShowMenuAndStatusBar}"
Orientation="Vertical">
<DockPanel HorizontalAlignment="Stretch">
<Menu
Name="Menu"
Margin="0"
Height="35"
HorizontalAlignment="Left">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch" Margin="0" />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem
VerticalAlignment="Center"
Header="{locale:Locale MenuBarFile}">
<MenuItem IsEnabled="{Binding EnableNonGameRunningControls}"
Command="{ReflectionBinding OpenFile}"
Header="{locale:Locale MenuBarFileOpenFromFile}"
ToolTip.Tip="{locale:Locale LoadApplicationFileTooltip}" />
<MenuItem IsEnabled="{Binding EnableNonGameRunningControls}"
Command="{ReflectionBinding OpenFolder}"
Header="{locale:Locale MenuBarFileOpenUnpacked}"
ToolTip.Tip="{locale:Locale LoadApplicationFolderTooltip}" />
<MenuItem Header="{locale:Locale MenuBarFileOpenApplet}"
IsEnabled="{Binding IsAppletMenuActive}">
<MenuItem Command="{ReflectionBinding OpenMiiApplet}" Header="Mii Edit Applet"
ToolTip.Tip="{locale:Locale MenuBarFileOpenAppletOpenMiiAppletToolTip}" />
</MenuItem>
<Separator />
<MenuItem Command="{ReflectionBinding OpenRyujinxFolder}"
Header="{locale:Locale MenuBarFileOpenEmuFolder}"
ToolTip.Tip="{locale:Locale OpenRyujinxFolderTooltip}" />
<MenuItem Command="{ReflectionBinding OpenLogsFolder}"
Header="{locale:Locale MenuBarFileOpenLogsFolder}"
ToolTip.Tip="{locale:Locale OpenRyujinxLogsTooltip}" />
<Separator />
<MenuItem Command="{ReflectionBinding CloseWindow}"
Header="{locale:Locale MenuBarFileExit}"
ToolTip.Tip="{locale:Locale ExitTooltip}" />
</MenuItem>
<MenuItem
VerticalAlignment="Center"
Header="{locale:Locale MenuBarOptions}">
<MenuItem Command="{ReflectionBinding ToggleFullscreen}"
Header="{locale:Locale MenuBarOptionsToggleFullscreen}" InputGesture="F11" />
<MenuItem Header="{locale:Locale MenuBarOptionsStartGamesInFullscreen}">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding StartGamesInFullscreen, Mode=TwoWay}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="{locale:Locale MenuBarOptionsShowConsole}">
<MenuItem.Icon>
<CheckBox IsChecked="{Binding ShowConsole, Mode=TwoWay}" />
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="{locale:Locale MenuBarOptionsChangeLanguage}">
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="en_US"
Header="American English" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="pt_BR"
Header="Brazilian Portuguese" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="es_ES"
Header="Castilian Spanish" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="fr_FR"
Header="French" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="de_DE"
Header="German" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="el_GR"
Header="Greek" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="it_IT"
Header="Italian" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="ko_KR"
Header="Korean" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="ru_RU"
Header="Russian" />
<MenuItem Command="{ReflectionBinding ChangeLanguage}" CommandParameter="tr_TR"
Header="Turkish" />
</MenuItem>
<Separator />
<MenuItem Command="{ReflectionBinding OpenSettings}"
Header="{locale:Locale MenuBarOptionsSettings}"
ToolTip.Tip="{locale:Locale OpenSettingsTooltip}" />
<MenuItem Command="{ReflectionBinding ManageProfiles}"
IsEnabled="{Binding EnableNonGameRunningControls}"
Header="{locale:Locale MenuBarOptionsManageUserProfiles}"
ToolTip.Tip="{locale:Locale OpenProfileManagerTooltip}" />
</MenuItem>
<MenuItem
VerticalAlignment="Center"
Header="{locale:Locale MenuBarActions}"
Name="ActionsMenuItem"
IsEnabled="{Binding IsGameRunning}">
<MenuItem
Click="PauseEmulation_Click"
Header="{locale:Locale MenuBarOptionsPauseEmulation}"
IsEnabled="{Binding !IsPaused}"
IsVisible="{Binding !IsPaused}"
InputGesture="{Binding PauseKey}" />
<MenuItem
Click="ResumeEmulation_Click"
Header="{locale:Locale MenuBarOptionsResumeEmulation}"
IsEnabled="{Binding IsPaused}"
IsVisible="{Binding IsPaused}"
InputGesture="{Binding PauseKey}" />
<MenuItem
Click="StopEmulation_Click"
Header="{locale:Locale MenuBarOptionsStopEmulation}"
ToolTip.Tip="{locale:Locale StopEmulationTooltip}"
IsEnabled="{Binding IsGameRunning}" InputGesture="Escape" />
<MenuItem Command="{ReflectionBinding SimulateWakeUpMessage}"
Header="{locale:Locale MenuBarOptionsSimulateWakeUpMessage}" />
<Separator />
<MenuItem
Name="ScanAmiiboMenuItem"
AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree"
Command="{ReflectionBinding OpenAmiiboWindow}"
Header="{locale:Locale MenuBarActionsScanAmiibo}"
IsEnabled="{Binding IsAmiiboRequested}" />
<MenuItem Command="{ReflectionBinding TakeScreenshot}"
IsEnabled="{Binding IsGameRunning}"
Header="{locale:Locale MenuBarFileToolsTakeScreenshot}"
InputGesture="{Binding ScreenshotKey}" />
<MenuItem Command="{ReflectionBinding HideUi}"
IsEnabled="{Binding IsGameRunning}"
Header="{locale:Locale MenuBarFileToolsHideUi}"
InputGesture="{Binding ShowUiKey}" />
<MenuItem Command="{ReflectionBinding OpenCheatManagerForCurrentApp}"
IsEnabled="{Binding IsGameRunning}"
Header="{locale:Locale GameListContextMenuManageCheat}" />
</MenuItem>
<MenuItem
VerticalAlignment="Center"
Header="{locale:Locale MenuBarTools}">
<MenuItem Header="{locale:Locale MenuBarToolsInstallFirmware}"
IsEnabled="{Binding EnableNonGameRunningControls}">
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFile}"
Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromFile}" />
<MenuItem Command="{ReflectionBinding InstallFirmwareFromFolder}"
Header="{locale:Locale MenuBarFileToolsInstallFirmwareFromDirectory}" />
</MenuItem>
</MenuItem>
<MenuItem
VerticalAlignment="Center"
Header="{locale:Locale MenuBarHelp}">
<MenuItem
Name="UpdateMenuItem"
Command="{ReflectionBinding CheckForUpdates}"
Header="{locale:Locale MenuBarHelpCheckForUpdates}"
ToolTip.Tip="{locale:Locale CheckUpdatesTooltip}" />
<Separator />
<MenuItem Command="{ReflectionBinding OpenAboutWindow}"
Header="{locale:Locale MenuBarHelpAbout}"
ToolTip.Tip="{locale:Locale OpenAboutTooltip}" />
</MenuItem>
</Menu>
</DockPanel>
</StackPanel>
<ContentControl
Name="Content"
Grid.Row="1"
Padding="0"
IsVisible="{Binding ShowContent}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="0,0,0,0"
DockPanel.Dock="Top">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" HorizontalAlignment="Stretch" Margin="0,0,0,5">
<Button
IsEnabled="{Binding IsGrid}" VerticalAlignment="Stretch" MinWidth="40" Width="40"
Margin="5,2,0,2" Command="{ReflectionBinding SetListMode}">
<ui:FontIcon FontFamily="avares://FluentAvalonia/Fonts#Symbols"
VerticalAlignment="Center"
Margin="0"
Glyph="{controls:GlyphValueConverter List}"
HorizontalAlignment="Stretch" />
</Button>
<Button
IsEnabled="{Binding IsList}" VerticalAlignment="Stretch" MinWidth="40" Width="40"
Margin="5,2,5,2" Command="{ReflectionBinding SetGridMode}">
<ui:FontIcon FontFamily="avares://FluentAvalonia/Fonts#Symbols"
VerticalAlignment="Center"
Margin="0"
Glyph="{controls:GlyphValueConverter Grid}"
HorizontalAlignment="Stretch" />
</Button>
<TextBlock Text="{locale:Locale IconSize}"
VerticalAlignment="Center" Margin="10,0"
ToolTip.Tip="{locale:Locale IconSizeTooltip}" />
<Slider Width="150" Margin="5,-10,5 ,0" Height="35"
ToolTip.Tip="{locale:Locale IconSizeTooltip}"
VerticalAlignment="Center" Minimum="1" Maximum="4" IsSnapToTickEnabled="True"
TickFrequency="1" Value="{Binding GridSizeScale}" />
<CheckBox Margin="0" IsChecked="{Binding ShowNames, Mode=TwoWay}" VerticalAlignment="Center"
IsVisible="{Binding IsGrid}">
<TextBlock Text="{locale:Locale CommonShowNames}" Margin="5,3,0,0" />
</CheckBox>
<TextBox
Name="SearchBox"
DockPanel.Dock="Right"
VerticalAlignment="Center"
MinWidth="200"
Margin="5,0,5,0"
HorizontalAlignment="Right"
KeyUp="SearchBox_OnKeyUp"
Text="{Binding SearchText}"
Watermark="{locale:Locale MenuSearch}" />
<ui:DropDownButton DockPanel.Dock="Right"
HorizontalAlignment="Right" Width="150" VerticalAlignment="Center"
Content="{Binding SortName}">
<ui:DropDownButton.Flyout>
<Flyout Placement="Bottom">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Margin="0">
<StackPanel>
<RadioButton Tag="Favorite"
IsChecked="{Binding IsSortedByFavorite, Mode=OneTime}"
GroupName="Sort"
Content="{locale:Locale CommonFavorite}"
Checked="Sort_Checked" />
<RadioButton Tag="Title" GroupName="Sort"
IsChecked="{Binding IsSortedByTitle, Mode=OneTime}"
Content="{locale:Locale GameListHeaderApplication}"
Checked="Sort_Checked" />
<RadioButton Tag="Developer" GroupName="Sort"
IsChecked="{Binding IsSortedByDeveloper, Mode=OneTime}"
Content="{locale:Locale GameListHeaderDeveloper}"
Checked="Sort_Checked" />
<RadioButton Tag="TotalTimePlayed" GroupName="Sort"
IsChecked="{Binding IsSortedByTimePlayed, Mode=OneTime}"
Content="{locale:Locale GameListHeaderTimePlayed}"
Checked="Sort_Checked" />
<RadioButton Tag="LastPlayed" GroupName="Sort"
IsChecked="{Binding IsSortedByLastPlayed, Mode=OneTime}"
Content="{locale:Locale GameListHeaderLastPlayed}"
Checked="Sort_Checked" />
<RadioButton Tag="FileType" GroupName="Sort"
IsChecked="{Binding IsSortedByType, Mode=OneTime}"
Content="{locale:Locale GameListHeaderFileExtension}"
Checked="Sort_Checked" />
<RadioButton Tag="FileSize" GroupName="Sort"
IsChecked="{Binding IsSortedBySize, Mode=OneTime}"
Content="{locale:Locale GameListHeaderFileSize}"
Checked="Sort_Checked" />
<RadioButton Tag="Path" GroupName="Sort"
IsChecked="{Binding IsSortedByPath, Mode=OneTime}"
Content="{locale:Locale GameListHeaderPath}"
Checked="Sort_Checked" />
</StackPanel>
<Border HorizontalAlignment="Stretch" Margin="5" Height="2" BorderBrush="White"
Width="60" BorderThickness="0,1,0,0">
<Separator HorizontalAlignment="Stretch" Height="0" />
</Border>
<RadioButton Tag="Ascending" IsChecked="{Binding IsAscending, Mode=OneTime}"
GroupName="Order"
Content="{locale:Locale OrderAscending}" Checked="Order_Checked" />
<RadioButton Tag="Descending" GroupName="Order"
IsChecked="{Binding !IsAscending, Mode=OneTime}"
Content="{locale:Locale OrderDescending}" Checked="Order_Checked" />
</StackPanel>
</Flyout>
</ui:DropDownButton.Flyout>
</ui:DropDownButton>
<TextBlock DockPanel.Dock="Right" HorizontalAlignment="Right"
Text="{locale:Locale CommonSort}" VerticalAlignment="Center" Margin="10,0" />
</DockPanel>
<controls:GameListView
x:Name="GameList"
Grid.Row="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding IsList}" />
<controls:GameGridView
x:Name="GameGrid"
Grid.Row="1"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding IsGrid}" />
</Grid>
</ContentControl>
<Grid Grid.Row="1"
VerticalAlignment="Stretch"
Background="{DynamicResource ThemeContentBackgroundColor}"
IsVisible="{Binding ShowLoadProgress}"
ZIndex="1000"
HorizontalAlignment="Stretch">
<Grid
HorizontalAlignment="Center"
IsVisible="{Binding ShowLoadProgress}"
Margin="40"
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border
Grid.Column="0"
Grid.RowSpan="2"
IsVisible="{Binding ShowLoadProgress}"
Width="256"
Height="256"
Margin="10"
Padding="4"
BorderBrush="Black"
BorderThickness="2"
BoxShadow="4 4 32 8 #40000000"
CornerRadius="3">
<Image
IsVisible="{Binding ShowLoadProgress}"
Width="256"
Height="256"
Source="{Binding SelectedIcon, Converter={StaticResource ByteImage}}" />
</Border>
<Grid Grid.Column="1"
IsVisible="{Binding ShowLoadProgress}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
IsVisible="{Binding ShowLoadProgress}"
Grid.Row="0"
Margin="10"
FontSize="30"
FontWeight="Bold"
TextWrapping="Wrap"
Text="{Binding LoadHeading}"
TextAlignment="Left" />
<Border
IsVisible="{Binding ShowLoadProgress}"
Grid.Row="1"
CornerRadius="5"
ClipToBounds="True"
BorderBrush="{Binding ProgressBarBackgroundColor}"
Padding="0"
HorizontalAlignment="Stretch"
Margin="10"
BorderThickness="1">
<ProgressBar
IsVisible="{Binding ShowLoadProgress}"
Height="10"
Margin="0"
Padding="0"
CornerRadius="5"
ClipToBounds="True"
MinWidth="500"
HorizontalAlignment="Stretch"
Background="{Binding ProgressBarBackgroundColor}"
Foreground="{Binding ProgressBarForegroundColor}"
Maximum="{Binding ProgressMaximum}"
Minimum="0"
IsIndeterminate="{Binding IsLoadingIndeterminate}"
Value="{Binding ProgressValue}" />
</Border>
<TextBlock
IsVisible="{Binding ShowLoadProgress}"
Grid.Row="2"
Margin="10"
FontSize="18"
Text="{Binding CacheLoadStatus}"
TextAlignment="Left" />
</Grid>
</Grid>
</Grid>
<Grid
Name="StatusBar"
Grid.Row="2"
Height="30"
Margin="0,0"
HorizontalAlignment="Stretch"
Background="{DynamicResource ThemeContentBackgroundColor}"
VerticalAlignment="Bottom"
DockPanel.Dock="Bottom"
IsVisible="{Binding ShowMenuAndStatusBar}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" IsVisible="{Binding EnableNonGameRunningControls}"
VerticalAlignment="Center" Margin="10,0">
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
Width="25"
Height="25"
MinWidth="0"
Margin="0,0,5,0"
VerticalAlignment="Center"
Background="Transparent"
Command="{ReflectionBinding LoadApplications}">
<ui:SymbolIcon Symbol="Refresh" Height="100" Width="50" />
</Button>
<TextBlock
Name="LoadStatus"
Grid.Column="1"
Margin="0,0,5,0"
VerticalAlignment="Center"
IsVisible="{Binding EnableNonGameRunningControls}"
Text="{locale:Locale StatusBarGamesLoaded}" />
<ProgressBar
Name="LoadProgressBar"
Grid.Column="2"
Height="6"
Maximum="{Binding StatusBarProgressMaximum}"
Value="{Binding StatusBarProgressValue}"
VerticalAlignment="Center"
Foreground="{DynamicResource HighlightColor}"
IsVisible="{Binding EnableNonGameRunningControls}" />
</Grid>
</StackPanel>
<StackPanel
Grid.Column="1"
Margin="10,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsVisible="{Binding IsGameRunning}"
Orientation="Horizontal">
<TextBlock
Name="VsyncStatus"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{Binding VsyncColor}"
PointerReleased="VsyncStatus_PointerReleased"
IsVisible="{Binding !ShowLoadProgress}"
Margin="0,0,5,0"
Text="VSync"
TextAlignment="Left" />
<Border
Width="2"
Margin="2,0"
IsVisible="{Binding !ShowLoadProgress}"
BorderThickness="1"
Height="12"
BorderBrush="Gray" />
<TextBlock
Margin="5,0,5,0"
Name="DockedStatus"
IsVisible="{Binding !ShowLoadProgress}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
PointerReleased="DockedStatus_PointerReleased"
Text="{Binding DockedStatusText}"
TextAlignment="Left" />
<Border
Width="2"
Margin="2,0"
IsVisible="{Binding !ShowLoadProgress}"
BorderThickness="1"
Height="12"
BorderBrush="Gray" />
<TextBlock
Margin="5,0,5,0"
Name="AspectRatioStatus"
IsVisible="{Binding !ShowLoadProgress}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
PointerReleased="AspectRatioStatus_PointerReleased"
Text="{Binding AspectRatioStatusText}"
TextAlignment="Left" />
<Border
Width="2"
Margin="2,0"
IsVisible="{Binding !ShowLoadProgress}"
BorderThickness="1"
Height="12"
BorderBrush="Gray" />
<ui:ToggleSplitButton
Margin="-2,0,-3,0"
Padding="5,0,0,5"
Name="VolumeStatus"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
BorderBrush="{DynamicResource ThemeContentBackgroundColor}"
Background="{DynamicResource ThemeContentBackgroundColor}"
IsChecked="{Binding VolumeMuted}"
Content="{Binding VolumeStatusText}">
<ui:ToggleSplitButton.Flyout>
<Flyout Placement="Bottom" ShowMode="TransientWithDismissOnPointerMoveAway">
<Grid Margin="0">
<Slider Value="{Binding Volume}"
ToolTip.Tip="{locale:Locale AudioVolumeTooltip}"
Minimum="0"
Maximum="1"
TickFrequency="0.05"
IsSnapToTickEnabled="True"
Padding="0"
Margin="0"
SmallChange="0.01"
LargeChange="0.05"
Width="150" />
</Grid>
</Flyout>
</ui:ToggleSplitButton.Flyout>
</ui:ToggleSplitButton>
<Border
Width="2"
Margin="2,0"
IsVisible="{Binding !ShowLoadProgress}"
BorderThickness="1"
Height="12"
BorderBrush="Gray" />
<TextBlock
Margin="5,0,5,0"
IsVisible="{Binding !ShowLoadProgress}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding GameStatusText}"
TextAlignment="Left" />
<Border
Width="2"
IsVisible="{Binding !ShowLoadProgress}"
Margin="2,0"
BorderThickness="1"
Height="12"
BorderBrush="Gray" />
<TextBlock
Margin="5,0,5,0"
IsVisible="{Binding !ShowLoadProgress}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding FifoStatusText}"
TextAlignment="Left" />
<Border
Width="2"
Margin="2,0"
IsVisible="{Binding !ShowLoadProgress}"
BorderThickness="1"
Height="12"
BorderBrush="Gray" />
<TextBlock
Margin="5,0,5,0"
IsVisible="{Binding !ShowLoadProgress}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding GpuStatusText}"
TextAlignment="Left" />
</StackPanel>
<StackPanel VerticalAlignment="Center" IsVisible="{Binding ShowFirmwareStatus}" Grid.Column="3"
Orientation="Horizontal" Margin="10, 0">
<TextBlock
Name="FirmwareStatus"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0"
Text="{locale:Locale StatusBarSystemVersion}" />
</StackPanel>
</Grid>
</Grid>
</Grid>
</window:StyleableWindow>

View file

@ -0,0 +1,719 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Threading;
using Avalonia.Win32;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.Ui.Applet;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.Input.SDL2;
using Ryujinx.Modules;
using Ryujinx.Ui.App.Common;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using InputManager = Ryujinx.Input.HLE.InputManager;
using ProgressBar = Avalonia.Controls.ProgressBar;
namespace Ryujinx.Ava.Ui.Windows
{
public class MainWindow : StyleableWindow
{
private bool _canUpdate;
private bool _isClosing;
private bool _isLoading;
private Control _mainViewContent;
private UserChannelPersistence _userChannelPersistence;
private static bool _deferLoad;
private static string _launchPath;
private static bool _startFullscreen;
private string _currentEmulatedGamePath;
internal readonly AvaHostUiHandler UiHandler;
private AutoResetEvent _rendererWaitEvent;
public VirtualFileSystem VirtualFileSystem { get; private set; }
public ContentManager ContentManager { get; private set; }
public AccountManager AccountManager { get; private set; }
public LibHacHorizonManager LibHacHorizonManager { get; private set; }
public AppHost AppHost { get; private set; }
public InputManager InputManager { get; private set; }
public RendererControl GlRenderer { get; private set; }
public ContentControl ContentFrame { get; private set; }
public TextBlock LoadStatus { get; private set; }
public TextBlock FirmwareStatus { get; private set; }
public TextBox SearchBox { get; private set; }
public ProgressBar LoadProgressBar { get; private set; }
public Menu Menu { get; private set; }
public MenuItem UpdateMenuItem { get; private set; }
public MenuItem ActionsMenuItem { get; private set; }
public GameGridView GameGrid { get; private set; }
public GameListView GameList { get; private set; }
public OffscreenTextBox HiddenTextBox { get; private set; }
public HotKeyControl FullscreenHotKey { get; private set; }
public HotKeyControl FullscreenHotKey2 { get; private set; }
public HotKeyControl DockToggleHotKey { get; private set; }
public HotKeyControl ExitHotKey { get; private set; }
public ToggleSplitButton VolumeStatus { get; set; }
public MainWindowViewModel ViewModel { get; private set; }
public bool CanUpdate
{
get => _canUpdate;
set
{
_canUpdate = value;
Dispatcher.UIThread.InvokeAsync(() => UpdateMenuItem.IsEnabled = _canUpdate);
}
}
public static bool ShowKeyErrorOnLoad { get; set; }
public ApplicationLibrary ApplicationLibrary { get; set; }
public MainWindow()
{
ViewModel = new MainWindowViewModel(this);
DataContext = ViewModel;
InitializeComponent();
AttachDebugDevTools();
UiHandler = new AvaHostUiHandler(this);
Title = $"Ryujinx {Program.Version}";
Height = Height / Program.WindowScaleFactor;
Width = Width / Program.WindowScaleFactor;
if (Program.PreviewerDetached)
{
Initialize();
ViewModel.Initialize();
InputManager = new InputManager(new AvaloniaKeyboardDriver(this), new SDL2GamepadDriver());
LoadGameList();
CheckLaunchState();
}
if (OperatingSystem.IsLinux())
{
Program.WindowScaleFactor = this.PlatformImpl.RenderScaling;
}
_rendererWaitEvent = new AutoResetEvent(false);
}
[Conditional("DEBUG")]
private void AttachDebugDevTools()
{
this.AttachDevTools();
}
public void LoadGameList()
{
if (_isLoading)
{
return;
}
_isLoading = true;
ViewModel.LoadApplications();
_isLoading = false;
}
private void Update_StatusBar(object sender, StatusUpdatedEventArgs args)
{
if (ViewModel.ShowMenuAndStatusBar && !ViewModel.ShowLoadProgress)
{
Dispatcher.UIThread.InvokeAsync(() =>
{
if (args.VSyncEnabled)
{
ViewModel.VsyncColor = new SolidColorBrush(Color.Parse("#ff2eeac9"));
}
else
{
ViewModel.VsyncColor = new SolidColorBrush(Color.Parse("#ffff4554"));
}
ViewModel.DockedStatusText = args.DockedMode;
ViewModel.AspectRatioStatusText = args.AspectRatio;
ViewModel.GameStatusText = args.GameStatus;
ViewModel.FifoStatusText = args.FifoStatus;
ViewModel.GpuStatusText = args.GpuName;
ViewModel.ShowStatusSeparator = true;
});
}
}
public void Application_Opened(object sender, ApplicationOpenedEventArgs args)
{
if (args.Application != null)
{
ViewModel.SelectedIcon = args.Application.Icon;
string path = new FileInfo(args.Application.Path).FullName;
LoadApplication(path);
}
args.Handled = true;
}
public async Task PerformanceCheck()
{
if (ConfigurationState.Instance.Logger.EnableTrace.Value)
{
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledMessage"];
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledConfirmMessage"];
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
if (result != UserResult.Yes)
{
ConfigurationState.Instance.Logger.EnableTrace.Value = false;
SaveConfig();
}
}
if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value))
{
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledMessage"];
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
if (result != UserResult.Yes)
{
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = "";
SaveConfig();
}
}
}
internal static void DeferLoadApplication(string launchPathArg, bool startFullscreenArg)
{
_deferLoad = true;
_launchPath = launchPathArg;
_startFullscreen = startFullscreenArg;
}
#pragma warning disable CS1998
public async void LoadApplication(string path, bool startFullscreen = false, string titleName = "")
#pragma warning restore CS1998
{
if (AppHost != null)
{
await ContentDialogHelper.CreateInfoDialog(this,
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedMessage"],
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedSubMessage"],
LocaleManager.Instance["InputDialogOk"],
"",
LocaleManager.Instance["RyujinxInfo"]);
return;
}
#if RELEASE
await PerformanceCheck();
#endif
Logger.RestartTime();
if (ViewModel.SelectedIcon == null)
{
ViewModel.SelectedIcon = ApplicationLibrary.GetApplicationIcon(path);
}
PrepareLoadScreen();
_mainViewContent = ContentFrame.Content as Control;
GlRenderer = new RendererControl(3, 3, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
AppHost = new AppHost(GlRenderer, InputManager, path, VirtualFileSystem, ContentManager, AccountManager, _userChannelPersistence, this);
if (!AppHost.LoadGuestApplication().Result)
{
AppHost.DisposeContext();
return;
}
ViewModel.LoadHeading = string.IsNullOrWhiteSpace(titleName) ? string.Format(LocaleManager.Instance["LoadingHeading"], AppHost.Device.Application.TitleName) : titleName;
ViewModel.TitleName = string.IsNullOrWhiteSpace(titleName) ? AppHost.Device.Application.TitleName : titleName;
SwitchToGameControl(startFullscreen);
_currentEmulatedGamePath = path;
Thread gameThread = new Thread(InitializeGame)
{
Name = "GUI.WindowThread"
};
gameThread.Start();
}
private void InitializeGame()
{
GlRenderer.GlInitialized += GlRenderer_Created;
AppHost.StatusUpdatedEvent += Update_StatusBar;
AppHost.AppExit += AppHost_AppExit;
_rendererWaitEvent.WaitOne();
AppHost?.Start();
AppHost.DisposeContext();
}
private void HandleRelaunch()
{
if (_userChannelPersistence.PreviousIndex != -1 && _userChannelPersistence.ShouldRestart)
{
_userChannelPersistence.ShouldRestart = false;
Dispatcher.UIThread.Post(() =>
{
LoadApplication(_currentEmulatedGamePath);
});
}
else
{
// otherwise, clear state.
_userChannelPersistence = new UserChannelPersistence();
_currentEmulatedGamePath = null;
}
}
public void SwitchToGameControl(bool startFullscreen = false)
{
ViewModel.ShowContent = true;
ViewModel.ShowLoadProgress = false;
ViewModel.IsLoadingIndeterminate = false;
Dispatcher.UIThread.InvokeAsync(() =>
{
ContentFrame.Content = GlRenderer;
if (startFullscreen && WindowState != WindowState.FullScreen)
{
ViewModel.ToggleFullscreen();
}
GlRenderer.Focus();
});
}
public void ShowLoading(bool startFullscreen = false)
{
ViewModel.ShowContent = false;
ViewModel.ShowLoadProgress = true;
ViewModel.IsLoadingIndeterminate = true;
Dispatcher.UIThread.InvokeAsync(() =>
{
if (startFullscreen && WindowState != WindowState.FullScreen)
{
ViewModel.ToggleFullscreen();
}
});
}
private void GlRenderer_Created(object sender, EventArgs e)
{
ShowLoading();
_rendererWaitEvent.Set();
}
private void AppHost_AppExit(object sender, EventArgs e)
{
if (_isClosing)
{
return;
}
ViewModel.IsGameRunning = false;
Dispatcher.UIThread.InvokeAsync(() =>
{
if (ContentFrame.Content != _mainViewContent)
{
ContentFrame.Content = _mainViewContent;
}
ViewModel.ShowMenuAndStatusBar = true;
ViewModel.ShowContent = true;
ViewModel.ShowLoadProgress = false;
ViewModel.IsLoadingIndeterminate = false;
AppHost = null;
HandleRelaunch();
});
GlRenderer.GlInitialized -= GlRenderer_Created;
GlRenderer = null;
ViewModel.SelectedIcon = null;
Dispatcher.UIThread.InvokeAsync(() =>
{
Title = $"Ryujinx {Program.Version}";
});
}
public void Sort_Checked(object sender, RoutedEventArgs args)
{
if (sender is RadioButton button)
{
var sort = Enum.Parse<ApplicationSort>(button.Tag.ToString());
ViewModel.Sort(sort);
}
}
protected override void HandleWindowStateChanged(WindowState state)
{
WindowState = state;
if (state != WindowState.Minimized)
{
Renderer.Start();
}
}
public void Order_Checked(object sender, RoutedEventArgs args)
{
if (sender is RadioButton button)
{
var tag = button.Tag.ToString();
ViewModel.Sort(tag != "Descending");
}
}
private void Initialize()
{
_userChannelPersistence = new UserChannelPersistence();
VirtualFileSystem = VirtualFileSystem.CreateInstance();
LibHacHorizonManager = new LibHacHorizonManager();
ContentManager = new ContentManager(VirtualFileSystem);
LibHacHorizonManager.InitializeFsServer(VirtualFileSystem);
LibHacHorizonManager.InitializeArpServer();
LibHacHorizonManager.InitializeBcatServer();
LibHacHorizonManager.InitializeSystemClients();
ApplicationLibrary = new ApplicationLibrary(VirtualFileSystem);
// Save data created before we supported extra data in directory save data will not work properly if
// given empty extra data. Luckily some of that extra data can be created using the data from the
// save data indexer, which should be enough to check access permissions for user saves.
// Every single save data's extra data will be checked and fixed if needed each time the emulator is opened.
// Consider removing this at some point in the future when we don't need to worry about old saves.
VirtualFileSystem.FixExtraData(LibHacHorizonManager.RyujinxClient);
AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, Program.CommandLineProfile);
VirtualFileSystem.ReloadKeySet();
ApplicationHelper.Initialize(VirtualFileSystem, AccountManager, LibHacHorizonManager.RyujinxClient, this);
RefreshFirmwareStatus();
}
protected async void CheckLaunchState()
{
if (ShowKeyErrorOnLoad)
{
ShowKeyErrorOnLoad = false;
Dispatcher.UIThread.Post(async () => await
UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys, this));
}
if (_deferLoad)
{
_deferLoad = false;
LoadApplication(_launchPath, _startFullscreen);
}
if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false, this))
{
await Updater.BeginParse(this, false).ContinueWith(task =>
{
Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}");
}, TaskContinuationOptions.OnlyOnFaulted);
}
}
public void RefreshFirmwareStatus()
{
SystemVersion version = null;
try
{
version = ContentManager.GetCurrentFirmwareVersion();
}
catch (Exception) { }
bool hasApplet = false;
if (version != null)
{
LocaleManager.Instance.UpdateDynamicValue("StatusBarSystemVersion",
version.VersionString);
hasApplet = version.Major > 3;
}
else
{
LocaleManager.Instance.UpdateDynamicValue("StatusBarSystemVersion", "0.0");
}
ViewModel.IsAppletMenuActive = hasApplet;
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
ContentFrame = this.FindControl<ContentControl>("Content");
GameList = this.FindControl<GameListView>("GameList");
LoadStatus = this.FindControl<TextBlock>("LoadStatus");
FirmwareStatus = this.FindControl<TextBlock>("FirmwareStatus");
LoadProgressBar = this.FindControl<ProgressBar>("LoadProgressBar");
SearchBox = this.FindControl<TextBox>("SearchBox");
Menu = this.FindControl<Menu>("Menu");
UpdateMenuItem = this.FindControl<MenuItem>("UpdateMenuItem");
GameGrid = this.FindControl<GameGridView>("GameGrid");
HiddenTextBox = this.FindControl<OffscreenTextBox>("HiddenTextBox");
FullscreenHotKey = this.FindControl<HotKeyControl>("FullscreenHotKey");
FullscreenHotKey2 = this.FindControl<HotKeyControl>("FullscreenHotKey2");
DockToggleHotKey = this.FindControl<HotKeyControl>("DockToggleHotKey");
ExitHotKey = this.FindControl<HotKeyControl>("ExitHotKey");
VolumeStatus = this.FindControl<ToggleSplitButton>("VolumeStatus");
ActionsMenuItem = this.FindControl<MenuItem>("ActionsMenuItem");
VolumeStatus.Click += VolumeStatus_CheckedChanged;
GameGrid.ApplicationOpened += Application_Opened;
GameGrid.DataContext = ViewModel;
GameList.ApplicationOpened += Application_Opened;
GameList.DataContext = ViewModel;
LoadHotKeys();
}
public static void UpdateGraphicsConfig()
{
int resScale = ConfigurationState.Instance.Graphics.ResScale;
float resScaleCustom = ConfigurationState.Instance.Graphics.ResScaleCustom;
GraphicsConfig.ResScale = resScale == -1 ? resScaleCustom : resScale;
GraphicsConfig.MaxAnisotropy = ConfigurationState.Instance.Graphics.MaxAnisotropy;
GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath;
GraphicsConfig.EnableShaderCache = ConfigurationState.Instance.Graphics.EnableShaderCache;
}
public void LoadHotKeys()
{
HotKeyManager.SetHotKey(FullscreenHotKey, new KeyGesture(Key.Enter, KeyModifiers.Alt));
HotKeyManager.SetHotKey(FullscreenHotKey2, new KeyGesture(Key.F11));
HotKeyManager.SetHotKey(DockToggleHotKey, new KeyGesture(Key.F9));
HotKeyManager.SetHotKey(ExitHotKey, new KeyGesture(Key.Escape));
}
public static void SaveConfig()
{
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
}
public void UpdateGameMetadata(string titleId)
{
ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata =>
{
DateTime lastPlayedDateTime = DateTime.Parse(appMetadata.LastPlayed);
double sessionTimePlayed = DateTime.UtcNow.Subtract(lastPlayedDateTime).TotalSeconds;
appMetadata.TimePlayed += Math.Round(sessionTimePlayed, MidpointRounding.AwayFromZero);
});
}
private void PrepareLoadScreen()
{
using MemoryStream stream = new MemoryStream(ViewModel.SelectedIcon);
using var gameIconBmp = SixLabors.ImageSharp.Image.Load<Bgra32>(stream);
var dominantColor = IconColorPicker.GetFilteredColor(gameIconBmp).ToPixel<Bgra32>();
const int ColorDivisor = 4;
Color progressFgColor = Color.FromRgb(dominantColor.R, dominantColor.G, dominantColor.B);
Color progressBgColor = Color.FromRgb(
(byte)(dominantColor.R / ColorDivisor),
(byte)(dominantColor.G / ColorDivisor),
(byte)(dominantColor.B / ColorDivisor));
ViewModel.ProgressBarForegroundColor = new SolidColorBrush(progressFgColor);
ViewModel.ProgressBarBackgroundColor = new SolidColorBrush(progressBgColor);
}
private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
{
ViewModel.SearchText = SearchBox.Text;
}
private async void StopEmulation_Click(object sender, RoutedEventArgs e)
{
if (AppHost != null)
{
await AppHost.ShowExitPrompt();
}
}
private async void PauseEmulation_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
AppHost?.Pause();
});
}
private async void ResumeEmulation_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
AppHost?.Resume();
});
}
private void ScanAmiiboMenuItem_AttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
{
if (sender is MenuItem)
{
ViewModel.IsAmiiboRequested = AppHost.Device.System.SearchingForAmiibo(out _);
}
}
private void VsyncStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
{
AppHost.Device.EnableDeviceVsync = !AppHost.Device.EnableDeviceVsync;
Logger.Info?.Print(LogClass.Application, $"VSync toggled to: {AppHost.Device.EnableDeviceVsync}");
}
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
{
ConfigurationState.Instance.System.EnableDockedMode.Value = !ConfigurationState.Instance.System.EnableDockedMode.Value;
}
private void AspectRatioStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
{
AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value;
ConfigurationState.Instance.Graphics.AspectRatio.Value = (int)aspectRatio + 1 > Enum.GetNames(typeof(AspectRatio)).Length - 1 ? AspectRatio.Fixed4x3 : aspectRatio + 1;
}
private void VolumeStatus_CheckedChanged(object sender, SplitButtonClickEventArgs e)
{
var volumeSplitButton = sender as ToggleSplitButton;
if (ViewModel.IsGameRunning)
{
if (!volumeSplitButton.IsChecked)
{
AppHost.Device.SetVolume(ConfigurationState.Instance.System.AudioVolume);
}
else
{
AppHost.Device.SetVolume(0);
}
ViewModel.Volume = AppHost.Device.GetVolume();
}
}
protected override void OnClosing(CancelEventArgs e)
{
if (!_isClosing && AppHost != null && ConfigurationState.Instance.ShowConfirmExit)
{
e.Cancel = true;
ConfirmExit();
return;
}
_isClosing = true;
if (AppHost != null)
{
AppHost.AppExit -= AppHost_AppExit;
AppHost.AppExit += (sender, e) =>
{
AppHost = null;
Dispatcher.UIThread.Post(Close);
};
AppHost?.Stop();
e.Cancel = true;
return;
}
ApplicationLibrary.CancelLoading();
InputManager.Dispose();
Program.Exit();
base.OnClosing(e);
}
private void ConfirmExit()
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
_isClosing = await ContentDialogHelper.CreateExitDialog(this);
if (_isClosing)
{
Close();
}
});
}
}
}

View file

@ -0,0 +1,47 @@
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using FluentAvalonia.UI.Controls;
using System;
using System.IO;
using System.Reflection;
namespace Ryujinx.Ava.Ui.Windows
{
public class StyleableWindow : Window
{
public ContentDialog ContentDialog { get; private set; }
public IBitmap IconImage { get; set; }
public StyleableWindow()
{
WindowStartupLocation = WindowStartupLocation.CenterOwner;
TransparencyLevelHint = WindowTransparencyLevel.None;
using Stream stream = Assembly.GetAssembly(typeof(Ryujinx.Ui.Common.Configuration.ConfigurationState)).GetManifestResourceStream("Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
Icon = new WindowIcon(stream);
stream.Position = 0;
IconImage = new Bitmap(stream);
}
public void LoadDialog()
{
ContentDialog = this.FindControl<ContentDialog>("ContentDialog");
}
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
ContentDialog = this.FindControl<ContentDialog>("ContentDialog");
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
}
}
}

View file

@ -0,0 +1,16 @@
namespace Ryujinx.Ava.Ui.Windows
{
public class TimeZone
{
public TimeZone(string utcDifference, string location, string abbreviation)
{
UtcDifference = utcDifference;
Location = location;
Abbreviation = abbreviation;
}
public string UtcDifference { get; set; }
public string Location { get; set; }
public string Abbreviation { get; set; }
}
}

View file

@ -0,0 +1,37 @@
<window:StyleableWindow xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
x:Class="Ryujinx.Ava.Ui.Windows.UpdaterWindow"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
CanResize="False"
SizeToContent="Height"
Width="500" MinHeight="500" Height="500"
WindowStartupLocation="CenterOwner"
MinWidth="500"
Title="Ryujinx Updater">
<Grid Margin="20" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="1" HorizontalAlignment="Stretch" TextAlignment="Center" Height="20" Name="MainText" />
<TextBlock Height="20" HorizontalAlignment="Stretch" TextAlignment="Center" Name="SecondaryText" Grid.Row="2" />
<ProgressBar IsVisible="False" HorizontalAlignment="Stretch" Name="ProgressBar" Maximum="100" Minimum="0"
Margin="20" Grid.Row="3" />
<StackPanel IsVisible="False" Name="ButtonBox" Orientation="Horizontal" Spacing="20" Grid.Row="4"
HorizontalAlignment="Right">
<Button Command="{Binding YesPressed}" MinWidth="50">
<TextBlock TextAlignment="Center" Text="{locale:Locale InputDialogYes}" />
</Button>
<Button Command="{Binding NoPressed}" MinWidth="50">
<TextBlock TextAlignment="Center" Text="{locale:Locale InputDialogNo}" />
</Button>
</StackPanel>
</Grid>
</window:StyleableWindow>

View file

@ -0,0 +1,93 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Modules;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace Ryujinx.Ava.Ui.Windows
{
public class UpdaterWindow : StyleableWindow
{
private readonly string _buildUrl;
private readonly MainWindow _mainWindow;
private readonly Version _newVersion;
private bool _restartQuery;
public UpdaterWindow()
{
DataContext = this;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
Title = LocaleManager.Instance["RyujinxUpdater"];
}
public UpdaterWindow(MainWindow mainWindow, Version newVersion, string buildUrl) : this()
{
_mainWindow = mainWindow;
_newVersion = newVersion;
_buildUrl = buildUrl;
}
public TextBlock MainText { get; set; }
public TextBlock SecondaryText { get; set; }
public ProgressBar ProgressBar { get; set; }
public StackPanel ButtonBox { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
MainText = this.FindControl<TextBlock>("MainText");
SecondaryText = this.FindControl<TextBlock>("SecondaryText");
ProgressBar = this.FindControl<ProgressBar>("ProgressBar");
ButtonBox = this.FindControl<StackPanel>("ButtonBox");
}
[DllImport("libc", SetLastError = true)]
private static extern int chmod(string path, uint mode);
public void YesPressed()
{
if (_restartQuery)
{
string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().AsEnumerable().Skip(1).ToArray());
if (!OperatingSystem.IsWindows())
{
chmod(ryuExe, 0777);
}
Process.Start(ryuExe, ryuArg);
Environment.Exit(0);
}
else
{
ButtonBox.IsVisible = false;
ProgressBar.IsVisible = true;
SecondaryText.Text = "";
_restartQuery = true;
Updater.UpdateRyujinx(this, _buildUrl);
}
}
public void NoPressed()
{
_mainWindow.UpdateMenuItem.IsEnabled = true;
Close();
}
}
}

View file

@ -1,9 +1,20 @@
using Ryujinx.Common.Configuration.Hid.Controller.Motion; using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using System;
using System.ComponentModel;
using System.Text.Json.Serialization;
using NotImplementedException = System.NotImplementedException;
namespace Ryujinx.Common.Configuration.Hid.Controller namespace Ryujinx.Common.Configuration.Hid.Controller
{ {
public class GenericControllerInputConfig<Button, Stick> : GenericInputConfigurationCommon<Button> where Button : unmanaged where Stick : unmanaged public class GenericControllerInputConfig<Button, Stick> : GenericInputConfigurationCommon<Button> where Button : unmanaged where Stick : unmanaged
{ {
[JsonIgnore]
private float _deadzoneLeft;
[JsonIgnore]
private float _deadzoneRight;
[JsonIgnore]
private float _triggerThreshold;
/// <summary> /// <summary>
/// Left JoyCon Controller Stick Bindings /// Left JoyCon Controller Stick Bindings
/// </summary> /// </summary>
@ -17,12 +28,26 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
/// <summary> /// <summary>
/// Controller Left Analog Stick Deadzone /// Controller Left Analog Stick Deadzone
/// </summary> /// </summary>
public float DeadzoneLeft { get; set; } public float DeadzoneLeft
{
get => _deadzoneLeft; set
{
_deadzoneLeft = MathF.Round(value, 3);
OnPropertyChanged();
}
}
/// <summary> /// <summary>
/// Controller Right Analog Stick Deadzone /// Controller Right Analog Stick Deadzone
/// </summary> /// </summary>
public float DeadzoneRight { get; set; } public float DeadzoneRight
{
get => _deadzoneRight; set
{
_deadzoneRight = MathF.Round(value, 3);
OnPropertyChanged();
}
}
/// <summary> /// <summary>
/// Controller Left Analog Stick Range /// Controller Left Analog Stick Range
@ -37,7 +62,14 @@ namespace Ryujinx.Common.Configuration.Hid.Controller
/// <summary> /// <summary>
/// Controller Trigger Threshold /// Controller Trigger Threshold
/// </summary> /// </summary>
public float TriggerThreshold { get; set; } public float TriggerThreshold
{
get => _triggerThreshold; set
{
_triggerThreshold = MathF.Round(value, 3);
OnPropertyChanged();
}
}
/// <summary> /// <summary>
/// Controller Motion Settings /// Controller Motion Settings

View file

@ -1,6 +1,9 @@
namespace Ryujinx.Common.Configuration.Hid using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Ryujinx.Common.Configuration.Hid
{ {
public class InputConfig public class InputConfig : INotifyPropertyChanged
{ {
/// <summary> /// <summary>
/// The current version of the input file format /// The current version of the input file format
@ -25,5 +28,12 @@
/// Player's Index for the controller /// Player's Index for the controller
/// </summary> /// </summary>
public PlayerIndex PlayerIndex { get; set; } public PlayerIndex PlayerIndex { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }

View file

@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.GAL
{ {
public interface IWindow public interface IWindow
{ {
void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback); void Present(ITexture texture, ImageCrop crop, Action<object> swapBuffersCallback);
void SetSize(int width, int height); void SetSize(int width, int height);
} }

View file

@ -9,9 +9,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Window
public CommandType CommandType => CommandType.WindowPresent; public CommandType CommandType => CommandType.WindowPresent;
private TableRef<ThreadedTexture> _texture; private TableRef<ThreadedTexture> _texture;
private ImageCrop _crop; private ImageCrop _crop;
private TableRef<Action> _swapBuffersCallback; private TableRef<Action<object>> _swapBuffersCallback;
public void Set(TableRef<ThreadedTexture> texture, ImageCrop crop, TableRef<Action> swapBuffersCallback) public void Set(TableRef<ThreadedTexture> texture, ImageCrop crop, TableRef<Action<object>> swapBuffersCallback)
{ {
_texture = texture; _texture = texture;
_crop = crop; _crop = crop;

View file

@ -16,13 +16,13 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_impl = window; _impl = window;
} }
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) public void Present(ITexture texture, ImageCrop crop, Action<object> swapBuffersCallback)
{ {
// If there's already a frame in the pipeline, wait for it to be presented first. // If there's already a frame in the pipeline, wait for it to be presented first.
// This is a multithread rate limit - we can't be more than one frame behind the command queue. // This is a multithread rate limit - we can't be more than one frame behind the command queue.
_renderer.WaitForFrame(); _renderer.WaitForFrame();
_renderer.New<WindowPresentCommand>().Set(new TableRef<ThreadedTexture>(_renderer, texture as ThreadedTexture), crop, new TableRef<Action>(_renderer, swapBuffersCallback)); _renderer.New<WindowPresentCommand>().Set(new TableRef<ThreadedTexture>(_renderer, texture as ThreadedTexture), crop, new TableRef<Action<object>>(_renderer, swapBuffersCallback));
_renderer.QueueCommand(); _renderer.QueueCommand();
} }

View file

@ -90,6 +90,8 @@ namespace Ryujinx.Graphics.Gpu
private int _framesAvailable; private int _framesAvailable;
public bool IsFrameAvailable => _framesAvailable != 0;
/// <summary> /// <summary>
/// Creates a new instance of the GPU presentation window. /// Creates a new instance of the GPU presentation window.
/// </summary> /// </summary>
@ -189,7 +191,7 @@ namespace Ryujinx.Graphics.Gpu
/// If the queue is empty, then no texture is presented. /// If the queue is empty, then no texture is presented.
/// </summary> /// </summary>
/// <param name="swapBuffersCallback">Callback method to call when a new texture should be presented on the screen</param> /// <param name="swapBuffersCallback">Callback method to call when a new texture should be presented on the screen</param>
public void Present(Action swapBuffersCallback) public void Present(Action<object> swapBuffersCallback)
{ {
_context.AdvanceSequence(); _context.AdvanceSequence();

View file

@ -1,5 +1,6 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Helper;
using Ryujinx.Graphics.OpenGL.Image; using Ryujinx.Graphics.OpenGL.Image;
using System; using System;
@ -7,12 +8,16 @@ namespace Ryujinx.Graphics.OpenGL
{ {
class Window : IWindow, IDisposable class Window : IWindow, IDisposable
{ {
private const int TextureCount = 3;
private readonly Renderer _renderer; private readonly Renderer _renderer;
private int _width; private int _width;
private int _height; private int _height;
private bool _sizeChanged;
private int _copyFramebufferHandle; private int _copyFramebufferHandle;
private int _stagingFrameBuffer;
private int[] _stagingTextures;
private int _currentTexture;
internal BackgroundContextWorker BackgroundContext { get; private set; } internal BackgroundContextWorker BackgroundContext { get; private set; }
@ -21,13 +26,31 @@ namespace Ryujinx.Graphics.OpenGL
public Window(Renderer renderer) public Window(Renderer renderer)
{ {
_renderer = renderer; _renderer = renderer;
_stagingTextures = new int[TextureCount];
} }
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) public void Present(ITexture texture, ImageCrop crop, Action<object> swapBuffersCallback)
{ {
GL.Disable(EnableCap.FramebufferSrgb); GL.Disable(EnableCap.FramebufferSrgb);
CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback); if (_sizeChanged)
{
if (_stagingFrameBuffer != 0)
{
GL.DeleteTextures(_stagingTextures.Length, _stagingTextures);
GL.DeleteFramebuffer(_stagingFrameBuffer);
}
CreateStagingFramebuffer();
_sizeChanged = false;
}
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers();
CopyTextureToFrameBufferRGB(_stagingFrameBuffer, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
GL.Enable(EnableCap.FramebufferSrgb); GL.Enable(EnableCap.FramebufferSrgb);
@ -35,19 +58,41 @@ namespace Ryujinx.Graphics.OpenGL
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
} }
public void SetSize(int width, int height) private void CreateStagingFramebuffer()
{ {
_width = width; _stagingFrameBuffer = GL.GenFramebuffer();
_height = height; GL.GenTextures(_stagingTextures.Length, _stagingTextures);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _stagingFrameBuffer);
foreach (var stagingTexture in _stagingTextures)
{
GL.BindTexture(TextureTarget.Texture2D, stagingTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, _width, _height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, stagingTexture, 0);
}
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.BindTexture(TextureTarget.Texture2D, 0);
} }
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action swapBuffersCallback) public void SetSize(int width, int height)
{ {
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); _width = width;
_height = height;
_sizeChanged = true;
}
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action<object> swapBuffersCallback)
{
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
GL.FramebufferTexture2D(FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, _stagingTextures[_currentTexture], 0);
TextureView viewConverted = view.Format.IsBgr() ? _renderer.TextureCopy.BgraSwap(view) : view; TextureView viewConverted = view.Format.IsBgr() ? _renderer.TextureCopy.BgraSwap(view) : view;
GL.FramebufferTexture( GL.FramebufferTexture(
@ -96,13 +141,13 @@ namespace Ryujinx.Graphics.OpenGL
srcY1 = (int)Math.Ceiling(srcY1 * scale); srcY1 = (int)Math.Ceiling(srcY1 * scale);
} }
float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY)); float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX)); float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
int dstWidth = (int)(_width * ratioX); int dstWidth = (int)(_width * ratioX);
int dstHeight = (int)(_height * ratioY); int dstHeight = (int)(_height * ratioY);
int dstPaddingX = (_width - dstWidth) / 2; int dstPaddingX = (_width - dstWidth) / 2;
int dstPaddingY = (_height - dstHeight) / 2; int dstPaddingY = (_height - dstHeight) / 2;
int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX;
@ -145,10 +190,10 @@ namespace Ryujinx.Graphics.OpenGL
GL.Viewport(0, 0, _width, _height); GL.Viewport(0, 0, _width, _height);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer); GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer);
swapBuffersCallback(); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _stagingFrameBuffer);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); swapBuffersCallback((object)_stagingTextures[_currentTexture]);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); _currentTexture = ++_currentTexture % _stagingTextures.Length;
((Pipeline)_renderer.Pipeline).RestoreClipControl(); ((Pipeline)_renderer.Pipeline).RestoreClipControl();
((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable();
@ -200,6 +245,14 @@ namespace Ryujinx.Graphics.OpenGL
_copyFramebufferHandle = 0; _copyFramebufferHandle = 0;
} }
if (_stagingFrameBuffer != 0)
{
GL.DeleteTextures(_stagingTextures.Length, _stagingTextures);
GL.DeleteFramebuffer(_stagingFrameBuffer);
_stagingFrameBuffer = 0;
_stagingTextures = null;
}
} }
} }
} }

View file

@ -11,6 +11,7 @@ using System.Numerics;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using Ryujinx.Common;
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{ {
@ -65,10 +66,10 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
public SoftwareKeyboardRendererBase(IHostUiTheme uiTheme) public SoftwareKeyboardRendererBase(IHostUiTheme uiTheme)
{ {
string ryujinxLogoPath = "Ryujinx.Ui.Resources.Logo_Ryujinx.png"; int ryujinxLogoSize = 32;
int ryujinxLogoSize = 32;
_ryujinxLogo = LoadResource(Assembly.GetEntryAssembly(), ryujinxLogoPath, ryujinxLogoSize, ryujinxLogoSize); Stream logoStream = EmbeddedResources.GetStream("Ryujinx.Ui.Common/Resources/Logo_Ryujinx.png");
_ryujinxLogo = LoadResource(logoStream, ryujinxLogoSize, ryujinxLogoSize);
string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png"; string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png";
string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png"; string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png";
@ -158,6 +159,11 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{ {
Stream resourceStream = assembly.GetManifestResourceStream(resourcePath); Stream resourceStream = assembly.GetManifestResourceStream(resourcePath);
return LoadResource(resourceStream, newWidth, newHeight);
}
private Image LoadResource(Stream resourceStream, int newWidth, int newHeight)
{
Debug.Assert(resourceStream != null); Debug.Assert(resourceStream != null);
var image = Image.Load(resourceStream); var image = Image.Load(resourceStream);

View file

@ -28,6 +28,8 @@ namespace Ryujinx.HLE
public bool EnableDeviceVsync { get; set; } = true; public bool EnableDeviceVsync { get; set; } = true;
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
public Switch(HLEConfiguration configuration) public Switch(HLEConfiguration configuration)
{ {
if (configuration.GpuRenderer == null) if (configuration.GpuRenderer == null)
@ -115,7 +117,7 @@ namespace Ryujinx.HLE
return Gpu.Window.ConsumeFrameAvailable(); return Gpu.Window.ConsumeFrameAvailable();
} }
public void PresentFrame(Action swapBuffersCallback) public void PresentFrame(Action<object> swapBuffersCallback)
{ {
Gpu.Window.Present(swapBuffersCallback); Gpu.Window.Present(swapBuffersCallback);
} }

View file

@ -141,7 +141,7 @@ namespace Ryujinx.Headless.SDL2.OpenGL
GL.ClearColor(0, 0, 0, 1.0f); GL.ClearColor(0, 0, 0, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit);
SwapBuffers(); SwapBuffers(0);
Renderer?.Window.SetSize(DefaultWidth, DefaultHeight); Renderer?.Window.SetSize(DefaultWidth, DefaultHeight);
MouseDriver.SetClientSize(DefaultWidth, DefaultHeight); MouseDriver.SetClientSize(DefaultWidth, DefaultHeight);
@ -159,8 +159,28 @@ namespace Ryujinx.Headless.SDL2.OpenGL
_openGLContext.Dispose(); _openGLContext.Dispose();
} }
protected override void SwapBuffers() protected override void SwapBuffers(object image)
{ {
if ((int)image != 0)
{
// The game's framebruffer is already bound, so blit it to the window's backbuffer
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.ClearColor(0, 0, 0, 1);
GL.BlitFramebuffer(0,
0,
Width,
Height,
0,
0,
Width,
Height,
ClearBufferMask.ColorBufferBit,
BlitFramebufferFilter.Linear);
}
SDL_GL_SwapWindow(WindowHandle); SDL_GL_SwapWindow(WindowHandle);
} }
} }

View file

@ -30,16 +30,16 @@
<PackageReference Include="CommandLineParser" Version="2.8.0" /> <PackageReference Include="CommandLineParser" Version="2.8.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="..\Ryujinx\THIRDPARTY.md"> <ContentWithTargetPath Include="..\distribution\legal\THIRDPARTY.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>THIRDPARTY.md</TargetPath> <TargetPath>THIRDPARTY.md</TargetPath>
</None> </ContentWithTargetPath>
<ContentWithTargetPath Include="..\Ryujinx.Audio\LICENSE.txt"> <ContentWithTargetPath Include="..\Ryujinx.Audio\LICENSE.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>LICENSE-Ryujinx.Audio.txt</TargetPath> <TargetPath>LICENSE-Ryujinx.Audio.txt</TargetPath>
</ContentWithTargetPath> </ContentWithTargetPath>
</ItemGroup> </ItemGroup>
<!-- Due to .net core 3.1 embedded resource loading --> <!-- Due to .net core 3.1 embedded resource loading -->
<PropertyGroup> <PropertyGroup>

View file

@ -36,6 +36,8 @@ namespace Ryujinx.Headless.SDL2
protected IntPtr WindowHandle { get; set; } protected IntPtr WindowHandle { get; set; }
public IHostUiTheme HostUiTheme { get; } public IHostUiTheme HostUiTheme { get; }
public int Width { get; private set; }
public int Height { get; private set; }
protected SDL2MouseDriver MouseDriver; protected SDL2MouseDriver MouseDriver;
private InputManager _inputManager; private InputManager _inputManager;
@ -119,6 +121,9 @@ namespace Ryujinx.Headless.SDL2
_windowId = SDL_GetWindowID(WindowHandle); _windowId = SDL_GetWindowID(WindowHandle);
SDL2Driver.Instance.RegisterWindow(_windowId, HandleWindowEvent); SDL2Driver.Instance.RegisterWindow(_windowId, HandleWindowEvent);
Width = DefaultWidth;
Height = DefaultHeight;
} }
private void HandleWindowEvent(SDL_Event evnt) private void HandleWindowEvent(SDL_Event evnt)
@ -128,8 +133,10 @@ namespace Ryujinx.Headless.SDL2
switch (evnt.window.windowEvent) switch (evnt.window.windowEvent)
{ {
case SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
Renderer?.Window.SetSize(evnt.window.data1, evnt.window.data2); Width = evnt.window.data1;
MouseDriver.SetClientSize(evnt.window.data1, evnt.window.data2); Height = evnt.window.data2;
Renderer?.Window.SetSize(Width, Height);
MouseDriver.SetClientSize(Width, Height);
break; break;
case SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE: case SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE:
Exit(); Exit();
@ -148,7 +155,7 @@ namespace Ryujinx.Headless.SDL2
protected abstract void FinalizeRenderer(); protected abstract void FinalizeRenderer();
protected abstract void SwapBuffers(); protected abstract void SwapBuffers(object image);
protected abstract string GetGpuVendorName(); protected abstract string GetGpuVendorName();
@ -188,7 +195,7 @@ namespace Ryujinx.Headless.SDL2
while (Device.ConsumeFrameAvailable()) while (Device.ConsumeFrameAvailable())
{ {
Device.PresentFrame(SwapBuffers); Device.PresentFrame((texture) => { SwapBuffers(texture); });
} }
if (_ticks >= _ticksPerFrame) if (_ticks >= _ticksPerFrame)

View file

@ -70,7 +70,6 @@ namespace Ryujinx.Input.SDL2
SDL_Keycode.SDLK_F23, SDL_Keycode.SDLK_F23,
SDL_Keycode.SDLK_F24, SDL_Keycode.SDLK_F24,
// F25-F35 not exposed on SDL2
SDL_Keycode.SDLK_0, SDL_Keycode.SDLK_0,
SDL_Keycode.SDLK_0, SDL_Keycode.SDLK_0,
SDL_Keycode.SDLK_0, SDL_Keycode.SDLK_0,

Some files were not shown because too many files have changed in this diff Show more