aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Guillemard <mary@mary.zone>2024-03-02 12:51:05 +0100
committerGitHub <noreply@github.com>2024-03-02 12:51:05 +0100
commitec6cb0abb4b7669895b6e96fd7581c93b5abd691 (patch)
tree128c862ff5faea0b219467656d4023bee7faefb5
parent53b5985da6b9d7b281d9fc25b93bfd1d1918a107 (diff)
infra: Make Avalonia the default UI (#6375)1.1.1216
* misc: Move Ryujinx project to Ryujinx.Gtk3 This breaks release CI for now but that's fine. Signed-off-by: Mary Guillemard <mary@mary.zone> * misc: Move Ryujinx.Ava project to Ryujinx This breaks CI for now, but it's fine. Signed-off-by: Mary Guillemard <mary@mary.zone> * infra: Make Avalonia the default UI Should fix CI after the previous changes. GTK3 isn't build by the release job anymore, only by PR CI. This also ensure that the test-ava update package is still generated to allow update from the old testing channel. Signed-off-by: Mary Guillemard <mary@mary.zone> * Fix missing copy in create_app_bundle.sh Signed-off-by: Mary Guillemard <mary@mary.zone> * Fix syntax error Signed-off-by: Mary Guillemard <mary@mary.zone> --------- Signed-off-by: Mary Guillemard <mary@mary.zone>
-rw-r--r--.editorconfig8
-rw-r--r--.github/labeler.yml2
-rw-r--r--.github/workflows/build.yml22
-rw-r--r--.github/workflows/nightly_pr_comment.yml10
-rw-r--r--.github/workflows/release.yml13
-rw-r--r--Ryujinx.sln4
-rwxr-xr-xdistribution/linux/Ryujinx.sh4
-rwxr-xr-xdistribution/macos/create_app_bundle.sh4
-rwxr-xr-xdistribution/macos/create_macos_build_ava.sh17
-rw-r--r--src/Ryujinx.Ava/Program.cs237
-rw-r--r--src/Ryujinx.Ava/Ryujinx.Ava.csproj167
-rw-r--r--src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs (renamed from src/Ryujinx/Input/GTK3/GTK3Keyboard.cs)0
-rw-r--r--src/Ryujinx.Gtk3/Input/GTK3/GTK3KeyboardDriver.cs (renamed from src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs)0
-rw-r--r--src/Ryujinx.Gtk3/Input/GTK3/GTK3MappingHelper.cs (renamed from src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs)0
-rw-r--r--src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs (renamed from src/Ryujinx/Input/GTK3/GTK3Mouse.cs)0
-rw-r--r--src/Ryujinx.Gtk3/Input/GTK3/GTK3MouseDriver.cs (renamed from src/Ryujinx/Input/GTK3/GTK3MouseDriver.cs)0
-rw-r--r--src/Ryujinx.Gtk3/Modules/Updater/UpdateDialog.cs (renamed from src/Ryujinx/Modules/Updater/UpdateDialog.cs)4
-rw-r--r--src/Ryujinx.Gtk3/Modules/Updater/UpdateDialog.glade (renamed from src/Ryujinx/Modules/Updater/UpdateDialog.glade)0
-rw-r--r--src/Ryujinx.Gtk3/Modules/Updater/Updater.cs (renamed from src/Ryujinx.Ava/Modules/Updater/Updater.cs)482
-rw-r--r--src/Ryujinx.Gtk3/Program.cs378
-rw-r--r--src/Ryujinx.Gtk3/Ryujinx.Gtk3.csproj104
-rw-r--r--src/Ryujinx.Gtk3/Ryujinx.ico (renamed from src/Ryujinx.Ava/Ryujinx.ico)bin108122 -> 108122 bytes
-rw-r--r--src/Ryujinx.Gtk3/UI/Applet/ErrorAppletDialog.cs (renamed from src/Ryujinx/UI/Applet/ErrorAppletDialog.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Applet/GtkDynamicTextInputHandler.cs (renamed from src/Ryujinx/UI/Applet/GtkDynamicTextInputHandler.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Applet/GtkHostUIHandler.cs (renamed from src/Ryujinx/UI/Applet/GtkHostUIHandler.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Applet/GtkHostUITheme.cs (renamed from src/Ryujinx/UI/Applet/GtkHostUITheme.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Applet/SwkbdAppletDialog.cs (renamed from src/Ryujinx/UI/Applet/SwkbdAppletDialog.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Helper/MetalHelper.cs (renamed from src/Ryujinx/UI/Helper/MetalHelper.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Helper/SortHelper.cs (renamed from src/Ryujinx/UI/Helper/SortHelper.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Helper/ThemeHelper.cs (renamed from src/Ryujinx/UI/Helper/ThemeHelper.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/MainWindow.cs (renamed from src/Ryujinx/UI/MainWindow.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/MainWindow.glade (renamed from src/Ryujinx/UI/MainWindow.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/OpenGLRenderer.cs (renamed from src/Ryujinx/UI/OpenGLRenderer.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/OpenToolkitBindingsContext.cs (renamed from src/Ryujinx/UI/OpenToolkitBindingsContext.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs (renamed from src/Ryujinx/UI/RendererWidgetBase.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/SPBOpenGLContext.cs (renamed from src/Ryujinx/UI/SPBOpenGLContext.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/StatusUpdatedEventArgs.cs (renamed from src/Ryujinx/UI/StatusUpdatedEventArgs.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/VulkanRenderer.cs (renamed from src/Ryujinx/UI/VulkanRenderer.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/GameTableContextMenu.Designer.cs (renamed from src/Ryujinx/UI/Widgets/GameTableContextMenu.Designer.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/GameTableContextMenu.cs (renamed from src/Ryujinx/UI/Widgets/GameTableContextMenu.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/GtkDialog.cs (renamed from src/Ryujinx/UI/Widgets/GtkDialog.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/GtkInputDialog.cs (renamed from src/Ryujinx/UI/Widgets/GtkInputDialog.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/ProfileDialog.cs (renamed from src/Ryujinx/UI/Widgets/ProfileDialog.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/ProfileDialog.glade (renamed from src/Ryujinx/UI/Widgets/ProfileDialog.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/RawInputToTextEntry.cs (renamed from src/Ryujinx/UI/Widgets/RawInputToTextEntry.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Widgets/UserErrorDialog.cs (renamed from src/Ryujinx/UI/Widgets/UserErrorDialog.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/AboutWindow.Designer.cs (renamed from src/Ryujinx/UI/Windows/AboutWindow.Designer.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/AboutWindow.cs (renamed from src/Ryujinx/UI/Windows/AboutWindow.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/AmiiboWindow.Designer.cs (renamed from src/Ryujinx/UI/Windows/AmiiboWindow.Designer.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/AmiiboWindow.cs (renamed from src/Ryujinx/UI/Windows/AmiiboWindow.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/AvatarWindow.cs (renamed from src/Ryujinx/UI/Windows/AvatarWindow.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/CheatWindow.cs (renamed from src/Ryujinx/UI/Windows/CheatWindow.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/CheatWindow.glade (renamed from src/Ryujinx/UI/Windows/CheatWindow.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/ControllerWindow.cs (renamed from src/Ryujinx/UI/Windows/ControllerWindow.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/ControllerWindow.glade (renamed from src/Ryujinx/UI/Windows/ControllerWindow.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/DlcWindow.cs (renamed from src/Ryujinx/UI/Windows/DlcWindow.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/DlcWindow.glade (renamed from src/Ryujinx/UI/Windows/DlcWindow.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs (renamed from src/Ryujinx/UI/Windows/SettingsWindow.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade (renamed from src/Ryujinx/UI/Windows/SettingsWindow.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/TitleUpdateWindow.cs (renamed from src/Ryujinx/UI/Windows/TitleUpdateWindow.cs)2
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/TitleUpdateWindow.glade (renamed from src/Ryujinx/UI/Windows/TitleUpdateWindow.glade)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/UserProfilesManagerWindow.Designer.cs (renamed from src/Ryujinx/UI/Windows/UserProfilesManagerWindow.Designer.cs)0
-rw-r--r--src/Ryujinx.Gtk3/UI/Windows/UserProfilesManagerWindow.cs (renamed from src/Ryujinx/UI/Windows/UserProfilesManagerWindow.cs)0
-rw-r--r--src/Ryujinx/App.axaml (renamed from src/Ryujinx.Ava/App.axaml)0
-rw-r--r--src/Ryujinx/App.axaml.cs (renamed from src/Ryujinx.Ava/App.axaml.cs)0
-rw-r--r--src/Ryujinx/AppHost.cs (renamed from src/Ryujinx.Ava/AppHost.cs)0
-rw-r--r--src/Ryujinx/Assets/Fonts/SegoeFluentIcons.ttf (renamed from src/Ryujinx.Ava/Assets/Fonts/SegoeFluentIcons.ttf)bin408752 -> 408752 bytes
-rw-r--r--src/Ryujinx/Assets/Icons/Controller_JoyConLeft.svg (renamed from src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg)0
-rw-r--r--src/Ryujinx/Assets/Icons/Controller_JoyConPair.svg (renamed from src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg)0
-rw-r--r--src/Ryujinx/Assets/Icons/Controller_JoyConRight.svg (renamed from src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg)0
-rw-r--r--src/Ryujinx/Assets/Icons/Controller_ProCon.svg (renamed from src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg)0
-rw-r--r--src/Ryujinx/Assets/Locales/de_DE.json (renamed from src/Ryujinx.Ava/Assets/Locales/de_DE.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/el_GR.json (renamed from src/Ryujinx.Ava/Assets/Locales/el_GR.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/en_US.json (renamed from src/Ryujinx.Ava/Assets/Locales/en_US.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/es_ES.json (renamed from src/Ryujinx.Ava/Assets/Locales/es_ES.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/fr_FR.json (renamed from src/Ryujinx.Ava/Assets/Locales/fr_FR.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/he_IL.json (renamed from src/Ryujinx.Ava/Assets/Locales/he_IL.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/it_IT.json (renamed from src/Ryujinx.Ava/Assets/Locales/it_IT.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/ja_JP.json (renamed from src/Ryujinx.Ava/Assets/Locales/ja_JP.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/ko_KR.json (renamed from src/Ryujinx.Ava/Assets/Locales/ko_KR.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/pl_PL.json (renamed from src/Ryujinx.Ava/Assets/Locales/pl_PL.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/pt_BR.json (renamed from src/Ryujinx.Ava/Assets/Locales/pt_BR.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/ru_RU.json (renamed from src/Ryujinx.Ava/Assets/Locales/ru_RU.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/tr_TR.json (renamed from src/Ryujinx.Ava/Assets/Locales/tr_TR.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/uk_UA.json (renamed from src/Ryujinx.Ava/Assets/Locales/uk_UA.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/zh_CN.json (renamed from src/Ryujinx.Ava/Assets/Locales/zh_CN.json)0
-rw-r--r--src/Ryujinx/Assets/Locales/zh_TW.json (renamed from src/Ryujinx.Ava/Assets/Locales/zh_TW.json)0
-rw-r--r--src/Ryujinx/Assets/Styles/Styles.xaml (renamed from src/Ryujinx.Ava/Assets/Styles/Styles.xaml)0
-rw-r--r--src/Ryujinx/Assets/Styles/Themes.xaml (renamed from src/Ryujinx.Ava/Assets/Styles/Themes.xaml)0
-rw-r--r--src/Ryujinx/Common/ApplicationHelper.cs (renamed from src/Ryujinx.Ava/Common/ApplicationHelper.cs)0
-rw-r--r--src/Ryujinx/Common/ApplicationSort.cs (renamed from src/Ryujinx.Ava/Common/ApplicationSort.cs)0
-rw-r--r--src/Ryujinx/Common/KeyboardHotkeyState.cs (renamed from src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs)0
-rw-r--r--src/Ryujinx/Common/Locale/LocaleExtension.cs (renamed from src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs)0
-rw-r--r--src/Ryujinx/Common/Locale/LocaleManager.cs (renamed from src/Ryujinx.Ava/Common/Locale/LocaleManager.cs)2
-rw-r--r--src/Ryujinx/Input/AvaloniaKeyboard.cs (renamed from src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs)0
-rw-r--r--src/Ryujinx/Input/AvaloniaKeyboardDriver.cs (renamed from src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs)0
-rw-r--r--src/Ryujinx/Input/AvaloniaKeyboardMappingHelper.cs (renamed from src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs)0
-rw-r--r--src/Ryujinx/Input/AvaloniaMouse.cs (renamed from src/Ryujinx.Ava/Input/AvaloniaMouse.cs)0
-rw-r--r--src/Ryujinx/Input/AvaloniaMouseDriver.cs (renamed from src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs)0
-rw-r--r--src/Ryujinx/Modules/Updater/Updater.cs480
-rw-r--r--src/Ryujinx/Program.cs309
-rw-r--r--src/Ryujinx/Ryujinx.csproj130
-rw-r--r--src/Ryujinx/UI/Applet/AvaHostUIHandler.cs (renamed from src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs)0
-rw-r--r--src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs (renamed from src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs)0
-rw-r--r--src/Ryujinx/UI/Applet/AvaloniaHostUITheme.cs (renamed from src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs)0
-rw-r--r--src/Ryujinx/UI/Applet/ControllerAppletDialog.axaml (renamed from src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml)0
-rw-r--r--src/Ryujinx/UI/Applet/ControllerAppletDialog.axaml.cs (renamed from src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs)8
-rw-r--r--src/Ryujinx/UI/Applet/ErrorAppletWindow.axaml (renamed from src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Applet/ErrorAppletWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Applet/SwkbdAppletDialog.axaml (renamed from src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml)0
-rw-r--r--src/Ryujinx/UI/Applet/SwkbdAppletDialog.axaml.cs (renamed from src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml (renamed from src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml)0
-rw-r--r--src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Controls/ApplicationGridView.axaml (renamed from src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml)0
-rw-r--r--src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Controls/ApplicationListView.axaml (renamed from src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml)0
-rw-r--r--src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Controls/NavigationDialogHost.axaml (renamed from src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml)0
-rw-r--r--src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Controls/SliderScroll.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Controls/UpdateWaitWindow.axaml (renamed from src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Controls/UpdateWaitWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/ApplicationOpenedEventArgs.cs (renamed from src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/BitmapArrayValueConverter.cs (renamed from src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/ButtonKeyAssigner.cs (renamed from src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/ContentDialogHelper.cs (renamed from src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/Glyph.cs (renamed from src/Ryujinx.Ava/UI/Helpers/Glyph.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/GlyphValueConverter.cs (renamed from src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/KeyValueConverter.cs (renamed from src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/LocalizedNeverConverter.cs (renamed from src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/LoggerAdapter.cs (renamed from src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/MiniCommand.cs (renamed from src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/NotificationHelper.cs (renamed from src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/OffscreenTextBox.cs (renamed from src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/TimeZoneConverter.cs (renamed from src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/UserErrorDialog.cs (renamed from src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/UserResult.cs (renamed from src/Ryujinx.Ava/UI/Helpers/UserResult.cs)0
-rw-r--r--src/Ryujinx/UI/Helpers/Win32NativeInterop.cs (renamed from src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs)0
-rw-r--r--src/Ryujinx/UI/Models/CheatNode.cs (renamed from src/Ryujinx.Ava/UI/Models/CheatNode.cs)0
-rw-r--r--src/Ryujinx/UI/Models/ControllerModel.cs (renamed from src/Ryujinx.Ava/UI/Models/ControllerModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/DeviceType.cs (renamed from src/Ryujinx.Ava/UI/Models/DeviceType.cs)0
-rw-r--r--src/Ryujinx/UI/Models/DownloadableContentModel.cs (renamed from src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs (renamed from src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs)0
-rw-r--r--src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs (renamed from src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs)0
-rw-r--r--src/Ryujinx/UI/Models/InputConfiguration.cs (renamed from src/Ryujinx.Ava/UI/Models/InputConfiguration.cs)0
-rw-r--r--src/Ryujinx/UI/Models/ModModel.cs (renamed from src/Ryujinx.Ava/UI/Models/ModModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/PlayerModel.cs (renamed from src/Ryujinx.Ava/UI/Models/PlayerModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/ProfileImageModel.cs (renamed from src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/SaveModel.cs (renamed from src/Ryujinx.Ava/UI/Models/SaveModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs (renamed from src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs)0
-rw-r--r--src/Ryujinx/UI/Models/TempProfile.cs (renamed from src/Ryujinx.Ava/UI/Models/TempProfile.cs)0
-rw-r--r--src/Ryujinx/UI/Models/TimeZone.cs (renamed from src/Ryujinx.Ava/UI/Models/TimeZone.cs)0
-rw-r--r--src/Ryujinx/UI/Models/TitleUpdateModel.cs (renamed from src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs)0
-rw-r--r--src/Ryujinx/UI/Models/UserProfile.cs (renamed from src/Ryujinx.Ava/UI/Models/UserProfile.cs)0
-rw-r--r--src/Ryujinx/UI/Renderer/EmbeddedWindow.cs (renamed from src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs)0
-rw-r--r--src/Ryujinx/UI/Renderer/EmbeddedWindowOpenGL.cs (renamed from src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs)0
-rw-r--r--src/Ryujinx/UI/Renderer/EmbeddedWindowVulkan.cs (renamed from src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs)0
-rw-r--r--src/Ryujinx/UI/Renderer/OpenTKBindingsContext.cs (renamed from src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs)0
-rw-r--r--src/Ryujinx/UI/Renderer/RendererHost.axaml (renamed from src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml)0
-rw-r--r--src/Ryujinx/UI/Renderer/RendererHost.axaml.cs (renamed from src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Renderer/SPBOpenGLContext.cs (renamed from src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/BaseModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/ControllerInputViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/MotionInputViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/RumbleInputViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/SettingsViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/UserProfileImageSelectorViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/UserProfileViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/ViewModels/UserSaveManagerViewModel.cs (renamed from src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Input/ControllerInputView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Input/MotionInputView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Input/RumbleInputView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs)2
-rw-r--r--src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Main/MainViewControls.axaml (renamed from src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Main/MainViewControls.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsAudioView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsAudioView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsInputView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsInputView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserEditorView.axaml (renamed from src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml (renamed from src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml (renamed from src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserRecovererView.axaml (renamed from src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml (renamed from src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserSelectorView.axaml (renamed from src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml)0
-rw-r--r--src/Ryujinx/UI/Views/User/UserSelectorView.axaml.cs (renamed from src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/AboutWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/AboutWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/AmiiboWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/AmiiboWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/CheatWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/CheatWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/ContentDialogOverlayWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/ContentDialogOverlayWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/IconColorPicker.cs (renamed from src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/MainWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/MainWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/MainWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/ModManagerWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/SettingsWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml)2
-rw-r--r--src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/StyleableWindow.cs (renamed from src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs)0
-rw-r--r--src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml (renamed from src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml)0
-rw-r--r--src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml.cs (renamed from src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs)0
-rw-r--r--src/Ryujinx/app.manifest (renamed from src/Ryujinx.Ava/app.manifest)0
239 files changed, 1205 insertions, 1202 deletions
diff --git a/.editorconfig b/.editorconfig
index 1eaf77ae..76edc491 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -259,12 +259,12 @@ dotnet_diagnostic.CA1861.severity = none
# Disable "Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'"
dotnet_diagnostic.CA1862.severity = none
-[src/Ryujinx.HLE/HOS/Services/**.cs]
-# Disable "mark members as static" rule for services
+[src/Ryujinx/UI/ViewModels/**.cs]
+# Disable "mark members as static" rule for ViewModels
dotnet_diagnostic.CA1822.severity = none
-[src/Ryujinx.Ava/UI/ViewModels/**.cs]
-# Disable "mark members as static" rule for ViewModels
+[src/Ryujinx.HLE/HOS/Services/**.cs]
+# Disable "mark members as static" rule for services
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Tests/Cpu/*.cs]
diff --git a/.github/labeler.yml b/.github/labeler.yml
index b967cc77..cd7650a9 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -20,7 +20,7 @@ gpu:
gui:
- changed-files:
- - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**', 'src/Ryujinx.Ava/**']
+ - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**', 'src/Ryujinx.Gtk3/**']
horizon:
- changed-files:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 598f23c5..9e11302f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -67,15 +67,15 @@ jobs:
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -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 src/Ryujinx.Headless.SDL2 --self-contained true
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- - name: Publish Ryujinx.Ava
- run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
+ - name: Publish Ryujinx.Gtk3
+ run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_gtk -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Gtk3 --self-contained true
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- name: Set executable bit
run: |
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
- chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh
+ chmod +x ./publish_gtk/Ryujinx.Gtk3 ./publish_gtk/Ryujinx.sh
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
- name: Upload Ryujinx artifact
@@ -92,11 +92,11 @@ jobs:
path: publish_sdl2_headless
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
- - name: Upload Ryujinx.Ava artifact
+ - name: Upload Ryujinx.Gtk3 artifact
uses: actions/upload-artifact@v4
with:
- name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
- path: publish_ava
+ name: gtk-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
+ path: publish_gtk
if: github.event_name == 'pull_request' && matrix.platform.os != 'macOS-latest'
build_macos:
@@ -140,19 +140,19 @@ jobs:
shell: bash
if: github.event_name == 'pull_request'
- - name: Publish macOS Ryujinx.Ava
+ - name: Publish macOS Ryujinx
run: |
- ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
+ ./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
- - name: Upload Ryujinx.Ava artifact
+ - name: Upload Ryujinx artifact
uses: actions/upload-artifact@v4
with:
- name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
- path: "publish_ava/*.tar.gz"
+ name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
+ path: "publish/*.tar.gz"
if: github.event_name == 'pull_request'
- name: Upload Ryujinx.Headless.SDL2 artifact
diff --git a/.github/workflows/nightly_pr_comment.yml b/.github/workflows/nightly_pr_comment.yml
index f59a6be1..38850df0 100644
--- a/.github/workflows/nightly_pr_comment.yml
+++ b/.github/workflows/nightly_pr_comment.yml
@@ -39,24 +39,24 @@ jobs:
return core.error(`No artifacts found`);
}
let body = `Download the artifacts for this pull request:\n`;
- let hidden_avalonia_artifacts = `\n\n <details><summary>Experimental GUI (Avalonia)</summary>\n`;
+ let hidden_gtk_artifacts = `\n\n <details><summary>Old GUI (GTK3)</summary>\n`;
let hidden_headless_artifacts = `\n\n <details><summary>GUI-less (SDL2)</summary>\n`;
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
for (const art of artifacts) {
if(art.name.includes('Debug')) {
hidden_debug_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
- } else if(art.name.includes('ava-ryujinx')) {
- hidden_avalonia_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
+ } else if(art.name.includes('gtk-ryujinx')) {
+ hidden_gtk_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
} else if(art.name.includes('sdl2-ryujinx-headless')) {
hidden_headless_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
} else {
body += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
}
}
- hidden_avalonia_artifacts += `\n</details>`;
+ hidden_gtk_artifacts += `\n</details>`;
hidden_headless_artifacts += `\n</details>`;
hidden_debug_artifacts += `\n</details>`;
- body += hidden_avalonia_artifacts;
+ body += hidden_gtk_artifacts;
body += hidden_headless_artifacts;
body += hidden_debug_artifacts;
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ac598684..133c2fad 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -86,14 +86,13 @@ jobs:
- name: Publish
run: |
- dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
+ dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
- dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
run: |
- pushd publish_gtk
+ pushd publish_ava
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
@@ -102,6 +101,7 @@ jobs:
popd
pushd publish_ava
+ mv publish/Ryujinx.exe publish/Ryujinx.Ava.exe
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
popd
shell: bash
@@ -109,7 +109,7 @@ jobs:
- name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
run: |
- pushd publish_gtk
+ pushd publish_ava
chmod +x publish/Ryujinx.sh publish/Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
@@ -120,6 +120,7 @@ jobs:
popd
pushd publish_ava
+ mv publish/Ryujinx publish/Ryujinx.Ava
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava
tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
popd
@@ -183,10 +184,10 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- - name: Publish macOS Ryujinx.Ava
+ - name: Publish macOS Ryujinx
run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
-
+
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
diff --git a/Ryujinx.sln b/Ryujinx.sln
index 47a5c714..b8304164 100644
--- a/Ryujinx.sln
+++ b/Ryujinx.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32228.430
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{074045D4-3ED2-4711-9169-E385F2BFB5A0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Gtk3", "src\Ryujinx.Gtk3\Ryujinx.Gtk3.csproj", "{074045D4-3ED2-4711-9169-E385F2BFB5A0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests", "src\Ryujinx.Tests\Ryujinx.Tests.csproj", "{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}"
EndProject
@@ -69,7 +69,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "sr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Ava", "src\Ryujinx.Ava\Ryujinx.Ava.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
EndProject
diff --git a/distribution/linux/Ryujinx.sh b/distribution/linux/Ryujinx.sh
index 6cce4d21..30eb1439 100755
--- a/distribution/linux/Ryujinx.sh
+++ b/distribution/linux/Ryujinx.sh
@@ -6,10 +6,6 @@ if [ -f "$SCRIPT_DIR/Ryujinx.Headless.SDL2" ]; then
RYUJINX_BIN="Ryujinx.Headless.SDL2"
fi
-if [ -f "$SCRIPT_DIR/Ryujinx.Ava" ]; then
- RYUJINX_BIN="Ryujinx.Ava"
-fi
-
if [ -f "$SCRIPT_DIR/Ryujinx" ]; then
RYUJINX_BIN="Ryujinx"
fi
diff --git a/distribution/macos/create_app_bundle.sh b/distribution/macos/create_app_bundle.sh
index 858c06f5..0fa54ead 100755
--- a/distribution/macos/create_app_bundle.sh
+++ b/distribution/macos/create_app_bundle.sh
@@ -14,8 +14,8 @@ mkdir "$APP_BUNDLE_DIRECTORY/Contents/Frameworks"
mkdir "$APP_BUNDLE_DIRECTORY/Contents/MacOS"
mkdir "$APP_BUNDLE_DIRECTORY/Contents/Resources"
-# Copy executables first
-cp "$PUBLISH_DIRECTORY/Ryujinx.Ava" "$APP_BUNDLE_DIRECTORY/Contents/MacOS/Ryujinx"
+# Copy executable and nsure executable can be executed
+cp "$PUBLISH_DIRECTORY/Ryujinx" "$APP_BUNDLE_DIRECTORY/Contents/MacOS/Ryujinx"
chmod u+x "$APP_BUNDLE_DIRECTORY/Contents/MacOS/Ryujinx"
# Then all libraries
diff --git a/distribution/macos/create_macos_build_ava.sh b/distribution/macos/create_macos_build_ava.sh
index 80594a40..23eafc12 100755
--- a/distribution/macos/create_macos_build_ava.sh
+++ b/distribution/macos/create_macos_build_ava.sh
@@ -22,9 +22,9 @@ EXTRA_ARGS=$8
if [ "$VERSION" == "1.1.0" ];
then
- RELEASE_TAR_FILE_NAME=test-ava-ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.app.tar
+ RELEASE_TAR_FILE_NAME=ryujinx-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.app.tar
else
- RELEASE_TAR_FILE_NAME=test-ava-ryujinx-$VERSION-macos_universal.app.tar
+ RELEASE_TAR_FILE_NAME=ryujinx-$VERSION-macos_universal.app.tar
fi
ARM64_APP_BUNDLE="$TEMP_DIRECTORY/output_arm64/Ryujinx.app"
@@ -38,9 +38,9 @@ mkdir -p "$TEMP_DIRECTORY"
DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
dotnet restore
-dotnet build -c "$CONFIGURATION" src/Ryujinx.Ava
-dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
-dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Ava
+dotnet build -c "$CONFIGURATION" src/Ryujinx
+dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx
+dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
@@ -108,6 +108,13 @@ tar --exclude "Ryujinx.app/Contents/MacOS/Ryujinx" -cvf "$RELEASE_TAR_FILE_NAME"
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "Ryujinx.app/Contents/MacOS/Ryujinx" "Ryujinx.app/Contents/MacOS/Ryujinx"
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
rm "$RELEASE_TAR_FILE_NAME"
+
+# Create legacy update package for Avalonia to not left behind old testers.
+if [ "$VERSION" != "1.1.0" ];
+then
+ cp $RELEASE_TAR_FILE_NAME.gz test-ava-ryujinx-$VERSION-macos_universal.app.tar.gz
+fi
+
popd
echo "Done" \ No newline at end of file
diff --git a/src/Ryujinx.Ava/Program.cs b/src/Ryujinx.Ava/Program.cs
deleted file mode 100644
index aecc585f..00000000
--- a/src/Ryujinx.Ava/Program.cs
+++ /dev/null
@@ -1,237 +0,0 @@
-using Avalonia;
-using Avalonia.Threading;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.Common;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.GraphicsDriver;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.SystemInterop;
-using Ryujinx.Modules;
-using Ryujinx.SDL2.Common;
-using Ryujinx.UI.Common;
-using Ryujinx.UI.Common.Configuration;
-using Ryujinx.UI.Common.Helper;
-using Ryujinx.UI.Common.SystemInfo;
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace Ryujinx.Ava
-{
- internal partial class Program
- {
- public static double WindowScaleFactor { get; set; }
- public static double DesktopScaleFactor { get; set; } = 1.0;
- public static string Version { get; private set; }
- public static string ConfigurationPath { get; private set; }
- public static bool PreviewerDetached { get; private set; }
-
- [LibraryImport("user32.dll", SetLastError = true)]
- public static partial int MessageBoxA(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type);
-
- private const uint MbIconwarning = 0x30;
-
- public static void Main(string[] args)
- {
- Version = ReleaseInformation.Version;
-
- 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}", MbIconwarning);
- }
-
- PreviewerDetached = true;
-
- Initialize(args);
-
- LoggerAdapter.Register();
-
- BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
- }
-
- public static AppBuilder BuildAvaloniaApp()
- {
- return AppBuilder.Configure<App>()
- .UsePlatformDetect()
- .With(new X11PlatformOptions
- {
- EnableMultiTouch = true,
- EnableIme = true,
- EnableInputFocusProxy = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP") == "gamescope",
- RenderingMode = new[] { X11RenderingMode.Glx, X11RenderingMode.Software },
- })
- .With(new Win32PlatformOptions
- {
- WinUICompositionBackdropCornerRadius = 8.0f,
- RenderingMode = new[] { Win32RenderingMode.AngleEgl, Win32RenderingMode.Software },
- })
- .UseSkia();
- }
-
- private static void Initialize(string[] args)
- {
- // Parse arguments
- CommandLineState.ParseArguments(args);
-
- // Delete backup files after updating.
- Task.Run(Updater.CleanupUpdate);
-
- Console.Title = $"Ryujinx Console {Version}";
-
- // Hook unhandled exception and process exit events.
- AppDomain.CurrentDomain.UnhandledException += (sender, e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
- AppDomain.CurrentDomain.ProcessExit += (sender, e) => Exit();
-
- // Setup base data directory.
- AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
-
- // Initialize the configuration.
- ConfigurationState.Initialize();
-
- // Initialize the logger system.
- LoggerModule.Initialize();
-
- // Initialize Discord integration.
- DiscordIntegrationModule.Initialize();
-
- // Initialize SDL2 driver
- SDL2Driver.MainThreadDispatcher = action => Dispatcher.UIThread.InvokeAsync(action, DispatcherPriority.Input);
-
- ReloadConfig();
-
- WindowScaleFactor = ForceDpiAware.GetWindowScaleFactor();
-
- // Logging system information.
- PrintSystemInfo();
-
- // Enable OGL multithreading on the driver, when available.
- DriverUtilities.ToggleOGLThreading(ConfigurationState.Instance.Graphics.BackendThreading == BackendThreading.Off);
-
- // Check if keys exists.
- if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))
- {
- if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"))))
- {
- MainWindow.ShowKeyErrorOnLoad = true;
- }
- }
-
- if (CommandLineState.LaunchPathArg != null)
- {
- MainWindow.DeferLoadApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
- }
- }
-
- public static void ReloadConfig()
- {
- string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
- string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
-
- // 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}");
- }
- }
-
- // Check if graphics backend was overridden
- if (CommandLineState.OverrideGraphicsBackend != null)
- {
- if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl")
- {
- ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl;
- }
- else if (CommandLineState.OverrideGraphicsBackend.ToLower() == "vulkan")
- {
- ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.Vulkan;
- }
- }
-
- // Check if docked mode was overriden.
- if (CommandLineState.OverrideDockedMode.HasValue)
- {
- ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
- }
-
- // Check if HideCursor was overridden.
- if (CommandLineState.OverrideHideCursor is not null)
- {
- ConfigurationState.Instance.HideCursor.Value = CommandLineState.OverrideHideCursor!.ToLower() switch
- {
- "never" => HideCursorMode.Never,
- "onidle" => HideCursorMode.OnIdle,
- "always" => HideCursorMode.Always,
- _ => ConfigurationState.Instance.HideCursor.Value,
- };
- }
- }
-
- private static void PrintSystemInfo()
- {
- Logger.Notice.Print(LogClass.Application, $"Ryujinx Version: {Version}");
- SystemInfo.Gather().Print();
-
- Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(Logger.GetEnabledLevels().Count == 0 ? "<None>" : string.Join(", ", Logger.GetEnabledLevels()))}");
-
- 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)
- {
- 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();
-
- Logger.Shutdown();
- }
- }
-}
diff --git a/src/Ryujinx.Ava/Ryujinx.Ava.csproj b/src/Ryujinx.Ava/Ryujinx.Ava.csproj
deleted file mode 100644
index 91c2744f..00000000
--- a/src/Ryujinx.Ava/Ryujinx.Ava.csproj
+++ /dev/null
@@ -1,167 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFramework>net8.0</TargetFramework>
- <RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
- <OutputType>Exe</OutputType>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <Version>1.0.0-dirty</Version>
- <DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
- <SigningCertificate Condition=" '$(SigningCertificate)' == '' ">-</SigningCertificate>
- <RootNamespace>Ryujinx.Ava</RootNamespace>
- <ApplicationIcon>Ryujinx.ico</ApplicationIcon>
- <TieredPGO>true</TieredPGO>
- <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
- <ApplicationManifest>app.manifest</ApplicationManifest>
- </PropertyGroup>
-
- <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
- <Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f --deep -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
- </Target>
-
- <PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
- <PublishSingleFile>true</PublishSingleFile>
- <TrimmerSingleWarn>false</TrimmerSingleWarn>
- <PublishTrimmed>true</PublishTrimmed>
- <TrimMode>partial</TrimMode>
- </PropertyGroup>
-
- <!--
- FluentAvalonia, used in the Avalonia UI, requires a workaround for the json serializer used internally when using .NET 8+ System.Text.Json.
- See:
- https://github.com/amwx/FluentAvalonia/issues/481
- https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-8/
- -->
- <PropertyGroup>
- <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="Avalonia" />
- <PackageReference Include="Avalonia.Desktop" />
- <PackageReference Include="Avalonia.Diagnostics" Condition="'$(Configuration)'=='Debug'" />
- <PackageReference Include="Avalonia.Controls.DataGrid" />
- <PackageReference Include="Avalonia.Markup.Xaml.Loader" />
- <PackageReference Include="Avalonia.Svg" />
- <PackageReference Include="Avalonia.Svg.Skia" />
- <PackageReference Include="DynamicData" />
- <PackageReference Include="FluentAvaloniaUI" />
-
- <PackageReference Include="OpenTK.Core" />
- <PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
- <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
- <PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
- <PackageReference Include="Silk.NET.Vulkan" />
- <PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
- <PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
- <PackageReference Include="SPB" />
- <PackageReference Include="SharpZipLib" />
- <PackageReference Include="SixLabors.ImageSharp" />
-
- <!--NOTE: DO NOT REMOVE, THIS IS REQUIRED AS A RESULT OF A TRIMMING ISSUE IN AVALONIA -->
- <PackageReference Include="System.Drawing.Common" />
- </ItemGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
- <ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.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" />
- <ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
- </ItemGroup>
-
- <ItemGroup>
- <Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- <TargetPath>alsoft.ini</TargetPath>
- </Content>
- <Content Include="..\..\distribution\legal\THIRDPARTY.md">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- <TargetPath>THIRDPARTY.md</TargetPath>
- </Content>
- <Content Include="..\..\LICENSE.txt">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- <TargetPath>LICENSE.txt</TargetPath>
- </Content>
- </ItemGroup>
-
- <ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'">
- <Content Include="..\..\distribution\linux\Ryujinx.sh">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
- <Content Include="..\..\distribution\linux\mime\Ryujinx.xml">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- <TargetPath>mime\Ryujinx.xml</TargetPath>
- </Content>
- </ItemGroup>
-
- <ItemGroup>
- <AvaloniaResource Include="UI\**\*.xaml">
- <SubType>Designer</SubType>
- </AvaloniaResource>
- <AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
- <AvaloniaResource Include="Assets\Styles\Themes.xaml">
- <Generator>MSBuild:Compile</Generator>
- </AvaloniaResource>
- <AvaloniaResource Include="Assets\Styles\Styles.xaml" />
- </ItemGroup>
-
- <ItemGroup>
- <None Remove="Assets\Locales\el_GR.json" />
- <None Remove="Assets\Locales\en_US.json" />
- <None Remove="Assets\Locales\es_ES.json" />
- <None Remove="Assets\Locales\fr_FR.json" />
- <None Remove="Assets\Locales\he_IL.json" />
- <None Remove="Assets\Locales\de_DE.json" />
- <None Remove="Assets\Locales\it_IT.json" />
- <None Remove="Assets\Locales\ja_JP.json" />
- <None Remove="Assets\Locales\ko_KR.json" />
- <None Remove="Assets\Locales\pl_PL.json" />
- <None Remove="Assets\Locales\pt_BR.json" />
- <None Remove="Assets\Locales\ru_RU.json" />
- <None Remove="Assets\Locales\tr_TR.json" />
- <None Remove="Assets\Locales\uk_UA.json" />
- <None Remove="Assets\Locales\zh_CN.json" />
- <None Remove="Assets\Locales\zh_TW.json" />
- <None Remove="Assets\Styles\Styles.xaml" />
- <None Remove="Assets\Styles\Themes.xaml" />
- <None Remove="Assets\Icons\Controller_JoyConLeft.svg" />
- <None Remove="Assets\Icons\Controller_JoyConPair.svg" />
- <None Remove="Assets\Icons\Controller_JoyConRight.svg" />
- <None Remove="Assets\Icons\Controller_ProCon.svg" />
- </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\he_IL.json" />
- <EmbeddedResource Include="Assets\Locales\de_DE.json" />
- <EmbeddedResource Include="Assets\Locales\it_IT.json" />
- <EmbeddedResource Include="Assets\Locales\ja_JP.json" />
- <EmbeddedResource Include="Assets\Locales\ko_KR.json" />
- <EmbeddedResource Include="Assets\Locales\pl_PL.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\Locales\uk_UA.json" />
- <EmbeddedResource Include="Assets\Locales\zh_CN.json" />
- <EmbeddedResource Include="Assets\Locales\zh_TW.json" />
- <EmbeddedResource Include="Assets\Styles\Styles.xaml" />
- <EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
- <EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
- <EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
- <EmbeddedResource Include="Assets\Icons\Controller_ProCon.svg" />
- </ItemGroup>
- <ItemGroup>
- <AdditionalFiles Include="Assets\Locales\en_US.json" />
- </ItemGroup>
-</Project>
diff --git a/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs
index ff7a2c3b..ff7a2c3b 100644
--- a/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs
+++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Keyboard.cs
diff --git a/src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3KeyboardDriver.cs
index e502254b..e502254b 100644
--- a/src/Ryujinx/Input/GTK3/GTK3KeyboardDriver.cs
+++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3KeyboardDriver.cs
diff --git a/src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3MappingHelper.cs
index 422a9603..422a9603 100644
--- a/src/Ryujinx/Input/GTK3/GTK3MappingHelper.cs
+++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3MappingHelper.cs
diff --git a/src/Ryujinx/Input/GTK3/GTK3Mouse.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs
index 0ab817ec..0ab817ec 100644
--- a/src/Ryujinx/Input/GTK3/GTK3Mouse.cs
+++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3Mouse.cs
diff --git a/src/Ryujinx/Input/GTK3/GTK3MouseDriver.cs b/src/Ryujinx.Gtk3/Input/GTK3/GTK3MouseDriver.cs
index 5962bcb2..5962bcb2 100644
--- a/src/Ryujinx/Input/GTK3/GTK3MouseDriver.cs
+++ b/src/Ryujinx.Gtk3/Input/GTK3/GTK3MouseDriver.cs
diff --git a/src/Ryujinx/Modules/Updater/UpdateDialog.cs b/src/Ryujinx.Gtk3/Modules/Updater/UpdateDialog.cs
index ec24cdc8..43bde942 100644
--- a/src/Ryujinx/Modules/Updater/UpdateDialog.cs
+++ b/src/Ryujinx.Gtk3/Modules/Updater/UpdateDialog.cs
@@ -25,7 +25,7 @@ namespace Ryujinx.Modules
private readonly string _buildUrl;
private bool _restartQuery;
- public UpdateDialog(MainWindow mainWindow, Version newVersion, string buildUrl) : this(new Builder("Ryujinx.Modules.Updater.UpdateDialog.glade"), mainWindow, newVersion, buildUrl) { }
+ public UpdateDialog(MainWindow mainWindow, Version newVersion, string buildUrl) : this(new Builder("Ryujinx.Gtk3.Modules.Updater.UpdateDialog.glade"), mainWindow, newVersion, buildUrl) { }
private UpdateDialog(Builder builder, MainWindow mainWindow, Version newVersion, string buildUrl) : base(builder.GetRawOwnedObject("UpdateDialog"))
{
@@ -34,7 +34,7 @@ namespace Ryujinx.Modules
_mainWindow = mainWindow;
_buildUrl = buildUrl;
- Icon = new Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.UI.Common.Resources.Logo_Ryujinx.png");
+ Icon = new Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Gtk3.UI.Common.Resources.Logo_Ryujinx.png");
MainText.Text = "Do you want to update Ryujinx to the latest version?";
SecondaryText.Text = $"{Program.Version} -> {newVersion}";
diff --git a/src/Ryujinx/Modules/Updater/UpdateDialog.glade b/src/Ryujinx.Gtk3/Modules/Updater/UpdateDialog.glade
index cc80167e..cc80167e 100644
--- a/src/Ryujinx/Modules/Updater/UpdateDialog.glade
+++ b/src/Ryujinx.Gtk3/Modules/Updater/UpdateDialog.glade
diff --git a/src/Ryujinx.Ava/Modules/Updater/Updater.cs b/src/Ryujinx.Gtk3/Modules/Updater/Updater.cs
index 5795f34f..8b006f63 100644
--- a/src/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/src/Ryujinx.Gtk3/Modules/Updater/Updater.cs
@@ -1,75 +1,93 @@
-using Avalonia.Controls;
-using Avalonia.Threading;
-using FluentAvalonia.UI.Controls;
+using Gtk;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
-using Ryujinx.Ava;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
-using Ryujinx.UI.Common.Helper;
+using Ryujinx.UI;
using Ryujinx.UI.Common.Models.Github;
+using Ryujinx.UI.Widgets;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Modules
{
- internal static class Updater
+ public static class Updater
{
private const string GitHubApiUrl = "https://api.github.com";
- private static readonly GithubReleasesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
+ private const int ConnectionCount = 4;
+
+ 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 const int ConnectionCount = 4;
private static string _buildVer;
private static string _platformExt;
private static string _buildUrl;
private static long _buildSize;
- private static bool _updateSuccessful;
- private static bool _running;
- private static readonly string[] _windowsDependencyDirs = Array.Empty<string>();
+ private static readonly GithubReleasesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
+
+ // On Windows, GtkSharp.Dependencies adds these extra dirs that must be cleaned during updates.
+ private static readonly string[] _windowsDependencyDirs = { "bin", "etc", "lib", "share" };
- public static async Task BeginParse(Window mainWindow, bool showVersionUpToDate)
+ private static HttpClient ConstructHttpClient()
{
- if (_running)
+ HttpClient result = new();
+
+ // Required by GitHub to interact with APIs.
+ result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
+
+ return result;
+ }
+
+ public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
+ {
+ if (Running)
{
return;
}
- _running = true;
+ Running = true;
+ mainWindow.UpdateMenuItem.Sensitive = false;
+
+ int artifactIndex = -1;
// Detect current platform
if (OperatingSystem.IsMacOS())
{
- _platformExt = "macos_universal.app.tar.gz";
+ _platformExt = "osx_x64.zip";
+ artifactIndex = 1;
}
else if (OperatingSystem.IsWindows())
{
_platformExt = "win_x64.zip";
+ artifactIndex = 2;
}
else if (OperatingSystem.IsLinux())
{
var arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64";
_platformExt = $"linux_{arch}.tar.gz";
+ artifactIndex = 0;
+ }
+
+ if (artifactIndex == -1)
+ {
+ GtkDialog.CreateErrorDialog("Your platform is not supported!");
+
+ return;
}
Version newVersion;
@@ -81,14 +99,9 @@ namespace Ryujinx.Modules
}
catch
{
+ GtkDialog.CreateWarningDialog("Failed to convert the current Ryujinx version.", "Cancelling Update!");
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
- await ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
-
- _running = false;
-
return;
}
@@ -96,15 +109,16 @@ namespace Ryujinx.Modules
try
{
using HttpClient jsonClient = ConstructHttpClient();
-
string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
+
+ // Fetch latest build information
string fetchedJson = await jsonClient.GetStringAsync(buildInfoUrl);
var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse);
_buildVer = fetched.Name;
foreach (var asset in fetched.Assets)
{
- if (asset.Name.StartsWith("test-ava-ryujinx") && asset.Name.EndsWith(_platformExt))
+ if (asset.Name.StartsWith("gtk-ryujinx") && asset.Name.EndsWith(_platformExt))
{
_buildUrl = asset.BrowserDownloadUrl;
@@ -112,13 +126,9 @@ namespace Ryujinx.Modules
{
if (showVersionUpToDate)
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
- "");
+ GtkDialog.CreateUpdaterInfoDialog("You are already using the latest version of Ryujinx!", "");
}
- _running = false;
-
return;
}
@@ -126,29 +136,20 @@ namespace Ryujinx.Modules
}
}
- // If build not done, assume no new update are available.
- if (_buildUrl is null)
+ if (_buildUrl == null)
{
if (showVersionUpToDate)
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
- "");
+ GtkDialog.CreateUpdaterInfoDialog("You are already using the latest version of Ryujinx!", "");
}
- _running = false;
-
return;
}
}
catch (Exception exception)
{
Logger.Error?.Print(LogClass.Application, exception.Message);
-
- await ContentDialogHelper.CreateErrorDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterFailedToGetVersionMessage]);
-
- _running = false;
+ GtkDialog.CreateErrorDialog("An error 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.");
return;
}
@@ -159,13 +160,8 @@ namespace Ryujinx.Modules
}
catch
{
- Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
-
- await ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
-
- _running = false;
+ GtkDialog.CreateWarningDialog("Failed to convert the received Ryujinx version from GitHub Release.", "Cancelling Update!");
+ Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from GitHub Release!");
return;
}
@@ -174,12 +170,11 @@ namespace Ryujinx.Modules
{
if (showVersionUpToDate)
{
- await ContentDialogHelper.CreateUpdaterInfoDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
- "");
+ GtkDialog.CreateUpdaterInfoDialog("You are already using the latest version of Ryujinx!", "");
}
- _running = false;
+ Running = false;
+ mainWindow.UpdateMenuItem.Sensitive = true;
return;
}
@@ -202,39 +197,13 @@ namespace Ryujinx.Modules
_buildSize = -1;
}
- await Dispatcher.UIThread.InvokeAsync(async () =>
- {
- // Show a message asking the user if they want to update
- var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(
- LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
- LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
- $"{Program.Version} -> {newVersion}");
-
- if (shouldUpdate)
- {
- await UpdateRyujinx(mainWindow, _buildUrl);
- }
- else
- {
- _running = false;
- }
- });
- }
-
- private static HttpClient ConstructHttpClient()
- {
- HttpClient result = new();
-
- // Required by GitHub to interact with APIs.
- result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
-
- return result;
+ // Show a message asking the user if they want to update
+ UpdateDialog updateDialog = new(mainWindow, newVersion, _buildUrl);
+ updateDialog.Show();
}
- private static async Task UpdateRyujinx(Window parent, string downloadUrl)
+ public static void UpdateRyujinx(UpdateDialog updateDialog, string downloadUrl)
{
- _updateSuccessful = false;
-
// Empty update dir, although it shouldn't ever have anything inside it
if (Directory.Exists(_updateDir))
{
@@ -245,93 +214,22 @@ namespace Ryujinx.Modules
string updateFile = Path.Combine(_updateDir, "update.bin");
- TaskDialog taskDialog = new()
- {
- Header = LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
- SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading],
- IconSource = new SymbolIconSource { Symbol = Symbol.Download },
- ShowProgressBar = true,
- XamlRoot = parent,
- };
+ // Download the update .zip
+ updateDialog.MainText.Text = "Downloading Update...";
+ updateDialog.ProgressBar.Value = 0;
+ updateDialog.ProgressBar.MaxValue = 100;
- taskDialog.Opened += (s, e) =>
+ if (_buildSize >= 0)
{
- if (_buildSize >= 0)
- {
- DoUpdateWithMultipleThreads(taskDialog, downloadUrl, updateFile);
- }
- else
- {
- DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
- }
- };
-
- await taskDialog.ShowAsync(true);
-
- if (_updateSuccessful)
+ DoUpdateWithMultipleThreads(updateDialog, downloadUrl, updateFile);
+ }
+ else
{
- bool shouldRestart = true;
-
- if (!OperatingSystem.IsMacOS())
- {
- shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
- }
-
- if (shouldRestart)
- {
- List<string> arguments = CommandLineState.Arguments.ToList();
- string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
-
- // On macOS we perform the update at relaunch.
- if (OperatingSystem.IsMacOS())
- {
- string baseBundlePath = Path.GetFullPath(Path.Combine(executableDirectory, "..", ".."));
- string newBundlePath = Path.Combine(_updateDir, "Ryujinx.app");
- string updaterScriptPath = Path.Combine(newBundlePath, "Contents", "Resources", "updater.sh");
- string currentPid = Environment.ProcessId.ToString();
-
- arguments.InsertRange(0, new List<string> { updaterScriptPath, baseBundlePath, newBundlePath, currentPid });
- Process.Start("/bin/bash", arguments);
- }
- else
- {
- // Find the process name.
- string ryuName = Path.GetFileName(Environment.ProcessPath);
-
- // Some operating systems can see the renamed executable, so strip off the .ryuold if found.
- if (ryuName.EndsWith(".ryuold"))
- {
- ryuName = ryuName[..^7];
- }
-
- // Fallback if the executable could not be found.
- if (!Path.Exists(Path.Combine(executableDirectory, ryuName)))
- {
- ryuName = OperatingSystem.IsWindows() ? "Ryujinx.Ava.exe" : "Ryujinx.Ava";
- }
-
- ProcessStartInfo processStart = new(ryuName)
- {
- UseShellExecute = true,
- WorkingDirectory = executableDirectory,
- };
-
- foreach (string argument in CommandLineState.Arguments)
- {
- processStart.ArgumentList.Add(argument);
- }
-
- Process.Start(processStart);
- }
-
- Environment.Exit(0);
- }
+ DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
}
}
- private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithMultipleThreads(UpdateDialog updateDialog, string downloadUrl, string updateFile)
{
// Multi-Threaded Updater
long chunkSize = _buildSize / ConnectionCount;
@@ -355,7 +253,6 @@ namespace Ryujinx.Modules
// TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient.
using WebClient client = new();
#pragma warning restore SYSLIB0014
-
webClients.Add(client);
if (i == ConnectionCount - 1)
@@ -375,7 +272,7 @@ namespace Ryujinx.Modules
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
- taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
+ updateDialog.ProgressBar.Value = totalProgressPercentage / ConnectionCount;
};
client.DownloadDataCompleted += (_, args) =>
@@ -386,8 +283,6 @@ namespace Ryujinx.Modules
{
webClients[index].Dispose();
- taskDialog.Hide();
-
return;
}
@@ -405,24 +300,18 @@ namespace Ryujinx.Modules
File.WriteAllBytes(updateFile, mergedFileBytes);
- // On macOS, ensure that we remove the quarantine bit to prevent Gatekeeper from blocking execution.
- if (OperatingSystem.IsMacOS())
- {
- using Process xattrProcess = Process.Start("xattr", new List<string> { "-d", "com.apple.quarantine", updateFile });
-
- xattrProcess.WaitForExit();
- }
-
try
{
- InstallUpdate(taskDialog, updateFile);
+ 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(taskDialog, downloadUrl, updateFile);
+ DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
+
+ return;
}
}
};
@@ -441,14 +330,14 @@ namespace Ryujinx.Modules
webClient.CancelAsync();
}
- DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
+ DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
return;
}
}
}
- private static void DoUpdateWithSingleThreadWorker(TaskDialog taskDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithSingleThreadWorker(UpdateDialog updateDialog, string downloadUrl, string updateFile)
{
using HttpClient client = new();
// We do not want to timeout while downloading
@@ -474,165 +363,151 @@ namespace Ryujinx.Modules
byteWritten += readSize;
- taskDialog.SetProgressBarState(GetPercentage(byteWritten, totalBytes), TaskDialogProgressState.Normal);
-
+ updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
updateFileStream.Write(buffer, 0, readSize);
}
- InstallUpdate(taskDialog, updateFile);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static double GetPercentage(double value, double max)
- {
- return max == 0 ? 0 : value / max * 100;
+ InstallUpdate(updateDialog, updateFile);
}
- private static void DoUpdateWithSingleThread(TaskDialog taskDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithSingleThread(UpdateDialog updateDialog, string downloadUrl, string updateFile)
{
- Thread worker = new(() => DoUpdateWithSingleThreadWorker(taskDialog, downloadUrl, updateFile))
+ Thread worker = new(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile))
{
Name = "Updater.SingleThreadWorker",
};
-
worker.Start();
}
- [SupportedOSPlatform("linux")]
- [SupportedOSPlatform("macos")]
- private static void ExtractTarGzipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
+ private static async void InstallUpdate(UpdateDialog updateDialog, string updateFile)
{
- using Stream inStream = File.OpenRead(archivePath);
- using GZipInputStream gzipStream = new(inStream);
- using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
-
- TarEntry tarEntry;
+ // Extract Update
+ updateDialog.MainText.Text = "Extracting Update...";
+ updateDialog.ProgressBar.Value = 0;
- while ((tarEntry = tarStream.GetNextEntry()) is not null)
+ if (OperatingSystem.IsLinux())
{
- if (tarEntry.IsDirectory)
+ using Stream inStream = File.OpenRead(updateFile);
+ using Stream gzipStream = new GZipInputStream(inStream);
+ using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
+ updateDialog.ProgressBar.MaxValue = inStream.Length;
+
+ await Task.Run(() =>
{
- continue;
- }
+ TarEntry tarEntry;
- string outPath = Path.Combine(outputDirectoryPath, tarEntry.Name);
+ if (!OperatingSystem.IsWindows())
+ {
+ while ((tarEntry = tarStream.GetNextEntry()) != null)
+ {
+ if (tarEntry.IsDirectory)
+ {
+ continue;
+ }
- Directory.CreateDirectory(Path.GetDirectoryName(outPath));
+ string outPath = Path.Combine(_updateDir, tarEntry.Name);
- using FileStream outStream = File.OpenWrite(outPath);
- tarStream.CopyEntryContents(outStream);
+ Directory.CreateDirectory(Path.GetDirectoryName(outPath));
- File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
- File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
+ using FileStream outStream = File.OpenWrite(outPath);
+ tarStream.CopyEntryContents(outStream);
- Dispatcher.UIThread.Post(() =>
- {
- if (tarEntry is null)
- {
- return;
- }
+ File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
+ File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
- taskDialog.SetProgressBarState(GetPercentage(tarEntry.Size, inStream.Length), TaskDialogProgressState.Normal);
- });
- }
- }
+ TarEntry entry = tarEntry;
- private static void ExtractZipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
- {
- using Stream inStream = File.OpenRead(archivePath);
- using ZipFile zipFile = new(inStream);
+ Application.Invoke(delegate
+ {
+ updateDialog.ProgressBar.Value += entry.Size;
+ });
+ }
+ }
+ });
- double count = 0;
- foreach (ZipEntry zipEntry in zipFile)
+ updateDialog.ProgressBar.Value = inStream.Length;
+ }
+ else
{
- count++;
- if (zipEntry.IsDirectory)
- {
- continue;
- }
+ using Stream inStream = File.OpenRead(updateFile);
+ using ZipFile zipFile = new(inStream);
+ updateDialog.ProgressBar.MaxValue = zipFile.Count;
- string outPath = Path.Combine(outputDirectoryPath, zipEntry.Name);
+ await Task.Run(() =>
+ {
+ foreach (ZipEntry zipEntry in zipFile)
+ {
+ if (zipEntry.IsDirectory)
+ {
+ continue;
+ }
- Directory.CreateDirectory(Path.GetDirectoryName(outPath));
+ string outPath = Path.Combine(_updateDir, zipEntry.Name);
- using Stream zipStream = zipFile.GetInputStream(zipEntry);
- using FileStream outStream = File.OpenWrite(outPath);
+ Directory.CreateDirectory(Path.GetDirectoryName(outPath));
- zipStream.CopyTo(outStream);
+ using Stream zipStream = zipFile.GetInputStream(zipEntry);
+ using FileStream outStream = File.OpenWrite(outPath);
+ zipStream.CopyTo(outStream);
- File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
+ File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
- Dispatcher.UIThread.Post(() =>
- {
- taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
+ Application.Invoke(delegate
+ {
+ updateDialog.ProgressBar.Value++;
+ });
+ }
});
}
- }
-
- private static void InstallUpdate(TaskDialog taskDialog, string updateFile)
- {
- // Extract Update
- taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterExtracting];
- taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
-
- if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
- {
- ExtractTarGzipFile(taskDialog, updateFile, _updateDir);
- }
- else if (OperatingSystem.IsWindows())
- {
- ExtractZipFile(taskDialog, updateFile, _updateDir);
- }
- else
- {
- throw new NotSupportedException();
- }
// Delete downloaded zip
File.Delete(updateFile);
List<string> allFiles = EnumerateFilesToDelete().ToList();
- taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterRenaming];
- taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
+ updateDialog.MainText.Text = "Renaming Old Files...";
+ updateDialog.ProgressBar.Value = 0;
+ updateDialog.ProgressBar.MaxValue = allFiles.Count;
- // NOTE: On macOS, replacement is delayed to the restart phase.
- if (!OperatingSystem.IsMacOS())
+ // Replace old files
+ await Task.Run(() =>
{
- // Replace old files
- double count = 0;
foreach (string file in allFiles)
{
- count++;
try
{
File.Move(file, file + ".ryuold");
- Dispatcher.UIThread.InvokeAsync(() =>
+ Application.Invoke(delegate
{
- taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
+ updateDialog.ProgressBar.Value++;
});
}
catch
{
- Logger.Warning?.Print(LogClass.Application, LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.UpdaterRenameFailed, file));
+ Logger.Warning?.Print(LogClass.Application, "Updater was unable to rename file: " + file);
}
}
- Dispatcher.UIThread.InvokeAsync(() =>
+ Application.Invoke(delegate
{
- taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterAddingFiles];
- taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
+ updateDialog.MainText.Text = "Adding New Files...";
+ updateDialog.ProgressBar.Value = 0;
+ updateDialog.ProgressBar.MaxValue = Directory.GetFiles(_updatePublishDir, "*", SearchOption.AllDirectories).Length;
});
- MoveAllFilesOver(_updatePublishDir, _homeDir, taskDialog);
+ MoveAllFilesOver(_updatePublishDir, _homeDir, updateDialog);
+ });
- Directory.Delete(_updateDir, true);
- }
+ Directory.Delete(_updateDir, true);
- _updateSuccessful = true;
+ updateDialog.MainText.Text = "Update Complete!";
+ updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?";
+ updateDialog.Modal = true;
- taskDialog.Hide();
+ updateDialog.ProgressBar.Hide();
+ updateDialog.YesButton.Show();
+ updateDialog.NoButton.Show();
}
public static bool CanUpdate(bool showWarnings)
@@ -642,11 +517,7 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- Dispatcher.UIThread.InvokeAsync(() =>
- ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterNoInternetMessage],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterNoInternetSubMessage])
- );
+ GtkDialog.CreateWarningDialog("You are not connected to the Internet!", "Please verify that you have a working Internet connection!");
}
return false;
@@ -656,11 +527,7 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- Dispatcher.UIThread.InvokeAsync(() =>
- ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildMessage],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildSubMessage])
- );
+ GtkDialog.CreateWarningDialog("You cannot update a Dirty build of Ryujinx!", "Please download Ryujinx at https://ryujinx.org/ if you are looking for a supported version.");
}
return false;
@@ -672,19 +539,11 @@ namespace Ryujinx.Modules
{
if (ReleaseInformation.IsFlatHubBuild)
{
- Dispatcher.UIThread.InvokeAsync(() =>
- ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.UpdaterDisabledWarningTitle],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterFlatpakNotSupportedMessage])
- );
+ GtkDialog.CreateWarningDialog("Updater Disabled!", "Please update Ryujinx via FlatHub.");
}
else
{
- Dispatcher.UIThread.InvokeAsync(() =>
- ContentDialogHelper.CreateWarningDialog(
- LocaleManager.Instance[LocaleKeys.UpdaterDisabledWarningTitle],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildSubMessage])
- );
+ GtkDialog.CreateWarningDialog("Updater Disabled!", "Please download Ryujinx at https://ryujinx.org/ if you are looking for a supported version.");
}
}
@@ -698,7 +557,7 @@ namespace Ryujinx.Modules
var files = Directory.EnumerateFiles(_homeDir); // All files directly in base dir.
// Determine and exclude user files only when the updater is running, not when cleaning old files
- if (_running && !OperatingSystem.IsMacOS())
+ if (Running)
{
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
var oldFiles = Directory.EnumerateFiles(_homeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
@@ -724,9 +583,8 @@ namespace Ryujinx.Modules
return files.Where(f => !new FileInfo(f).Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
}
- private static void MoveAllFilesOver(string root, string dest, TaskDialog taskDialog)
+ private static void MoveAllFilesOver(string root, string dest, UpdateDialog dialog)
{
- int total = Directory.GetFiles(root, "*", SearchOption.AllDirectories).Length;
foreach (string directory in Directory.GetDirectories(root))
{
string dirName = Path.GetFileName(directory);
@@ -736,28 +594,28 @@ namespace Ryujinx.Modules
Directory.CreateDirectory(Path.Combine(dest, dirName));
}
- MoveAllFilesOver(directory, Path.Combine(dest, dirName), taskDialog);
+ MoveAllFilesOver(directory, Path.Combine(dest, dirName), dialog);
}
- double count = 0;
foreach (string file in Directory.GetFiles(root))
{
- count++;
-
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
- Dispatcher.UIThread.InvokeAsync(() =>
+ Application.Invoke(delegate
{
- taskDialog.SetProgressBarState(GetPercentage(count, total), TaskDialogProgressState.Normal);
+ dialog.ProgressBar.Value++;
});
}
}
public static void CleanupUpdate()
{
- foreach (string file in Directory.GetFiles(_homeDir, "*.ryuold", SearchOption.AllDirectories))
+ foreach (string file in EnumerateFilesToDelete())
{
- File.Delete(file);
+ if (Path.GetExtension(file).EndsWith(".ryuold"))
+ {
+ File.Delete(file);
+ }
}
}
}
diff --git a/src/Ryujinx.Gtk3/Program.cs b/src/Ryujinx.Gtk3/Program.cs
new file mode 100644
index 00000000..1845c512
--- /dev/null
+++ b/src/Ryujinx.Gtk3/Program.cs
@@ -0,0 +1,378 @@
+using Gtk;
+using Ryujinx.Common;
+using Ryujinx.Common.Configuration;
+using Ryujinx.Common.GraphicsDriver;
+using Ryujinx.Common.Logging;
+using Ryujinx.Common.SystemInterop;
+using Ryujinx.Modules;
+using Ryujinx.SDL2.Common;
+using Ryujinx.UI;
+using Ryujinx.UI.Common;
+using Ryujinx.UI.Common.Configuration;
+using Ryujinx.UI.Common.Helper;
+using Ryujinx.UI.Common.SystemInfo;
+using Ryujinx.UI.Widgets;
+using SixLabors.ImageSharp.Formats.Jpeg;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Ryujinx
+{
+ partial class Program
+ {
+ public static double WindowScaleFactor { get; private set; }
+
+ public static string Version { get; private set; }
+
+ public static string ConfigurationPath { get; set; }
+
+ public static string CommandLineProfile { get; set; }
+
+ private const string X11LibraryName = "libX11";
+
+ [LibraryImport(X11LibraryName)]
+ private static partial int XInitThreads();
+
+ [LibraryImport("user32.dll", SetLastError = true)]
+ public static partial int MessageBoxA(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type);
+
+ [LibraryImport("libc", SetLastError = true)]
+ private static partial int setenv([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int overwrite);
+
+ private const uint MbIconWarning = 0x30;
+
+ static Program()
+ {
+ if (OperatingSystem.IsLinux())
+ {
+ NativeLibrary.SetDllImportResolver(typeof(Program).Assembly, (name, assembly, path) =>
+ {
+ if (name != X11LibraryName)
+ {
+ return IntPtr.Zero;
+ }
+
+ if (!NativeLibrary.TryLoad("libX11.so.6", assembly, path, out IntPtr result))
+ {
+ if (!NativeLibrary.TryLoad("libX11.so", assembly, path, out result))
+ {
+ return IntPtr.Zero;
+ }
+ }
+
+ return result;
+ });
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ Version = ReleaseInformation.Version;
+
+ 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}", MbIconWarning);
+ }
+
+ // Parse arguments
+ CommandLineState.ParseArguments(args);
+
+ // Hook unhandled exception and process exit events.
+ GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
+ AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
+ AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit();
+
+ // 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}";
+
+ // NOTE: GTK3 doesn't init X11 in a multi threaded way.
+ // This ends up causing race condition and abort of XCB when a context is created by SPB (even if SPB do call XInitThreads).
+ if (OperatingSystem.IsLinux())
+ {
+ if (XInitThreads() == 0)
+ {
+ throw new NotSupportedException("Failed to initialize multi-threading support.");
+ }
+
+ Environment.SetEnvironmentVariable("GDK_BACKEND", "x11");
+ setenv("GDK_BACKEND", "x11", 1);
+ }
+
+ if (OperatingSystem.IsMacOS())
+ {
+ string baseDirectory = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
+ string resourcesDataDir;
+
+ if (Path.GetFileName(baseDirectory) == "MacOS")
+ {
+ resourcesDataDir = Path.Combine(Directory.GetParent(baseDirectory).FullName, "Resources");
+ }
+ else
+ {
+ resourcesDataDir = baseDirectory;
+ }
+
+ static void SetEnvironmentVariableNoCaching(string key, string value)
+ {
+ int res = setenv(key, value, 1);
+ Debug.Assert(res != -1);
+ }
+
+ // On macOS, GTK3 needs XDG_DATA_DIRS to be set, otherwise it will try searching for "gschemas.compiled" in system directories.
+ SetEnvironmentVariableNoCaching("XDG_DATA_DIRS", Path.Combine(resourcesDataDir, "share"));
+
+ // On macOS, GTK3 needs GDK_PIXBUF_MODULE_FILE to be set, otherwise it will try searching for "loaders.cache" in system directories.
+ SetEnvironmentVariableNoCaching("GDK_PIXBUF_MODULE_FILE", Path.Combine(resourcesDataDir, "lib", "gdk-pixbuf-2.0", "2.10.0", "loaders.cache"));
+
+ SetEnvironmentVariableNoCaching("GTK_IM_MODULE_FILE", Path.Combine(resourcesDataDir, "lib", "gtk-3.0", "3.0.0", "immodules.cache"));
+ }
+
+ string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
+ Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPath}");
+
+ // Setup base data directory.
+ AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
+
+ // Initialize the configuration.
+ ConfigurationState.Initialize();
+
+ // Initialize the logger system.
+ LoggerModule.Initialize();
+
+ // Initialize Discord integration.
+ DiscordIntegrationModule.Initialize();
+
+ // Initialize SDL2 driver
+ SDL2Driver.MainThreadDispatcher = action =>
+ {
+ Application.Invoke(delegate
+ {
+ action();
+ });
+ };
+
+ // Sets ImageSharp Jpeg Encoder Quality.
+ SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder()
+ {
+ Quality = 100,
+ });
+
+ string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
+ string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
+
+ // Now load the configuration as the other subsystems are now registered
+ ConfigurationPath = File.Exists(localConfigurationPath)
+ ? localConfigurationPath
+ : File.Exists(appDataConfigurationPath)
+ ? appDataConfigurationPath
+ : null;
+
+ 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}");
+ }
+ }
+
+ // Check if graphics backend was overridden.
+ if (CommandLineState.OverrideGraphicsBackend != null)
+ {
+ if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl")
+ {
+ ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl;
+ }
+ else if (CommandLineState.OverrideGraphicsBackend.ToLower() == "vulkan")
+ {
+ ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.Vulkan;
+ }
+ }
+
+ // Check if HideCursor was overridden.
+ if (CommandLineState.OverrideHideCursor is not null)
+ {
+ ConfigurationState.Instance.HideCursor.Value = CommandLineState.OverrideHideCursor!.ToLower() switch
+ {
+ "never" => HideCursorMode.Never,
+ "onidle" => HideCursorMode.OnIdle,
+ "always" => HideCursorMode.Always,
+ _ => ConfigurationState.Instance.HideCursor.Value,
+ };
+ }
+
+ // Check if docked mode was overridden.
+ if (CommandLineState.OverrideDockedMode.HasValue)
+ {
+ ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
+ }
+
+ // Logging system information.
+ PrintSystemInfo();
+
+ // Enable OGL multithreading on the driver, when available.
+ BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
+ DriverUtilities.ToggleOGLThreading(threadingMode == BackendThreading.Off);
+
+ // Initialize Gtk.
+ Application.Init();
+
+ // Check if keys exists.
+ bool hasSystemProdKeys = File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"));
+ bool hasCommonProdKeys = AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"));
+ if (!hasSystemProdKeys && !hasCommonProdKeys)
+ {
+ UserErrorDialog.CreateUserErrorDialog(UserError.NoKeys);
+ }
+
+ // Show the main window UI.
+ MainWindow mainWindow = new();
+ mainWindow.Show();
+
+ if (OperatingSystem.IsLinux())
+ {
+ int currentVmMaxMapCount = LinuxHelper.VmMaxMapCount;
+
+ if (LinuxHelper.VmMaxMapCount < LinuxHelper.RecommendedVmMaxMapCount)
+ {
+ Logger.Warning?.Print(LogClass.Application, $"The value of vm.max_map_count is lower than {LinuxHelper.RecommendedVmMaxMapCount}. ({currentVmMaxMapCount})");
+
+ if (LinuxHelper.PkExecPath is not null)
+ {
+ var buttonTexts = new Dictionary<int, string>()
+ {
+ { 0, "Yes, until the next restart" },
+ { 1, "Yes, permanently" },
+ { 2, "No" },
+ };
+
+ ResponseType response = GtkDialog.CreateCustomDialog(
+ "Ryujinx - Low limit for memory mappings detected",
+ $"Would you like to increase the value of vm.max_map_count to {LinuxHelper.RecommendedVmMaxMapCount}?",
+ "Some games might try to create more memory mappings than currently allowed. " +
+ "Ryujinx will crash as soon as this limit gets exceeded.",
+ buttonTexts,
+ MessageType.Question);
+
+ int rc;
+
+ switch ((int)response)
+ {
+ case 0:
+ rc = LinuxHelper.RunPkExec($"echo {LinuxHelper.RecommendedVmMaxMapCount} > {LinuxHelper.VmMaxMapCountPath}");
+ if (rc == 0)
+ {
+ Logger.Info?.Print(LogClass.Application, $"vm.max_map_count set to {LinuxHelper.VmMaxMapCount} until the next restart.");
+ }
+ else
+ {
+ Logger.Error?.Print(LogClass.Application, $"Unable to change vm.max_map_count. Process exited with code: {rc}");
+ }
+ break;
+ case 1:
+ rc = LinuxHelper.RunPkExec($"echo \"vm.max_map_count = {LinuxHelper.RecommendedVmMaxMapCount}\" > {LinuxHelper.SysCtlConfigPath} && sysctl -p {LinuxHelper.SysCtlConfigPath}");
+ if (rc == 0)
+ {
+ Logger.Info?.Print(LogClass.Application, $"vm.max_map_count set to {LinuxHelper.VmMaxMapCount}. Written to config: {LinuxHelper.SysCtlConfigPath}");
+ }
+ else
+ {
+ Logger.Error?.Print(LogClass.Application, $"Unable to write new value for vm.max_map_count to config. Process exited with code: {rc}");
+ }
+ break;
+ }
+ }
+ else
+ {
+ GtkDialog.CreateWarningDialog(
+ "Max amount of memory mappings is lower than recommended.",
+ $"The current value of vm.max_map_count ({currentVmMaxMapCount}) is lower than {LinuxHelper.RecommendedVmMaxMapCount}." +
+ "Some games might try to create more memory mappings than currently allowed. " +
+ "Ryujinx will crash as soon as this limit gets exceeded.\n\n" +
+ "You might want to either manually increase the limit or install pkexec, which allows Ryujinx to assist with that.");
+ }
+ }
+ }
+
+ if (CommandLineState.LaunchPathArg != null)
+ {
+ mainWindow.RunApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
+ }
+
+ if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false))
+ {
+ Updater.BeginParse(mainWindow, false).ContinueWith(task =>
+ {
+ Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}");
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ }
+
+ Application.Run();
+ }
+
+ 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)
+ {
+ 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();
+
+ Logger.Shutdown();
+ }
+ }
+}
diff --git a/src/Ryujinx.Gtk3/Ryujinx.Gtk3.csproj b/src/Ryujinx.Gtk3/Ryujinx.Gtk3.csproj
new file mode 100644
index 00000000..68bf9898
--- /dev/null
+++ b/src/Ryujinx.Gtk3/Ryujinx.Gtk3.csproj
@@ -0,0 +1,104 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net8.0</TargetFramework>
+ <RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
+ <OutputType>Exe</OutputType>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <Version>1.0.0-dirty</Version>
+ <DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
+ <!-- As we already provide GTK3 on Windows via GtkSharp.Dependencies this is redundant. -->
+ <SkipGtkInstall>true</SkipGtkInstall>
+ <TieredPGO>true</TieredPGO>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
+ <PublishSingleFile>true</PublishSingleFile>
+ <TrimmerSingleWarn>false</TrimmerSingleWarn>
+ <PublishTrimmed>true</PublishTrimmed>
+ <TrimMode>partial</TrimMode>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Ryujinx.GtkSharp" />
+ <PackageReference Include="GtkSharp.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
+ <PackageReference Include="GtkSharp.Dependencies.osx" Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'" />
+ <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
+ <PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
+ <PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
+ <PackageReference Include="OpenTK.Core" />
+ <PackageReference Include="OpenTK.Graphics" />
+ <PackageReference Include="SPB" />
+ <PackageReference Include="SharpZipLib" />
+ <PackageReference Include="SixLabors.ImageSharp" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <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.SDL2\Ryujinx.Audio.Backends.SDL2.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.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
+ <ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
+ <ProjectReference Include="..\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <TargetPath>alsoft.ini</TargetPath>
+ </Content>
+ <Content Include="..\..\distribution\legal\THIRDPARTY.md">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <TargetPath>THIRDPARTY.md</TargetPath>
+ </Content>
+ <Content Include="..\..\LICENSE.txt">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <TargetPath>LICENSE.txt</TargetPath>
+ </Content>
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64'">
+ <Content Include="..\..\distribution\linux\Ryujinx.sh">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="..\..\distribution\linux\mime\Ryujinx.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <TargetPath>mime\Ryujinx.xml</TargetPath>
+ </Content>
+ </ItemGroup>
+
+ <!-- Due to .net core 3.1 embedded resource loading -->
+ <PropertyGroup>
+ <EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
+ <ApplicationIcon>Ryujinx.ico</ApplicationIcon>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <None Remove="UI\MainWindow.glade" />
+ <None Remove="UI\Widgets\ProfileDialog.glade" />
+ <None Remove="UI\Windows\CheatWindow.glade" />
+ <None Remove="UI\Windows\ControllerWindow.glade" />
+ <None Remove="UI\Windows\DlcWindow.glade" />
+ <None Remove="UI\Windows\SettingsWindow.glade" />
+ <None Remove="UI\Windows\TitleUpdateWindow.glade" />
+ <None Remove="Modules\Updater\UpdateDialog.glade" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <EmbeddedResource Include="UI\MainWindow.glade" />
+ <EmbeddedResource Include="UI\Widgets\ProfileDialog.glade" />
+ <EmbeddedResource Include="UI\Windows\CheatWindow.glade" />
+ <EmbeddedResource Include="UI\Windows\ControllerWindow.glade" />
+ <EmbeddedResource Include="UI\Windows\DlcWindow.glade" />
+ <EmbeddedResource Include="UI\Windows\SettingsWindow.glade" />
+ <EmbeddedResource Include="UI\Windows\TitleUpdateWindow.glade" />
+ <EmbeddedResource Include="Modules\Updater\UpdateDialog.glade" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/Ryujinx.Ava/Ryujinx.ico b/src/Ryujinx.Gtk3/Ryujinx.ico
index edf1b93f..edf1b93f 100644
--- a/src/Ryujinx.Ava/Ryujinx.ico
+++ b/src/Ryujinx.Gtk3/Ryujinx.ico
Binary files differ
diff --git a/src/Ryujinx/UI/Applet/ErrorAppletDialog.cs b/src/Ryujinx.Gtk3/UI/Applet/ErrorAppletDialog.cs
index 7f8cc0e9..cb8103ca 100644
--- a/src/Ryujinx/UI/Applet/ErrorAppletDialog.cs
+++ b/src/Ryujinx.Gtk3/UI/Applet/ErrorAppletDialog.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.UI.Applet
{
public ErrorAppletDialog(Window parentWindow, DialogFlags dialogFlags, MessageType messageType, string[] buttons) : base(parentWindow, dialogFlags, messageType, ButtonsType.None, null)
{
- Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.UI.Common.Resources.Logo_Ryujinx.png");
+ Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Gtk3.UI.Common.Resources.Logo_Ryujinx.png");
int responseId = 0;
diff --git a/src/Ryujinx/UI/Applet/GtkDynamicTextInputHandler.cs b/src/Ryujinx.Gtk3/UI/Applet/GtkDynamicTextInputHandler.cs
index 0e560b78..0e560b78 100644
--- a/src/Ryujinx/UI/Applet/GtkDynamicTextInputHandler.cs
+++ b/src/Ryujinx.Gtk3/UI/Applet/GtkDynamicTextInputHandler.cs
diff --git a/src/Ryujinx/UI/Applet/GtkHostUIHandler.cs b/src/Ryujinx.Gtk3/UI/Applet/GtkHostUIHandler.cs
index 1d918d21..1d918d21 100644
--- a/src/Ryujinx/UI/Applet/GtkHostUIHandler.cs
+++ b/src/Ryujinx.Gtk3/UI/Applet/GtkHostUIHandler.cs
diff --git a/src/Ryujinx/UI/Applet/GtkHostUITheme.cs b/src/Ryujinx.Gtk3/UI/Applet/GtkHostUITheme.cs
index 52d1123b..52d1123b 100644
--- a/src/Ryujinx/UI/Applet/GtkHostUITheme.cs
+++ b/src/Ryujinx.Gtk3/UI/Applet/GtkHostUITheme.cs
diff --git a/src/Ryujinx/UI/Applet/SwkbdAppletDialog.cs b/src/Ryujinx.Gtk3/UI/Applet/SwkbdAppletDialog.cs
index 8045da91..8045da91 100644
--- a/src/Ryujinx/UI/Applet/SwkbdAppletDialog.cs
+++ b/src/Ryujinx.Gtk3/UI/Applet/SwkbdAppletDialog.cs
diff --git a/src/Ryujinx/UI/Helper/MetalHelper.cs b/src/Ryujinx.Gtk3/UI/Helper/MetalHelper.cs
index c2c32d3a..c2c32d3a 100644
--- a/src/Ryujinx/UI/Helper/MetalHelper.cs
+++ b/src/Ryujinx.Gtk3/UI/Helper/MetalHelper.cs
diff --git a/src/Ryujinx/UI/Helper/SortHelper.cs b/src/Ryujinx.Gtk3/UI/Helper/SortHelper.cs
index 3e3fbeaa..3e3fbeaa 100644
--- a/src/Ryujinx/UI/Helper/SortHelper.cs
+++ b/src/Ryujinx.Gtk3/UI/Helper/SortHelper.cs
diff --git a/src/Ryujinx/UI/Helper/ThemeHelper.cs b/src/Ryujinx.Gtk3/UI/Helper/ThemeHelper.cs
index e1fed1c4..e1fed1c4 100644
--- a/src/Ryujinx/UI/Helper/ThemeHelper.cs
+++ b/src/Ryujinx.Gtk3/UI/Helper/ThemeHelper.cs
diff --git a/src/Ryujinx/UI/MainWindow.cs b/src/Ryujinx.Gtk3/UI/MainWindow.cs
index 2908f1a8..d1ca6ce6 100644
--- a/src/Ryujinx/UI/MainWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/MainWindow.cs
@@ -143,7 +143,7 @@ namespace Ryujinx.UI
#pragma warning restore CS0649, IDE0044, CS0169, IDE0051
- public MainWindow() : this(new Builder("Ryujinx.UI.MainWindow.glade")) { }
+ public MainWindow() : this(new Builder("Ryujinx.Gtk3.UI.MainWindow.glade")) { }
private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("_mainWin"))
{
diff --git a/src/Ryujinx/UI/MainWindow.glade b/src/Ryujinx.Gtk3/UI/MainWindow.glade
index d1b6872a..d1b6872a 100644
--- a/src/Ryujinx/UI/MainWindow.glade
+++ b/src/Ryujinx.Gtk3/UI/MainWindow.glade
diff --git a/src/Ryujinx/UI/OpenGLRenderer.cs b/src/Ryujinx.Gtk3/UI/OpenGLRenderer.cs
index 1fdabc75..1fdabc75 100644
--- a/src/Ryujinx/UI/OpenGLRenderer.cs
+++ b/src/Ryujinx.Gtk3/UI/OpenGLRenderer.cs
diff --git a/src/Ryujinx/UI/OpenToolkitBindingsContext.cs b/src/Ryujinx.Gtk3/UI/OpenToolkitBindingsContext.cs
index 1224ccfe..1224ccfe 100644
--- a/src/Ryujinx/UI/OpenToolkitBindingsContext.cs
+++ b/src/Ryujinx.Gtk3/UI/OpenToolkitBindingsContext.cs
diff --git a/src/Ryujinx/UI/RendererWidgetBase.cs b/src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs
index e27d0604..e27d0604 100644
--- a/src/Ryujinx/UI/RendererWidgetBase.cs
+++ b/src/Ryujinx.Gtk3/UI/RendererWidgetBase.cs
diff --git a/src/Ryujinx/UI/SPBOpenGLContext.cs b/src/Ryujinx.Gtk3/UI/SPBOpenGLContext.cs
index 97feb434..97feb434 100644
--- a/src/Ryujinx/UI/SPBOpenGLContext.cs
+++ b/src/Ryujinx.Gtk3/UI/SPBOpenGLContext.cs
diff --git a/src/Ryujinx/UI/StatusUpdatedEventArgs.cs b/src/Ryujinx.Gtk3/UI/StatusUpdatedEventArgs.cs
index db467ebf..db467ebf 100644
--- a/src/Ryujinx/UI/StatusUpdatedEventArgs.cs
+++ b/src/Ryujinx.Gtk3/UI/StatusUpdatedEventArgs.cs
diff --git a/src/Ryujinx/UI/VulkanRenderer.cs b/src/Ryujinx.Gtk3/UI/VulkanRenderer.cs
index eefc5699..eefc5699 100644
--- a/src/Ryujinx/UI/VulkanRenderer.cs
+++ b/src/Ryujinx.Gtk3/UI/VulkanRenderer.cs
diff --git a/src/Ryujinx/UI/Widgets/GameTableContextMenu.Designer.cs b/src/Ryujinx.Gtk3/UI/Widgets/GameTableContextMenu.Designer.cs
index 8ee1cd2f..8ee1cd2f 100644
--- a/src/Ryujinx/UI/Widgets/GameTableContextMenu.Designer.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/GameTableContextMenu.Designer.cs
diff --git a/src/Ryujinx/UI/Widgets/GameTableContextMenu.cs b/src/Ryujinx.Gtk3/UI/Widgets/GameTableContextMenu.cs
index dc0dd4c5..c8236223 100644
--- a/src/Ryujinx/UI/Widgets/GameTableContextMenu.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/GameTableContextMenu.cs
@@ -189,7 +189,7 @@ namespace Ryujinx.UI.Widgets
_dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Cancel, null)
{
Title = "Ryujinx - NCA Section Extractor",
- Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.UI.Common.Resources.Logo_Ryujinx.png"),
+ Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Gtk3.UI.Common.Resources.Logo_Ryujinx.png"),
SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(_titleFilePath)}...",
WindowPosition = WindowPosition.Center,
};
diff --git a/src/Ryujinx/UI/Widgets/GtkDialog.cs b/src/Ryujinx.Gtk3/UI/Widgets/GtkDialog.cs
index 567f9ad6..567f9ad6 100644
--- a/src/Ryujinx/UI/Widgets/GtkDialog.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/GtkDialog.cs
diff --git a/src/Ryujinx/UI/Widgets/GtkInputDialog.cs b/src/Ryujinx.Gtk3/UI/Widgets/GtkInputDialog.cs
index fd85248b..fd85248b 100644
--- a/src/Ryujinx/UI/Widgets/GtkInputDialog.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/GtkInputDialog.cs
diff --git a/src/Ryujinx/UI/Widgets/ProfileDialog.cs b/src/Ryujinx.Gtk3/UI/Widgets/ProfileDialog.cs
index f8aa6345..3b3e2fbb 100644
--- a/src/Ryujinx/UI/Widgets/ProfileDialog.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/ProfileDialog.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.UI.Widgets
[GUI] Label _errorMessage;
#pragma warning restore CS0649, IDE0044
- public ProfileDialog() : this(new Builder("Ryujinx.UI.Widgets.ProfileDialog.glade")) { }
+ public ProfileDialog() : this(new Builder("Ryujinx.Gtk3.UI.Widgets.ProfileDialog.glade")) { }
private ProfileDialog(Builder builder) : base(builder.GetRawOwnedObject("_profileDialog"))
{
diff --git a/src/Ryujinx/UI/Widgets/ProfileDialog.glade b/src/Ryujinx.Gtk3/UI/Widgets/ProfileDialog.glade
index adaf6608..adaf6608 100644
--- a/src/Ryujinx/UI/Widgets/ProfileDialog.glade
+++ b/src/Ryujinx.Gtk3/UI/Widgets/ProfileDialog.glade
diff --git a/src/Ryujinx/UI/Widgets/RawInputToTextEntry.cs b/src/Ryujinx.Gtk3/UI/Widgets/RawInputToTextEntry.cs
index 6470790e..6470790e 100644
--- a/src/Ryujinx/UI/Widgets/RawInputToTextEntry.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/RawInputToTextEntry.cs
diff --git a/src/Ryujinx/UI/Widgets/UserErrorDialog.cs b/src/Ryujinx.Gtk3/UI/Widgets/UserErrorDialog.cs
index f0b55cd8..f0b55cd8 100644
--- a/src/Ryujinx/UI/Widgets/UserErrorDialog.cs
+++ b/src/Ryujinx.Gtk3/UI/Widgets/UserErrorDialog.cs
diff --git a/src/Ryujinx/UI/Windows/AboutWindow.Designer.cs b/src/Ryujinx.Gtk3/UI/Windows/AboutWindow.Designer.cs
index fd912ef9..fd912ef9 100644
--- a/src/Ryujinx/UI/Windows/AboutWindow.Designer.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/AboutWindow.Designer.cs
diff --git a/src/Ryujinx/UI/Windows/AboutWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/AboutWindow.cs
index f4bb533c..f4bb533c 100644
--- a/src/Ryujinx/UI/Windows/AboutWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/AboutWindow.cs
diff --git a/src/Ryujinx/UI/Windows/AmiiboWindow.Designer.cs b/src/Ryujinx.Gtk3/UI/Windows/AmiiboWindow.Designer.cs
index 3bf73318..3bf73318 100644
--- a/src/Ryujinx/UI/Windows/AmiiboWindow.Designer.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/AmiiboWindow.Designer.cs
diff --git a/src/Ryujinx/UI/Windows/AmiiboWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/AmiiboWindow.cs
index d8c0b0c0..d8c0b0c0 100644
--- a/src/Ryujinx/UI/Windows/AmiiboWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/AmiiboWindow.cs
diff --git a/src/Ryujinx/UI/Windows/AvatarWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/AvatarWindow.cs
index 7cddc362..7cddc362 100644
--- a/src/Ryujinx/UI/Windows/AvatarWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/AvatarWindow.cs
diff --git a/src/Ryujinx/UI/Windows/CheatWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/CheatWindow.cs
index 73ee870c..96ed0723 100644
--- a/src/Ryujinx/UI/Windows/CheatWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/CheatWindow.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.UI.Windows
[GUI] Button _saveButton;
#pragma warning restore CS0649, IDE0044
- public CheatWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) : this(new Builder("Ryujinx.UI.Windows.CheatWindow.glade"), virtualFileSystem, titleId, titleName, titlePath) { }
+ public CheatWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) : this(new Builder("Ryujinx.Gtk3.UI.Windows.CheatWindow.glade"), virtualFileSystem, titleId, titleName, titlePath) { }
private CheatWindow(Builder builder, VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) : base(builder.GetRawOwnedObject("_cheatWindow"))
{
diff --git a/src/Ryujinx/UI/Windows/CheatWindow.glade b/src/Ryujinx.Gtk3/UI/Windows/CheatWindow.glade
index 9a165f1a..9a165f1a 100644
--- a/src/Ryujinx/UI/Windows/CheatWindow.glade
+++ b/src/Ryujinx.Gtk3/UI/Windows/CheatWindow.glade
diff --git a/src/Ryujinx/UI/Windows/ControllerWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/ControllerWindow.cs
index 95411344..6712657f 100644
--- a/src/Ryujinx/UI/Windows/ControllerWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/ControllerWindow.cs
@@ -117,7 +117,7 @@ namespace Ryujinx.UI.Windows
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
- public ControllerWindow(MainWindow mainWindow, PlayerIndex controllerId) : this(mainWindow, new Builder("Ryujinx.UI.Windows.ControllerWindow.glade"), controllerId) { }
+ public ControllerWindow(MainWindow mainWindow, PlayerIndex controllerId) : this(mainWindow, new Builder("Ryujinx.Gtk3.UI.Windows.ControllerWindow.glade"), controllerId) { }
private ControllerWindow(MainWindow mainWindow, Builder builder, PlayerIndex controllerId) : base(builder.GetRawOwnedObject("_controllerWin"))
{
diff --git a/src/Ryujinx/UI/Windows/ControllerWindow.glade b/src/Ryujinx.Gtk3/UI/Windows/ControllerWindow.glade
index e433f5cc..e433f5cc 100644
--- a/src/Ryujinx/UI/Windows/ControllerWindow.glade
+++ b/src/Ryujinx.Gtk3/UI/Windows/ControllerWindow.glade
diff --git a/src/Ryujinx/UI/Windows/DlcWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/DlcWindow.cs
index aed1a015..388f1108 100644
--- a/src/Ryujinx/UI/Windows/DlcWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/DlcWindow.cs
@@ -32,7 +32,7 @@ namespace Ryujinx.UI.Windows
[GUI] TreeSelection _dlcTreeSelection;
#pragma warning restore CS0649, IDE0044
- public DlcWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName) : this(new Builder("Ryujinx.UI.Windows.DlcWindow.glade"), virtualFileSystem, titleId, titleName) { }
+ public DlcWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName) : this(new Builder("Ryujinx.Gtk3.UI.Windows.DlcWindow.glade"), virtualFileSystem, titleId, titleName) { }
private DlcWindow(Builder builder, VirtualFileSystem virtualFileSystem, string titleId, string titleName) : base(builder.GetRawOwnedObject("_dlcWindow"))
{
diff --git a/src/Ryujinx/UI/Windows/DlcWindow.glade b/src/Ryujinx.Gtk3/UI/Windows/DlcWindow.glade
index bdb0e647..bdb0e647 100644
--- a/src/Ryujinx/UI/Windows/DlcWindow.glade
+++ b/src/Ryujinx.Gtk3/UI/Windows/DlcWindow.glade
diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs
index 270a8ad4..dc467c0f 100644
--- a/src/Ryujinx/UI/Windows/SettingsWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.cs
@@ -120,7 +120,7 @@ namespace Ryujinx.UI.Windows
#pragma warning restore CS0649, IDE0044
- public SettingsWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this(parent, new Builder("Ryujinx.UI.Windows.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
+ public SettingsWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this(parent, new Builder("Ryujinx.Gtk3.UI.Windows.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
private SettingsWindow(MainWindow parent, Builder builder, VirtualFileSystem virtualFileSystem, ContentManager contentManager) : base(builder.GetRawOwnedObject("_settingsWin"))
{
diff --git a/src/Ryujinx/UI/Windows/SettingsWindow.glade b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade
index f0dbd6b6..f0dbd6b6 100644
--- a/src/Ryujinx/UI/Windows/SettingsWindow.glade
+++ b/src/Ryujinx.Gtk3/UI/Windows/SettingsWindow.glade
diff --git a/src/Ryujinx/UI/Windows/TitleUpdateWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/TitleUpdateWindow.cs
index 1df92933..74b2330e 100644
--- a/src/Ryujinx/UI/Windows/TitleUpdateWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/TitleUpdateWindow.cs
@@ -38,7 +38,7 @@ namespace Ryujinx.UI.Windows
[GUI] RadioButton _noUpdateRadioButton;
#pragma warning restore CS0649, IDE0044
- public TitleUpdateWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, string titleId, string titleName) : this(new Builder("Ryujinx.UI.Windows.TitleUpdateWindow.glade"), parent, virtualFileSystem, titleId, titleName) { }
+ public TitleUpdateWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, string titleId, string titleName) : this(new Builder("Ryujinx.Gtk3.UI.Windows.TitleUpdateWindow.glade"), parent, virtualFileSystem, titleId, titleName) { }
private TitleUpdateWindow(Builder builder, MainWindow parent, VirtualFileSystem virtualFileSystem, string titleId, string titleName) : base(builder.GetRawOwnedObject("_titleUpdateWindow"))
{
diff --git a/src/Ryujinx/UI/Windows/TitleUpdateWindow.glade b/src/Ryujinx.Gtk3/UI/Windows/TitleUpdateWindow.glade
index cfbac86d..cfbac86d 100644
--- a/src/Ryujinx/UI/Windows/TitleUpdateWindow.glade
+++ b/src/Ryujinx.Gtk3/UI/Windows/TitleUpdateWindow.glade
diff --git a/src/Ryujinx/UI/Windows/UserProfilesManagerWindow.Designer.cs b/src/Ryujinx.Gtk3/UI/Windows/UserProfilesManagerWindow.Designer.cs
index bc5a18f9..bc5a18f9 100644
--- a/src/Ryujinx/UI/Windows/UserProfilesManagerWindow.Designer.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/UserProfilesManagerWindow.Designer.cs
diff --git a/src/Ryujinx/UI/Windows/UserProfilesManagerWindow.cs b/src/Ryujinx.Gtk3/UI/Windows/UserProfilesManagerWindow.cs
index d1e5fa9f..d1e5fa9f 100644
--- a/src/Ryujinx/UI/Windows/UserProfilesManagerWindow.cs
+++ b/src/Ryujinx.Gtk3/UI/Windows/UserProfilesManagerWindow.cs
diff --git a/src/Ryujinx.Ava/App.axaml b/src/Ryujinx/App.axaml
index eab318b7..eab318b7 100644
--- a/src/Ryujinx.Ava/App.axaml
+++ b/src/Ryujinx/App.axaml
diff --git a/src/Ryujinx.Ava/App.axaml.cs b/src/Ryujinx/App.axaml.cs
index 387a6dc1..387a6dc1 100644
--- a/src/Ryujinx.Ava/App.axaml.cs
+++ b/src/Ryujinx/App.axaml.cs
diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx/AppHost.cs
index 04cec957..04cec957 100644
--- a/src/Ryujinx.Ava/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
diff --git a/src/Ryujinx.Ava/Assets/Fonts/SegoeFluentIcons.ttf b/src/Ryujinx/Assets/Fonts/SegoeFluentIcons.ttf
index 8f05a4bb..8f05a4bb 100644
--- a/src/Ryujinx.Ava/Assets/Fonts/SegoeFluentIcons.ttf
+++ b/src/Ryujinx/Assets/Fonts/SegoeFluentIcons.ttf
Binary files differ
diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg b/src/Ryujinx/Assets/Icons/Controller_JoyConLeft.svg
index cf78cf12..cf78cf12 100644
--- a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg
+++ b/src/Ryujinx/Assets/Icons/Controller_JoyConLeft.svg
diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg b/src/Ryujinx/Assets/Icons/Controller_JoyConPair.svg
index 8097762d..8097762d 100644
--- a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg
+++ b/src/Ryujinx/Assets/Icons/Controller_JoyConPair.svg
diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg b/src/Ryujinx/Assets/Icons/Controller_JoyConRight.svg
index adb6e1e1..adb6e1e1 100644
--- a/src/Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg
+++ b/src/Ryujinx/Assets/Icons/Controller_JoyConRight.svg
diff --git a/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg b/src/Ryujinx/Assets/Icons/Controller_ProCon.svg
index 53eef82c..53eef82c 100644
--- a/src/Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg
+++ b/src/Ryujinx/Assets/Icons/Controller_ProCon.svg
diff --git a/src/Ryujinx.Ava/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index 7cdcdf5a..7cdcdf5a 100644
--- a/src/Ryujinx.Ava/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index 59f50ad9..59f50ad9 100644
--- a/src/Ryujinx.Ava/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index 2febf90e..2febf90e 100644
--- a/src/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index 91bcd8f1..91bcd8f1 100644
--- a/src/Ryujinx.Ava/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json
index 5bab6f7b..5bab6f7b 100644
--- a/src/Ryujinx.Ava/Assets/Locales/fr_FR.json
+++ b/src/Ryujinx/Assets/Locales/fr_FR.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index e5caf445..e5caf445 100644
--- a/src/Ryujinx.Ava/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index 5aff7a7e..5aff7a7e 100644
--- a/src/Ryujinx.Ava/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index 5b31c5f2..5b31c5f2 100644
--- a/src/Ryujinx.Ava/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index cdc61722..cdc61722 100644
--- a/src/Ryujinx.Ava/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index 7edf41e8..7edf41e8 100644
--- a/src/Ryujinx.Ava/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index 8909a84f..8909a84f 100644
--- a/src/Ryujinx.Ava/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index a2128e52..a2128e52 100644
--- a/src/Ryujinx.Ava/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index 3f70a781..3f70a781 100644
--- a/src/Ryujinx.Ava/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index a119fb4b..a119fb4b 100644
--- a/src/Ryujinx.Ava/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index d09a80ec..d09a80ec 100644
--- a/src/Ryujinx.Ava/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
diff --git a/src/Ryujinx.Ava/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index a2f59f60..a2f59f60 100644
--- a/src/Ryujinx.Ava/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
diff --git a/src/Ryujinx.Ava/Assets/Styles/Styles.xaml b/src/Ryujinx/Assets/Styles/Styles.xaml
index f7f64be2..f7f64be2 100644
--- a/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
+++ b/src/Ryujinx/Assets/Styles/Styles.xaml
diff --git a/src/Ryujinx.Ava/Assets/Styles/Themes.xaml b/src/Ryujinx/Assets/Styles/Themes.xaml
index 0f323f84..0f323f84 100644
--- a/src/Ryujinx.Ava/Assets/Styles/Themes.xaml
+++ b/src/Ryujinx/Assets/Styles/Themes.xaml
diff --git a/src/Ryujinx.Ava/Common/ApplicationHelper.cs b/src/Ryujinx/Common/ApplicationHelper.cs
index 622a6a02..622a6a02 100644
--- a/src/Ryujinx.Ava/Common/ApplicationHelper.cs
+++ b/src/Ryujinx/Common/ApplicationHelper.cs
diff --git a/src/Ryujinx.Ava/Common/ApplicationSort.cs b/src/Ryujinx/Common/ApplicationSort.cs
index 4b80e3d2..4b80e3d2 100644
--- a/src/Ryujinx.Ava/Common/ApplicationSort.cs
+++ b/src/Ryujinx/Common/ApplicationSort.cs
diff --git a/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs b/src/Ryujinx/Common/KeyboardHotkeyState.cs
index 6e492098..6e492098 100644
--- a/src/Ryujinx.Ava/Common/KeyboardHotkeyState.cs
+++ b/src/Ryujinx/Common/KeyboardHotkeyState.cs
diff --git a/src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs b/src/Ryujinx/Common/Locale/LocaleExtension.cs
index 40661bf3..40661bf3 100644
--- a/src/Ryujinx.Ava/Common/Locale/LocaleExtension.cs
+++ b/src/Ryujinx/Common/Locale/LocaleExtension.cs
diff --git a/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs b/src/Ryujinx/Common/Locale/LocaleManager.cs
index b2f3e7ab..e973fcc0 100644
--- a/src/Ryujinx.Ava/Common/Locale/LocaleManager.cs
+++ b/src/Ryujinx/Common/Locale/LocaleManager.cs
@@ -143,7 +143,7 @@ namespace Ryujinx.Ava.Common.Locale
private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode = DefaultLanguageCode)
{
var localeStrings = new Dictionary<LocaleKeys, string>();
- string languageJson = EmbeddedResources.ReadAllText($"Ryujinx.Ava/Assets/Locales/{languageCode}.json");
+ string languageJson = EmbeddedResources.ReadAllText($"Ryujinx/Assets/Locales/{languageCode}.json");
var strings = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary);
foreach (var item in strings)
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs b/src/Ryujinx/Input/AvaloniaKeyboard.cs
index fbaaaaba..fbaaaaba 100644
--- a/src/Ryujinx.Ava/Input/AvaloniaKeyboard.cs
+++ b/src/Ryujinx/Input/AvaloniaKeyboard.cs
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs b/src/Ryujinx/Input/AvaloniaKeyboardDriver.cs
index e9e71b99..e9e71b99 100644
--- a/src/Ryujinx.Ava/Input/AvaloniaKeyboardDriver.cs
+++ b/src/Ryujinx/Input/AvaloniaKeyboardDriver.cs
diff --git a/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs b/src/Ryujinx/Input/AvaloniaKeyboardMappingHelper.cs
index 97ebd721..97ebd721 100644
--- a/src/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs
+++ b/src/Ryujinx/Input/AvaloniaKeyboardMappingHelper.cs
diff --git a/src/Ryujinx.Ava/Input/AvaloniaMouse.cs b/src/Ryujinx/Input/AvaloniaMouse.cs
index 1aa2d586..1aa2d586 100644
--- a/src/Ryujinx.Ava/Input/AvaloniaMouse.cs
+++ b/src/Ryujinx/Input/AvaloniaMouse.cs
diff --git a/src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs b/src/Ryujinx/Input/AvaloniaMouseDriver.cs
index e71bbf64..e71bbf64 100644
--- a/src/Ryujinx.Ava/Input/AvaloniaMouseDriver.cs
+++ b/src/Ryujinx/Input/AvaloniaMouseDriver.cs
diff --git a/src/Ryujinx/Modules/Updater/Updater.cs b/src/Ryujinx/Modules/Updater/Updater.cs
index 6c0f9cce..d8346c8e 100644
--- a/src/Ryujinx/Modules/Updater/Updater.cs
+++ b/src/Ryujinx/Modules/Updater/Updater.cs
@@ -1,93 +1,75 @@
-using Gtk;
+using Avalonia.Controls;
+using Avalonia.Threading;
+using FluentAvalonia.UI.Controls;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
+using Ryujinx.Ava;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
-using Ryujinx.UI;
+using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.Models.Github;
-using Ryujinx.UI.Widgets;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Modules
{
- public static class Updater
+ internal static class Updater
{
private const string GitHubApiUrl = "https://api.github.com";
- private const int ConnectionCount = 4;
-
- internal static bool Running;
+ private static readonly GithubReleasesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
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 const int ConnectionCount = 4;
private static string _buildVer;
private static string _platformExt;
private static string _buildUrl;
private static long _buildSize;
+ private static bool _updateSuccessful;
+ private static bool _running;
- private static readonly GithubReleasesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- // On Windows, GtkSharp.Dependencies adds these extra dirs that must be cleaned during updates.
- private static readonly string[] _windowsDependencyDirs = { "bin", "etc", "lib", "share" };
+ private static readonly string[] _windowsDependencyDirs = Array.Empty<string>();
- private static HttpClient ConstructHttpClient()
+ public static async Task BeginParse(Window mainWindow, bool showVersionUpToDate)
{
- HttpClient result = new();
-
- // Required by GitHub to interact with APIs.
- result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
-
- return result;
- }
-
- public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
- {
- if (Running)
+ if (_running)
{
return;
}
- Running = true;
- mainWindow.UpdateMenuItem.Sensitive = false;
-
- int artifactIndex = -1;
+ _running = true;
// Detect current platform
if (OperatingSystem.IsMacOS())
{
- _platformExt = "osx_x64.zip";
- artifactIndex = 1;
+ _platformExt = "macos_universal.app.tar.gz";
}
else if (OperatingSystem.IsWindows())
{
_platformExt = "win_x64.zip";
- artifactIndex = 2;
}
else if (OperatingSystem.IsLinux())
{
var arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64";
_platformExt = $"linux_{arch}.tar.gz";
- artifactIndex = 0;
- }
-
- if (artifactIndex == -1)
- {
- GtkDialog.CreateErrorDialog("Your platform is not supported!");
-
- return;
}
Version newVersion;
@@ -99,9 +81,14 @@ namespace Ryujinx.Modules
}
catch
{
- GtkDialog.CreateWarningDialog("Failed to convert the current Ryujinx version.", "Cancelling Update!");
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
+ await ContentDialogHelper.CreateWarningDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
+
+ _running = false;
+
return;
}
@@ -109,9 +96,8 @@ namespace Ryujinx.Modules
try
{
using HttpClient jsonClient = ConstructHttpClient();
- string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
- // Fetch latest build information
+ string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
string fetchedJson = await jsonClient.GetStringAsync(buildInfoUrl);
var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse);
_buildVer = fetched.Name;
@@ -126,9 +112,13 @@ namespace Ryujinx.Modules
{
if (showVersionUpToDate)
{
- GtkDialog.CreateUpdaterInfoDialog("You are already using the latest version of Ryujinx!", "");
+ await ContentDialogHelper.CreateUpdaterInfoDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
+ "");
}
+ _running = false;
+
return;
}
@@ -136,20 +126,29 @@ namespace Ryujinx.Modules
}
}
- if (_buildUrl == null)
+ // If build not done, assume no new update are available.
+ if (_buildUrl is null)
{
if (showVersionUpToDate)
{
- GtkDialog.CreateUpdaterInfoDialog("You are already using the latest version of Ryujinx!", "");
+ await ContentDialogHelper.CreateUpdaterInfoDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
+ "");
}
+ _running = false;
+
return;
}
}
catch (Exception exception)
{
Logger.Error?.Print(LogClass.Application, exception.Message);
- GtkDialog.CreateErrorDialog("An error 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.");
+
+ await ContentDialogHelper.CreateErrorDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterFailedToGetVersionMessage]);
+
+ _running = false;
return;
}
@@ -160,8 +159,13 @@ namespace Ryujinx.Modules
}
catch
{
- GtkDialog.CreateWarningDialog("Failed to convert the received Ryujinx version from GitHub Release.", "Cancelling Update!");
- Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from GitHub Release!");
+ Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
+
+ await ContentDialogHelper.CreateWarningDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
+
+ _running = false;
return;
}
@@ -170,11 +174,12 @@ namespace Ryujinx.Modules
{
if (showVersionUpToDate)
{
- GtkDialog.CreateUpdaterInfoDialog("You are already using the latest version of Ryujinx!", "");
+ await ContentDialogHelper.CreateUpdaterInfoDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
+ "");
}
- Running = false;
- mainWindow.UpdateMenuItem.Sensitive = true;
+ _running = false;
return;
}
@@ -197,13 +202,39 @@ namespace Ryujinx.Modules
_buildSize = -1;
}
- // Show a message asking the user if they want to update
- UpdateDialog updateDialog = new(mainWindow, newVersion, _buildUrl);
- updateDialog.Show();
+ await Dispatcher.UIThread.InvokeAsync(async () =>
+ {
+ // Show a message asking the user if they want to update
+ var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(
+ LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
+ LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
+ $"{Program.Version} -> {newVersion}");
+
+ if (shouldUpdate)
+ {
+ await UpdateRyujinx(mainWindow, _buildUrl);
+ }
+ else
+ {
+ _running = false;
+ }
+ });
+ }
+
+ private static HttpClient ConstructHttpClient()
+ {
+ HttpClient result = new();
+
+ // Required by GitHub to interact with APIs.
+ result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
+
+ return result;
}
- public static void UpdateRyujinx(UpdateDialog updateDialog, string downloadUrl)
+ private static async Task UpdateRyujinx(Window parent, string downloadUrl)
{
+ _updateSuccessful = false;
+
// Empty update dir, although it shouldn't ever have anything inside it
if (Directory.Exists(_updateDir))
{
@@ -214,22 +245,93 @@ namespace Ryujinx.Modules
string updateFile = Path.Combine(_updateDir, "update.bin");
- // Download the update .zip
- updateDialog.MainText.Text = "Downloading Update...";
- updateDialog.ProgressBar.Value = 0;
- updateDialog.ProgressBar.MaxValue = 100;
+ TaskDialog taskDialog = new()
+ {
+ Header = LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
+ SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading],
+ IconSource = new SymbolIconSource { Symbol = Symbol.Download },
+ ShowProgressBar = true,
+ XamlRoot = parent,
+ };
- if (_buildSize >= 0)
+ taskDialog.Opened += (s, e) =>
{
- DoUpdateWithMultipleThreads(updateDialog, downloadUrl, updateFile);
- }
- else
+ if (_buildSize >= 0)
+ {
+ DoUpdateWithMultipleThreads(taskDialog, downloadUrl, updateFile);
+ }
+ else
+ {
+ DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
+ }
+ };
+
+ await taskDialog.ShowAsync(true);
+
+ if (_updateSuccessful)
{
- DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
+ bool shouldRestart = true;
+
+ if (!OperatingSystem.IsMacOS())
+ {
+ shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
+ }
+
+ if (shouldRestart)
+ {
+ List<string> arguments = CommandLineState.Arguments.ToList();
+ string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
+
+ // On macOS we perform the update at relaunch.
+ if (OperatingSystem.IsMacOS())
+ {
+ string baseBundlePath = Path.GetFullPath(Path.Combine(executableDirectory, "..", ".."));
+ string newBundlePath = Path.Combine(_updateDir, "Ryujinx.app");
+ string updaterScriptPath = Path.Combine(newBundlePath, "Contents", "Resources", "updater.sh");
+ string currentPid = Environment.ProcessId.ToString();
+
+ arguments.InsertRange(0, new List<string> { updaterScriptPath, baseBundlePath, newBundlePath, currentPid });
+ Process.Start("/bin/bash", arguments);
+ }
+ else
+ {
+ // Find the process name.
+ string ryuName = Path.GetFileName(Environment.ProcessPath);
+
+ // Some operating systems can see the renamed executable, so strip off the .ryuold if found.
+ if (ryuName.EndsWith(".ryuold"))
+ {
+ ryuName = ryuName[..^7];
+ }
+
+ // Fallback if the executable could not be found.
+ if (!Path.Exists(Path.Combine(executableDirectory, ryuName)))
+ {
+ ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
+ }
+
+ ProcessStartInfo processStart = new(ryuName)
+ {
+ UseShellExecute = true,
+ WorkingDirectory = executableDirectory,
+ };
+
+ foreach (string argument in CommandLineState.Arguments)
+ {
+ processStart.ArgumentList.Add(argument);
+ }
+
+ Process.Start(processStart);
+ }
+
+ Environment.Exit(0);
+ }
}
}
- private static void DoUpdateWithMultipleThreads(UpdateDialog updateDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
// Multi-Threaded Updater
long chunkSize = _buildSize / ConnectionCount;
@@ -253,6 +355,7 @@ namespace Ryujinx.Modules
// TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient.
using WebClient client = new();
#pragma warning restore SYSLIB0014
+
webClients.Add(client);
if (i == ConnectionCount - 1)
@@ -272,7 +375,7 @@ namespace Ryujinx.Modules
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
- updateDialog.ProgressBar.Value = totalProgressPercentage / ConnectionCount;
+ taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
};
client.DownloadDataCompleted += (_, args) =>
@@ -283,6 +386,8 @@ namespace Ryujinx.Modules
{
webClients[index].Dispose();
+ taskDialog.Hide();
+
return;
}
@@ -300,18 +405,24 @@ namespace Ryujinx.Modules
File.WriteAllBytes(updateFile, mergedFileBytes);
+ // On macOS, ensure that we remove the quarantine bit to prevent Gatekeeper from blocking execution.
+ if (OperatingSystem.IsMacOS())
+ {
+ using Process xattrProcess = Process.Start("xattr", new List<string> { "-d", "com.apple.quarantine", updateFile });
+
+ xattrProcess.WaitForExit();
+ }
+
try
{
- InstallUpdate(updateDialog, updateFile);
+ InstallUpdate(taskDialog, 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;
+ DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
}
}
};
@@ -330,14 +441,14 @@ namespace Ryujinx.Modules
webClient.CancelAsync();
}
- DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
+ DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
return;
}
}
}
- private static void DoUpdateWithSingleThreadWorker(UpdateDialog updateDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithSingleThreadWorker(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
using HttpClient client = new();
// We do not want to timeout while downloading
@@ -363,151 +474,165 @@ namespace Ryujinx.Modules
byteWritten += readSize;
- updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
+ taskDialog.SetProgressBarState(GetPercentage(byteWritten, totalBytes), TaskDialogProgressState.Normal);
+
updateFileStream.Write(buffer, 0, readSize);
}
- InstallUpdate(updateDialog, updateFile);
+ InstallUpdate(taskDialog, updateFile);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static double GetPercentage(double value, double max)
+ {
+ return max == 0 ? 0 : value / max * 100;
}
- private static void DoUpdateWithSingleThread(UpdateDialog updateDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithSingleThread(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
- Thread worker = new(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile))
+ Thread worker = new(() => DoUpdateWithSingleThreadWorker(taskDialog, downloadUrl, updateFile))
{
Name = "Updater.SingleThreadWorker",
};
+
worker.Start();
}
- private static async void InstallUpdate(UpdateDialog updateDialog, string updateFile)
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
+ private static void ExtractTarGzipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
{
- // Extract Update
- updateDialog.MainText.Text = "Extracting Update...";
- updateDialog.ProgressBar.Value = 0;
+ using Stream inStream = File.OpenRead(archivePath);
+ using GZipInputStream gzipStream = new(inStream);
+ using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
- if (OperatingSystem.IsLinux())
- {
- using Stream inStream = File.OpenRead(updateFile);
- using Stream gzipStream = new GZipInputStream(inStream);
- using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
- updateDialog.ProgressBar.MaxValue = inStream.Length;
+ TarEntry tarEntry;
- await Task.Run(() =>
+ while ((tarEntry = tarStream.GetNextEntry()) is not null)
+ {
+ if (tarEntry.IsDirectory)
{
- TarEntry tarEntry;
-
- if (!OperatingSystem.IsWindows())
- {
- while ((tarEntry = tarStream.GetNextEntry()) != null)
- {
- if (tarEntry.IsDirectory)
- {
- continue;
- }
-
- string outPath = Path.Combine(_updateDir, tarEntry.Name);
+ continue;
+ }
- Directory.CreateDirectory(Path.GetDirectoryName(outPath));
+ string outPath = Path.Combine(outputDirectoryPath, tarEntry.Name);
- using FileStream outStream = File.OpenWrite(outPath);
- tarStream.CopyEntryContents(outStream);
+ Directory.CreateDirectory(Path.GetDirectoryName(outPath));
- File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
- File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
+ using FileStream outStream = File.OpenWrite(outPath);
+ tarStream.CopyEntryContents(outStream);
- TarEntry entry = tarEntry;
+ File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
+ File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
- Application.Invoke(delegate
- {
- updateDialog.ProgressBar.Value += entry.Size;
- });
- }
+ Dispatcher.UIThread.Post(() =>
+ {
+ if (tarEntry is null)
+ {
+ return;
}
- });
- updateDialog.ProgressBar.Value = inStream.Length;
+ taskDialog.SetProgressBarState(GetPercentage(tarEntry.Size, inStream.Length), TaskDialogProgressState.Normal);
+ });
}
- else
- {
- using Stream inStream = File.OpenRead(updateFile);
- using ZipFile zipFile = new(inStream);
- updateDialog.ProgressBar.MaxValue = zipFile.Count;
+ }
- await Task.Run(() =>
+ private static void ExtractZipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
+ {
+ using Stream inStream = File.OpenRead(archivePath);
+ using ZipFile zipFile = new(inStream);
+
+ double count = 0;
+ foreach (ZipEntry zipEntry in zipFile)
+ {
+ count++;
+ if (zipEntry.IsDirectory)
{
- foreach (ZipEntry zipEntry in zipFile)
- {
- if (zipEntry.IsDirectory)
- {
- continue;
- }
+ continue;
+ }
- string outPath = Path.Combine(_updateDir, zipEntry.Name);
+ string outPath = Path.Combine(outputDirectoryPath, zipEntry.Name);
- Directory.CreateDirectory(Path.GetDirectoryName(outPath));
+ Directory.CreateDirectory(Path.GetDirectoryName(outPath));
- using Stream zipStream = zipFile.GetInputStream(zipEntry);
- using FileStream outStream = File.OpenWrite(outPath);
- zipStream.CopyTo(outStream);
+ using Stream zipStream = zipFile.GetInputStream(zipEntry);
+ using FileStream outStream = File.OpenWrite(outPath);
- File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
+ zipStream.CopyTo(outStream);
- Application.Invoke(delegate
- {
- updateDialog.ProgressBar.Value++;
- });
- }
+ File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
+
+ Dispatcher.UIThread.Post(() =>
+ {
+ taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
});
}
+ }
+
+ private static void InstallUpdate(TaskDialog taskDialog, string updateFile)
+ {
+ // Extract Update
+ taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterExtracting];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
+
+ if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
+ {
+ ExtractTarGzipFile(taskDialog, updateFile, _updateDir);
+ }
+ else if (OperatingSystem.IsWindows())
+ {
+ ExtractZipFile(taskDialog, updateFile, _updateDir);
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
// Delete downloaded zip
File.Delete(updateFile);
List<string> allFiles = EnumerateFilesToDelete().ToList();
- updateDialog.MainText.Text = "Renaming Old Files...";
- updateDialog.ProgressBar.Value = 0;
- updateDialog.ProgressBar.MaxValue = allFiles.Count;
+ taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterRenaming];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
- // Replace old files
- await Task.Run(() =>
+ // NOTE: On macOS, replacement is delayed to the restart phase.
+ if (!OperatingSystem.IsMacOS())
{
+ // Replace old files
+ double count = 0;
foreach (string file in allFiles)
{
+ count++;
try
{
File.Move(file, file + ".ryuold");
- Application.Invoke(delegate
+ Dispatcher.UIThread.InvokeAsync(() =>
{
- updateDialog.ProgressBar.Value++;
+ taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
});
}
catch
{
- Logger.Warning?.Print(LogClass.Application, "Updater was unable to rename file: " + file);
+ Logger.Warning?.Print(LogClass.Application, LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.UpdaterRenameFailed, file));
}
}
- Application.Invoke(delegate
+ Dispatcher.UIThread.InvokeAsync(() =>
{
- updateDialog.MainText.Text = "Adding New Files...";
- updateDialog.ProgressBar.Value = 0;
- updateDialog.ProgressBar.MaxValue = Directory.GetFiles(_updatePublishDir, "*", SearchOption.AllDirectories).Length;
+ taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterAddingFiles];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
});
- MoveAllFilesOver(_updatePublishDir, _homeDir, updateDialog);
- });
+ MoveAllFilesOver(_updatePublishDir, _homeDir, taskDialog);
- Directory.Delete(_updateDir, true);
+ Directory.Delete(_updateDir, true);
+ }
- updateDialog.MainText.Text = "Update Complete!";
- updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?";
- updateDialog.Modal = true;
+ _updateSuccessful = true;
- updateDialog.ProgressBar.Hide();
- updateDialog.YesButton.Show();
- updateDialog.NoButton.Show();
+ taskDialog.Hide();
}
public static bool CanUpdate(bool showWarnings)
@@ -517,7 +642,11 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- GtkDialog.CreateWarningDialog("You are not connected to the Internet!", "Please verify that you have a working Internet connection!");
+ Dispatcher.UIThread.InvokeAsync(() =>
+ ContentDialogHelper.CreateWarningDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterNoInternetMessage],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterNoInternetSubMessage])
+ );
}
return false;
@@ -527,7 +656,11 @@ namespace Ryujinx.Modules
{
if (showWarnings)
{
- GtkDialog.CreateWarningDialog("You cannot update a Dirty build of Ryujinx!", "Please download Ryujinx at https://ryujinx.org/ if you are looking for a supported version.");
+ Dispatcher.UIThread.InvokeAsync(() =>
+ ContentDialogHelper.CreateWarningDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildMessage],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildSubMessage])
+ );
}
return false;
@@ -539,11 +672,19 @@ namespace Ryujinx.Modules
{
if (ReleaseInformation.IsFlatHubBuild)
{
- GtkDialog.CreateWarningDialog("Updater Disabled!", "Please update Ryujinx via FlatHub.");
+ Dispatcher.UIThread.InvokeAsync(() =>
+ ContentDialogHelper.CreateWarningDialog(
+ LocaleManager.Instance[LocaleKeys.UpdaterDisabledWarningTitle],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterFlatpakNotSupportedMessage])
+ );
}
else
{
- GtkDialog.CreateWarningDialog("Updater Disabled!", "Please download Ryujinx at https://ryujinx.org/ if you are looking for a supported version.");
+ Dispatcher.UIThread.InvokeAsync(() =>
+ ContentDialogHelper.CreateWarningDialog(
+ LocaleManager.Instance[LocaleKeys.UpdaterDisabledWarningTitle],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildSubMessage])
+ );
}
}
@@ -557,7 +698,7 @@ namespace Ryujinx.Modules
var files = Directory.EnumerateFiles(_homeDir); // All files directly in base dir.
// Determine and exclude user files only when the updater is running, not when cleaning old files
- if (Running)
+ if (_running && !OperatingSystem.IsMacOS())
{
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
var oldFiles = Directory.EnumerateFiles(_homeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
@@ -583,8 +724,9 @@ namespace Ryujinx.Modules
return files.Where(f => !new FileInfo(f).Attributes.HasFlag(FileAttributes.Hidden | FileAttributes.System));
}
- private static void MoveAllFilesOver(string root, string dest, UpdateDialog dialog)
+ private static void MoveAllFilesOver(string root, string dest, TaskDialog taskDialog)
{
+ int total = Directory.GetFiles(root, "*", SearchOption.AllDirectories).Length;
foreach (string directory in Directory.GetDirectories(root))
{
string dirName = Path.GetFileName(directory);
@@ -594,28 +736,28 @@ namespace Ryujinx.Modules
Directory.CreateDirectory(Path.Combine(dest, dirName));
}
- MoveAllFilesOver(directory, Path.Combine(dest, dirName), dialog);
+ MoveAllFilesOver(directory, Path.Combine(dest, dirName), taskDialog);
}
+ double count = 0;
foreach (string file in Directory.GetFiles(root))
{
+ count++;
+
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
- Application.Invoke(delegate
+ Dispatcher.UIThread.InvokeAsync(() =>
{
- dialog.ProgressBar.Value++;
+ taskDialog.SetProgressBarState(GetPercentage(count, total), TaskDialogProgressState.Normal);
});
}
}
public static void CleanupUpdate()
{
- foreach (string file in EnumerateFilesToDelete())
+ foreach (string file in Directory.GetFiles(_homeDir, "*.ryuold", SearchOption.AllDirectories))
{
- if (Path.GetExtension(file).EndsWith(".ryuold"))
- {
- File.Delete(file);
- }
+ File.Delete(file);
}
}
}
diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs
index 1845c512..aecc585f 100644
--- a/src/Ryujinx/Program.cs
+++ b/src/Ryujinx/Program.cs
@@ -1,4 +1,7 @@
-using Gtk;
+using Avalonia;
+using Avalonia.Threading;
+using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.GraphicsDriver;
@@ -6,139 +9,80 @@ using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop;
using Ryujinx.Modules;
using Ryujinx.SDL2.Common;
-using Ryujinx.UI;
using Ryujinx.UI.Common;
using Ryujinx.UI.Common.Configuration;
using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.SystemInfo;
-using Ryujinx.UI.Widgets;
-using SixLabors.ImageSharp.Formats.Jpeg;
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
-namespace Ryujinx
+namespace Ryujinx.Ava
{
- partial class Program
+ internal partial class Program
{
- public static double WindowScaleFactor { get; private set; }
-
+ public static double WindowScaleFactor { get; set; }
+ public static double DesktopScaleFactor { get; set; } = 1.0;
public static string Version { get; private set; }
-
- public static string ConfigurationPath { get; set; }
-
- public static string CommandLineProfile { get; set; }
-
- private const string X11LibraryName = "libX11";
-
- [LibraryImport(X11LibraryName)]
- private static partial int XInitThreads();
+ public static string ConfigurationPath { get; private set; }
+ public static bool PreviewerDetached { get; private set; }
[LibraryImport("user32.dll", SetLastError = true)]
public static partial int MessageBoxA(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type);
- [LibraryImport("libc", SetLastError = true)]
- private static partial int setenv([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int overwrite);
-
- private const uint MbIconWarning = 0x30;
+ private const uint MbIconwarning = 0x30;
- static Program()
- {
- if (OperatingSystem.IsLinux())
- {
- NativeLibrary.SetDllImportResolver(typeof(Program).Assembly, (name, assembly, path) =>
- {
- if (name != X11LibraryName)
- {
- return IntPtr.Zero;
- }
-
- if (!NativeLibrary.TryLoad("libX11.so.6", assembly, path, out IntPtr result))
- {
- if (!NativeLibrary.TryLoad("libX11.so", assembly, path, out result))
- {
- return IntPtr.Zero;
- }
- }
-
- return result;
- });
- }
- }
-
- static void Main(string[] args)
+ public static void Main(string[] args)
{
Version = ReleaseInformation.Version;
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}", MbIconWarning);
+ _ = 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}", MbIconwarning);
}
- // Parse arguments
- CommandLineState.ParseArguments(args);
-
- // Hook unhandled exception and process exit events.
- GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
- AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
- AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit();
+ PreviewerDetached = true;
- // Make process DPI aware for proper window sizing on high-res screens.
- ForceDpiAware.Windows();
- WindowScaleFactor = ForceDpiAware.GetWindowScaleFactor();
+ Initialize(args);
- // Delete backup files after updating.
- Task.Run(Updater.CleanupUpdate);
+ LoggerAdapter.Register();
- Console.Title = $"Ryujinx Console {Version}";
-
- // NOTE: GTK3 doesn't init X11 in a multi threaded way.
- // This ends up causing race condition and abort of XCB when a context is created by SPB (even if SPB do call XInitThreads).
- if (OperatingSystem.IsLinux())
- {
- if (XInitThreads() == 0)
- {
- throw new NotSupportedException("Failed to initialize multi-threading support.");
- }
-
- Environment.SetEnvironmentVariable("GDK_BACKEND", "x11");
- setenv("GDK_BACKEND", "x11", 1);
- }
-
- if (OperatingSystem.IsMacOS())
- {
- string baseDirectory = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
- string resourcesDataDir;
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+ }
- if (Path.GetFileName(baseDirectory) == "MacOS")
+ public static AppBuilder BuildAvaloniaApp()
+ {
+ return AppBuilder.Configure<App>()
+ .UsePlatformDetect()
+ .With(new X11PlatformOptions
{
- resourcesDataDir = Path.Combine(Directory.GetParent(baseDirectory).FullName, "Resources");
- }
- else
+ EnableMultiTouch = true,
+ EnableIme = true,
+ EnableInputFocusProxy = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP") == "gamescope",
+ RenderingMode = new[] { X11RenderingMode.Glx, X11RenderingMode.Software },
+ })
+ .With(new Win32PlatformOptions
{
- resourcesDataDir = baseDirectory;
- }
-
- static void SetEnvironmentVariableNoCaching(string key, string value)
- {
- int res = setenv(key, value, 1);
- Debug.Assert(res != -1);
- }
+ WinUICompositionBackdropCornerRadius = 8.0f,
+ RenderingMode = new[] { Win32RenderingMode.AngleEgl, Win32RenderingMode.Software },
+ })
+ .UseSkia();
+ }
- // On macOS, GTK3 needs XDG_DATA_DIRS to be set, otherwise it will try searching for "gschemas.compiled" in system directories.
- SetEnvironmentVariableNoCaching("XDG_DATA_DIRS", Path.Combine(resourcesDataDir, "share"));
+ private static void Initialize(string[] args)
+ {
+ // Parse arguments
+ CommandLineState.ParseArguments(args);
- // On macOS, GTK3 needs GDK_PIXBUF_MODULE_FILE to be set, otherwise it will try searching for "loaders.cache" in system directories.
- SetEnvironmentVariableNoCaching("GDK_PIXBUF_MODULE_FILE", Path.Combine(resourcesDataDir, "lib", "gdk-pixbuf-2.0", "2.10.0", "loaders.cache"));
+ // Delete backup files after updating.
+ Task.Run(Updater.CleanupUpdate);
- SetEnvironmentVariableNoCaching("GTK_IM_MODULE_FILE", Path.Combine(resourcesDataDir, "lib", "gtk-3.0", "3.0.0", "immodules.cache"));
- }
+ Console.Title = $"Ryujinx Console {Version}";
- string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
- Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPath}");
+ // Hook unhandled exception and process exit events.
+ AppDomain.CurrentDomain.UnhandledException += (sender, e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
+ AppDomain.CurrentDomain.ProcessExit += (sender, e) => Exit();
// Setup base data directory.
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
@@ -153,29 +97,47 @@ namespace Ryujinx
DiscordIntegrationModule.Initialize();
// Initialize SDL2 driver
- SDL2Driver.MainThreadDispatcher = action =>
+ SDL2Driver.MainThreadDispatcher = action => Dispatcher.UIThread.InvokeAsync(action, DispatcherPriority.Input);
+
+ ReloadConfig();
+
+ WindowScaleFactor = ForceDpiAware.GetWindowScaleFactor();
+
+ // Logging system information.
+ PrintSystemInfo();
+
+ // Enable OGL multithreading on the driver, when available.
+ DriverUtilities.ToggleOGLThreading(ConfigurationState.Instance.Graphics.BackendThreading == BackendThreading.Off);
+
+ // Check if keys exists.
+ if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))
{
- Application.Invoke(delegate
+ if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"))))
{
- action();
- });
- };
+ MainWindow.ShowKeyErrorOnLoad = true;
+ }
+ }
- // Sets ImageSharp Jpeg Encoder Quality.
- SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder()
+ if (CommandLineState.LaunchPathArg != null)
{
- Quality = 100,
- });
+ MainWindow.DeferLoadApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
+ }
+ }
+ public static void ReloadConfig()
+ {
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
// Now load the configuration as the other subsystems are now registered
- ConfigurationPath = File.Exists(localConfigurationPath)
- ? localConfigurationPath
- : File.Exists(appDataConfigurationPath)
- ? appDataConfigurationPath
- : null;
+ if (File.Exists(localConfigurationPath))
+ {
+ ConfigurationPath = localConfigurationPath;
+ }
+ else if (File.Exists(appDataConfigurationPath))
+ {
+ ConfigurationPath = appDataConfigurationPath;
+ }
if (ConfigurationPath == null)
{
@@ -199,7 +161,7 @@ namespace Ryujinx
}
}
- // Check if graphics backend was overridden.
+ // Check if graphics backend was overridden
if (CommandLineState.OverrideGraphicsBackend != null)
{
if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl")
@@ -212,6 +174,12 @@ namespace Ryujinx
}
}
+ // Check if docked mode was overriden.
+ if (CommandLineState.OverrideDockedMode.HasValue)
+ {
+ ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
+ }
+
// Check if HideCursor was overridden.
if (CommandLineState.OverrideHideCursor is not null)
{
@@ -223,114 +191,6 @@ namespace Ryujinx
_ => ConfigurationState.Instance.HideCursor.Value,
};
}
-
- // Check if docked mode was overridden.
- if (CommandLineState.OverrideDockedMode.HasValue)
- {
- ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
- }
-
- // Logging system information.
- PrintSystemInfo();
-
- // Enable OGL multithreading on the driver, when available.
- BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
- DriverUtilities.ToggleOGLThreading(threadingMode == BackendThreading.Off);
-
- // Initialize Gtk.
- Application.Init();
-
- // Check if keys exists.
- bool hasSystemProdKeys = File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys"));
- bool hasCommonProdKeys = AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"));
- if (!hasSystemProdKeys && !hasCommonProdKeys)
- {
- UserErrorDialog.CreateUserErrorDialog(UserError.NoKeys);
- }
-
- // Show the main window UI.
- MainWindow mainWindow = new();
- mainWindow.Show();
-
- if (OperatingSystem.IsLinux())
- {
- int currentVmMaxMapCount = LinuxHelper.VmMaxMapCount;
-
- if (LinuxHelper.VmMaxMapCount < LinuxHelper.RecommendedVmMaxMapCount)
- {
- Logger.Warning?.Print(LogClass.Application, $"The value of vm.max_map_count is lower than {LinuxHelper.RecommendedVmMaxMapCount}. ({currentVmMaxMapCount})");
-
- if (LinuxHelper.PkExecPath is not null)
- {
- var buttonTexts = new Dictionary<int, string>()
- {
- { 0, "Yes, until the next restart" },
- { 1, "Yes, permanently" },
- { 2, "No" },
- };
-
- ResponseType response = GtkDialog.CreateCustomDialog(
- "Ryujinx - Low limit for memory mappings detected",
- $"Would you like to increase the value of vm.max_map_count to {LinuxHelper.RecommendedVmMaxMapCount}?",
- "Some games might try to create more memory mappings than currently allowed. " +
- "Ryujinx will crash as soon as this limit gets exceeded.",
- buttonTexts,
- MessageType.Question);
-
- int rc;
-
- switch ((int)response)
- {
- case 0:
- rc = LinuxHelper.RunPkExec($"echo {LinuxHelper.RecommendedVmMaxMapCount} > {LinuxHelper.VmMaxMapCountPath}");
- if (rc == 0)
- {
- Logger.Info?.Print(LogClass.Application, $"vm.max_map_count set to {LinuxHelper.VmMaxMapCount} until the next restart.");
- }
- else
- {
- Logger.Error?.Print(LogClass.Application, $"Unable to change vm.max_map_count. Process exited with code: {rc}");
- }
- break;
- case 1:
- rc = LinuxHelper.RunPkExec($"echo \"vm.max_map_count = {LinuxHelper.RecommendedVmMaxMapCount}\" > {LinuxHelper.SysCtlConfigPath} && sysctl -p {LinuxHelper.SysCtlConfigPath}");
- if (rc == 0)
- {
- Logger.Info?.Print(LogClass.Application, $"vm.max_map_count set to {LinuxHelper.VmMaxMapCount}. Written to config: {LinuxHelper.SysCtlConfigPath}");
- }
- else
- {
- Logger.Error?.Print(LogClass.Application, $"Unable to write new value for vm.max_map_count to config. Process exited with code: {rc}");
- }
- break;
- }
- }
- else
- {
- GtkDialog.CreateWarningDialog(
- "Max amount of memory mappings is lower than recommended.",
- $"The current value of vm.max_map_count ({currentVmMaxMapCount}) is lower than {LinuxHelper.RecommendedVmMaxMapCount}." +
- "Some games might try to create more memory mappings than currently allowed. " +
- "Ryujinx will crash as soon as this limit gets exceeded.\n\n" +
- "You might want to either manually increase the limit or install pkexec, which allows Ryujinx to assist with that.");
- }
- }
- }
-
- if (CommandLineState.LaunchPathArg != null)
- {
- mainWindow.RunApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
- }
-
- if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false))
- {
- Updater.BeginParse(mainWindow, false).ContinueWith(task =>
- {
- Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}");
- }, TaskContinuationOptions.OnlyOnFaulted);
- }
-
- Application.Run();
}
private static void PrintSystemInfo()
@@ -338,8 +198,7 @@ namespace Ryujinx
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))}");
+ Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(Logger.GetEnabledLevels().Count == 0 ? "<None>" : string.Join(", ", Logger.GetEnabledLevels()))}");
if (AppDataManager.Mode == AppDataManager.LaunchMode.Custom)
{
diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj
index 68bf9898..b3d312f6 100644
--- a/src/Ryujinx/Ryujinx.csproj
+++ b/src/Ryujinx/Ryujinx.csproj
@@ -1,5 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
@@ -7,11 +6,17 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>1.0.0-dirty</Version>
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
- <!-- As we already provide GTK3 on Windows via GtkSharp.Dependencies this is redundant. -->
- <SkipGtkInstall>true</SkipGtkInstall>
+ <SigningCertificate Condition=" '$(SigningCertificate)' == '' ">-</SigningCertificate>
+ <ApplicationIcon>Ryujinx.ico</ApplicationIcon>
<TieredPGO>true</TieredPGO>
+ <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
+ <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
+ <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
+ <Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f --deep -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
+ </Target>
+
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
@@ -19,33 +24,56 @@
<TrimMode>partial</TrimMode>
</PropertyGroup>
+ <!--
+ FluentAvalonia, used in the Avalonia UI, requires a workaround for the json serializer used internally when using .NET 8+ System.Text.Json.
+ See:
+ https://github.com/amwx/FluentAvalonia/issues/481
+ https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-8/
+ -->
+ <PropertyGroup>
+ <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
+ </PropertyGroup>
+
<ItemGroup>
- <PackageReference Include="Ryujinx.GtkSharp" />
- <PackageReference Include="GtkSharp.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
- <PackageReference Include="GtkSharp.Dependencies.osx" Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64'" />
- <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
+ <PackageReference Include="Avalonia" />
+ <PackageReference Include="Avalonia.Desktop" />
+ <PackageReference Include="Avalonia.Diagnostics" Condition="'$(Configuration)'=='Debug'" />
+ <PackageReference Include="Avalonia.Controls.DataGrid" />
+ <PackageReference Include="Avalonia.Markup.Xaml.Loader" />
+ <PackageReference Include="Avalonia.Svg" />
+ <PackageReference Include="Avalonia.Svg.Skia" />
+ <PackageReference Include="DynamicData" />
+ <PackageReference Include="FluentAvaloniaUI" />
+
+ <PackageReference Include="OpenTK.Core" />
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
+ <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
- <PackageReference Include="OpenTK.Core" />
- <PackageReference Include="OpenTK.Graphics" />
+ <PackageReference Include="Silk.NET.Vulkan" />
+ <PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
+ <PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
<PackageReference Include="SPB" />
<PackageReference Include="SharpZipLib" />
<PackageReference Include="SixLabors.ImageSharp" />
+
+ <!--NOTE: DO NOT REMOVE, THIS IS REQUIRED AS A RESULT OF A TRIMMING ISSUE IN AVALONIA -->
+ <PackageReference Include="System.Drawing.Common" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
+ <ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.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.SDL2\Ryujinx.Audio.Backends.SDL2.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.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
<ProjectReference Include="..\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj" />
+ <ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<ItemGroup>
@@ -73,32 +101,66 @@
</Content>
</ItemGroup>
- <!-- Due to .net core 3.1 embedded resource loading -->
- <PropertyGroup>
- <EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
- <ApplicationIcon>Ryujinx.ico</ApplicationIcon>
- </PropertyGroup>
-
<ItemGroup>
- <None Remove="UI\MainWindow.glade" />
- <None Remove="UI\Widgets\ProfileDialog.glade" />
- <None Remove="UI\Windows\CheatWindow.glade" />
- <None Remove="UI\Windows\ControllerWindow.glade" />
- <None Remove="UI\Windows\DlcWindow.glade" />
- <None Remove="UI\Windows\SettingsWindow.glade" />
- <None Remove="UI\Windows\TitleUpdateWindow.glade" />
- <None Remove="Modules\Updater\UpdateDialog.glade" />
+ <AvaloniaResource Include="UI\**\*.xaml">
+ <SubType>Designer</SubType>
+ </AvaloniaResource>
+ <AvaloniaResource Include="Assets\Fonts\SegoeFluentIcons.ttf" />
+ <AvaloniaResource Include="Assets\Styles\Themes.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ </AvaloniaResource>
+ <AvaloniaResource Include="Assets\Styles\Styles.xaml" />
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="UI\MainWindow.glade" />
- <EmbeddedResource Include="UI\Widgets\ProfileDialog.glade" />
- <EmbeddedResource Include="UI\Windows\CheatWindow.glade" />
- <EmbeddedResource Include="UI\Windows\ControllerWindow.glade" />
- <EmbeddedResource Include="UI\Windows\DlcWindow.glade" />
- <EmbeddedResource Include="UI\Windows\SettingsWindow.glade" />
- <EmbeddedResource Include="UI\Windows\TitleUpdateWindow.glade" />
- <EmbeddedResource Include="Modules\Updater\UpdateDialog.glade" />
+ <None Remove="Assets\Locales\el_GR.json" />
+ <None Remove="Assets\Locales\en_US.json" />
+ <None Remove="Assets\Locales\es_ES.json" />
+ <None Remove="Assets\Locales\fr_FR.json" />
+ <None Remove="Assets\Locales\he_IL.json" />
+ <None Remove="Assets\Locales\de_DE.json" />
+ <None Remove="Assets\Locales\it_IT.json" />
+ <None Remove="Assets\Locales\ja_JP.json" />
+ <None Remove="Assets\Locales\ko_KR.json" />
+ <None Remove="Assets\Locales\pl_PL.json" />
+ <None Remove="Assets\Locales\pt_BR.json" />
+ <None Remove="Assets\Locales\ru_RU.json" />
+ <None Remove="Assets\Locales\tr_TR.json" />
+ <None Remove="Assets\Locales\uk_UA.json" />
+ <None Remove="Assets\Locales\zh_CN.json" />
+ <None Remove="Assets\Locales\zh_TW.json" />
+ <None Remove="Assets\Styles\Styles.xaml" />
+ <None Remove="Assets\Styles\Themes.xaml" />
+ <None Remove="Assets\Icons\Controller_JoyConLeft.svg" />
+ <None Remove="Assets\Icons\Controller_JoyConPair.svg" />
+ <None Remove="Assets\Icons\Controller_JoyConRight.svg" />
+ <None Remove="Assets\Icons\Controller_ProCon.svg" />
</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\he_IL.json" />
+ <EmbeddedResource Include="Assets\Locales\de_DE.json" />
+ <EmbeddedResource Include="Assets\Locales\it_IT.json" />
+ <EmbeddedResource Include="Assets\Locales\ja_JP.json" />
+ <EmbeddedResource Include="Assets\Locales\ko_KR.json" />
+ <EmbeddedResource Include="Assets\Locales\pl_PL.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\Locales\uk_UA.json" />
+ <EmbeddedResource Include="Assets\Locales\zh_CN.json" />
+ <EmbeddedResource Include="Assets\Locales\zh_TW.json" />
+ <EmbeddedResource Include="Assets\Styles\Styles.xaml" />
+ <EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
+ <EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
+ <EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
+ <EmbeddedResource Include="Assets\Icons\Controller_ProCon.svg" />
+ </ItemGroup>
+ <ItemGroup>
+ <AdditionalFiles Include="Assets\Locales\en_US.json" />
+ </ItemGroup>
</Project>
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs
index 4bcc35a7..4bcc35a7 100644
--- a/src/Ryujinx.Ava/UI/Applet/AvaHostUIHandler.cs
+++ b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs
index 531d0061..531d0061 100644
--- a/src/Ryujinx.Ava/UI/Applet/AvaloniaDynamicTextInputHandler.cs
+++ b/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs
diff --git a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs b/src/Ryujinx/UI/Applet/AvaloniaHostUITheme.cs
index 016fb484..016fb484 100644
--- a/src/Ryujinx.Ava/UI/Applet/AvaloniaHostUITheme.cs
+++ b/src/Ryujinx/UI/Applet/AvaloniaHostUITheme.cs
diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml b/src/Ryujinx/UI/Applet/ControllerAppletDialog.axaml
index b2c22f6b..b2c22f6b 100644
--- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml
+++ b/src/Ryujinx/UI/Applet/ControllerAppletDialog.axaml
diff --git a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs b/src/Ryujinx/UI/Applet/ControllerAppletDialog.axaml.cs
index 279af07c..5a98b164 100644
--- a/src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs
+++ b/src/Ryujinx/UI/Applet/ControllerAppletDialog.axaml.cs
@@ -17,10 +17,10 @@ namespace Ryujinx.Ava.UI.Applet
{
internal partial class ControllerAppletDialog : UserControl
{
- private const string ProControllerResource = "Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg";
- private const string JoyConPairResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg";
- private const string JoyConLeftResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg";
- private const string JoyConRightResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg";
+ private const string ProControllerResource = "Ryujinx/Assets/Icons/Controller_ProCon.svg";
+ private const string JoyConPairResource = "Ryujinx/Assets/Icons/Controller_JoyConPair.svg";
+ private const string JoyConLeftResource = "Ryujinx/Assets/Icons/Controller_JoyConLeft.svg";
+ private const string JoyConRightResource = "Ryujinx/Assets/Icons/Controller_JoyConRight.svg";
public static SvgImage ProControllerImage => GetResource(ProControllerResource);
public static SvgImage JoyconPairImage => GetResource(JoyConPairResource);
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml b/src/Ryujinx/UI/Applet/ErrorAppletWindow.axaml
index 51f37051..51f37051 100644
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml
+++ b/src/Ryujinx/UI/Applet/ErrorAppletWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs b/src/Ryujinx/UI/Applet/ErrorAppletWindow.axaml.cs
index ec6f7682..ec6f7682 100644
--- a/src/Ryujinx.Ava/UI/Applet/ErrorAppletWindow.axaml.cs
+++ b/src/Ryujinx/UI/Applet/ErrorAppletWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml b/src/Ryujinx/UI/Applet/SwkbdAppletDialog.axaml
index b1c84734..b1c84734 100644
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml
+++ b/src/Ryujinx/UI/Applet/SwkbdAppletDialog.axaml
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs b/src/Ryujinx/UI/Applet/SwkbdAppletDialog.axaml.cs
index af3837e4..af3837e4 100644
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
+++ b/src/Ryujinx/UI/Applet/SwkbdAppletDialog.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
index dd0926fc..dd0926fc 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml
+++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs
index 894ac6c1..894ac6c1 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
+++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml b/src/Ryujinx/UI/Controls/ApplicationGridView.axaml
index 2dc95662..2dc95662 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml
+++ b/src/Ryujinx/UI/Controls/ApplicationGridView.axaml
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs
index ee15bc8d..ee15bc8d 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationGridView.axaml.cs
+++ b/src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml b/src/Ryujinx/UI/Controls/ApplicationListView.axaml
index fecf0888..fecf0888 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
+++ b/src/Ryujinx/UI/Controls/ApplicationListView.axaml
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs
index 8681158f..8681158f 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml.cs
+++ b/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml
index bf34b303..bf34b303 100644
--- a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml
+++ b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml
diff --git a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs
index a32c052b..a32c052b 100644
--- a/src/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
+++ b/src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs b/src/Ryujinx/UI/Controls/SliderScroll.axaml.cs
index b57c6f0a..b57c6f0a 100644
--- a/src/Ryujinx.Ava/UI/Controls/SliderScroll.axaml.cs
+++ b/src/Ryujinx/UI/Controls/SliderScroll.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml b/src/Ryujinx/UI/Controls/UpdateWaitWindow.axaml
index 09fa0404..09fa0404 100644
--- a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml
+++ b/src/Ryujinx/UI/Controls/UpdateWaitWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs b/src/Ryujinx/UI/Controls/UpdateWaitWindow.axaml.cs
index 7ad1ee33..7ad1ee33 100644
--- a/src/Ryujinx.Ava/UI/Controls/UpdateWaitWindow.axaml.cs
+++ b/src/Ryujinx/UI/Controls/UpdateWaitWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs b/src/Ryujinx/UI/Helpers/ApplicationOpenedEventArgs.cs
index bc5622b5..bc5622b5 100644
--- a/src/Ryujinx.Ava/UI/Helpers/ApplicationOpenedEventArgs.cs
+++ b/src/Ryujinx/UI/Helpers/ApplicationOpenedEventArgs.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs b/src/Ryujinx/UI/Helpers/BitmapArrayValueConverter.cs
index 42bd8d5a..42bd8d5a 100644
--- a/src/Ryujinx.Ava/UI/Helpers/BitmapArrayValueConverter.cs
+++ b/src/Ryujinx/UI/Helpers/BitmapArrayValueConverter.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs b/src/Ryujinx/UI/Helpers/ButtonKeyAssigner.cs
index 7e8ba734..7e8ba734 100644
--- a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
+++ b/src/Ryujinx/UI/Helpers/ButtonKeyAssigner.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs
index 15b7ddd1..15b7ddd1 100644
--- a/src/Ryujinx.Ava/UI/Helpers/ContentDialogHelper.cs
+++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs b/src/Ryujinx/UI/Helpers/Glyph.cs
index f257dc02..f257dc02 100644
--- a/src/Ryujinx.Ava/UI/Helpers/Glyph.cs
+++ b/src/Ryujinx/UI/Helpers/Glyph.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs b/src/Ryujinx/UI/Helpers/GlyphValueConverter.cs
index 7da23648..7da23648 100644
--- a/src/Ryujinx.Ava/UI/Helpers/GlyphValueConverter.cs
+++ b/src/Ryujinx/UI/Helpers/GlyphValueConverter.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs b/src/Ryujinx/UI/Helpers/KeyValueConverter.cs
index 028ed6bf..028ed6bf 100644
--- a/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs
+++ b/src/Ryujinx/UI/Helpers/KeyValueConverter.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs b/src/Ryujinx/UI/Helpers/LocalizedNeverConverter.cs
index 26fe36c4..26fe36c4 100644
--- a/src/Ryujinx.Ava/UI/Helpers/LocalizedNeverConverter.cs
+++ b/src/Ryujinx/UI/Helpers/LocalizedNeverConverter.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs
index fc714541..fc714541 100644
--- a/src/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
+++ b/src/Ryujinx/UI/Helpers/LoggerAdapter.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs b/src/Ryujinx/UI/Helpers/MiniCommand.cs
index 7e1bb9a6..7e1bb9a6 100644
--- a/src/Ryujinx.Ava/UI/Helpers/MiniCommand.cs
+++ b/src/Ryujinx/UI/Helpers/MiniCommand.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs b/src/Ryujinx/UI/Helpers/NotificationHelper.cs
index 656a8b52..656a8b52 100644
--- a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs
+++ b/src/Ryujinx/UI/Helpers/NotificationHelper.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs b/src/Ryujinx/UI/Helpers/OffscreenTextBox.cs
index a055f335..a055f335 100644
--- a/src/Ryujinx.Ava/UI/Helpers/OffscreenTextBox.cs
+++ b/src/Ryujinx/UI/Helpers/OffscreenTextBox.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs b/src/Ryujinx/UI/Helpers/TimeZoneConverter.cs
index 876d51f7..876d51f7 100644
--- a/src/Ryujinx.Ava/UI/Helpers/TimeZoneConverter.cs
+++ b/src/Ryujinx/UI/Helpers/TimeZoneConverter.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs b/src/Ryujinx/UI/Helpers/UserErrorDialog.cs
index 9a44b862..9a44b862 100644
--- a/src/Ryujinx.Ava/UI/Helpers/UserErrorDialog.cs
+++ b/src/Ryujinx/UI/Helpers/UserErrorDialog.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/UserResult.cs b/src/Ryujinx/UI/Helpers/UserResult.cs
index 2fcd35ae..2fcd35ae 100644
--- a/src/Ryujinx.Ava/UI/Helpers/UserResult.cs
+++ b/src/Ryujinx/UI/Helpers/UserResult.cs
diff --git a/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs b/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs
index 4834df80..4834df80 100644
--- a/src/Ryujinx.Ava/UI/Helpers/Win32NativeInterop.cs
+++ b/src/Ryujinx/UI/Helpers/Win32NativeInterop.cs
diff --git a/src/Ryujinx.Ava/UI/Models/CheatNode.cs b/src/Ryujinx/UI/Models/CheatNode.cs
index 8e9aee25..8e9aee25 100644
--- a/src/Ryujinx.Ava/UI/Models/CheatNode.cs
+++ b/src/Ryujinx/UI/Models/CheatNode.cs
diff --git a/src/Ryujinx.Ava/UI/Models/ControllerModel.cs b/src/Ryujinx/UI/Models/ControllerModel.cs
index 98de7757..98de7757 100644
--- a/src/Ryujinx.Ava/UI/Models/ControllerModel.cs
+++ b/src/Ryujinx/UI/Models/ControllerModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/DeviceType.cs b/src/Ryujinx/UI/Models/DeviceType.cs
index bb4fc3b3..bb4fc3b3 100644
--- a/src/Ryujinx.Ava/UI/Models/DeviceType.cs
+++ b/src/Ryujinx/UI/Models/DeviceType.cs
diff --git a/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs b/src/Ryujinx/UI/Models/DownloadableContentModel.cs
index 9e400441..9e400441 100644
--- a/src/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs
+++ b/src/Ryujinx/UI/Models/DownloadableContentModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs b/src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs
index 224f78f4..224f78f4 100644
--- a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
+++ b/src/Ryujinx/UI/Models/Generic/LastPlayedSortComparer.cs
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs b/src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs
index f0fb035d..f0fb035d 100644
--- a/src/Ryujinx.Ava/UI/Models/Generic/TimePlayedSortComparer.cs
+++ b/src/Ryujinx/UI/Models/Generic/TimePlayedSortComparer.cs
diff --git a/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs b/src/Ryujinx/UI/Models/InputConfiguration.cs
index f1352c6d..f1352c6d 100644
--- a/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs
+++ b/src/Ryujinx/UI/Models/InputConfiguration.cs
diff --git a/src/Ryujinx.Ava/UI/Models/ModModel.cs b/src/Ryujinx/UI/Models/ModModel.cs
index ee28ca5f..ee28ca5f 100644
--- a/src/Ryujinx.Ava/UI/Models/ModModel.cs
+++ b/src/Ryujinx/UI/Models/ModModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/PlayerModel.cs b/src/Ryujinx/UI/Models/PlayerModel.cs
index a19852b9..a19852b9 100644
--- a/src/Ryujinx.Ava/UI/Models/PlayerModel.cs
+++ b/src/Ryujinx/UI/Models/PlayerModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs b/src/Ryujinx/UI/Models/ProfileImageModel.cs
index 99365dfc..99365dfc 100644
--- a/src/Ryujinx.Ava/UI/Models/ProfileImageModel.cs
+++ b/src/Ryujinx/UI/Models/ProfileImageModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/SaveModel.cs b/src/Ryujinx/UI/Models/SaveModel.cs
index d6dea2f6..d6dea2f6 100644
--- a/src/Ryujinx.Ava/UI/Models/SaveModel.cs
+++ b/src/Ryujinx/UI/Models/SaveModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs
index 7f04c0ee..7f04c0ee 100644
--- a/src/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs
+++ b/src/Ryujinx/UI/Models/StatusUpdatedEventArgs.cs
diff --git a/src/Ryujinx.Ava/UI/Models/TempProfile.cs b/src/Ryujinx/UI/Models/TempProfile.cs
index 659092e6..659092e6 100644
--- a/src/Ryujinx.Ava/UI/Models/TempProfile.cs
+++ b/src/Ryujinx/UI/Models/TempProfile.cs
diff --git a/src/Ryujinx.Ava/UI/Models/TimeZone.cs b/src/Ryujinx/UI/Models/TimeZone.cs
index 950fbce4..950fbce4 100644
--- a/src/Ryujinx.Ava/UI/Models/TimeZone.cs
+++ b/src/Ryujinx/UI/Models/TimeZone.cs
diff --git a/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs b/src/Ryujinx/UI/Models/TitleUpdateModel.cs
index c270c9ed..c270c9ed 100644
--- a/src/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs
+++ b/src/Ryujinx/UI/Models/TitleUpdateModel.cs
diff --git a/src/Ryujinx.Ava/UI/Models/UserProfile.cs b/src/Ryujinx/UI/Models/UserProfile.cs
index 7a9237fe..7a9237fe 100644
--- a/src/Ryujinx.Ava/UI/Models/UserProfile.cs
+++ b/src/Ryujinx/UI/Models/UserProfile.cs
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs
index 3bf19b43..3bf19b43 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
+++ b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindowOpenGL.cs
index 3842301d..3842301d 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
+++ b/src/Ryujinx/UI/Renderer/EmbeddedWindowOpenGL.cs
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindowVulkan.cs
index fafbec20..fafbec20 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowVulkan.cs
+++ b/src/Ryujinx/UI/Renderer/EmbeddedWindowVulkan.cs
diff --git a/src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs b/src/Ryujinx/UI/Renderer/OpenTKBindingsContext.cs
index 85e8585f..85e8585f 100644
--- a/src/Ryujinx.Ava/UI/Renderer/OpenTKBindingsContext.cs
+++ b/src/Ryujinx/UI/Renderer/OpenTKBindingsContext.cs
diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml b/src/Ryujinx/UI/Renderer/RendererHost.axaml
index e0b586b4..e0b586b4 100644
--- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml
+++ b/src/Ryujinx/UI/Renderer/RendererHost.axaml
diff --git a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs b/src/Ryujinx/UI/Renderer/RendererHost.axaml.cs
index d055d9ea..d055d9ea 100644
--- a/src/Ryujinx.Ava/UI/Renderer/RendererHost.axaml.cs
+++ b/src/Ryujinx/UI/Renderer/RendererHost.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs b/src/Ryujinx/UI/Renderer/SPBOpenGLContext.cs
index 63bf6cf7..63bf6cf7 100644
--- a/src/Ryujinx.Ava/UI/Renderer/SPBOpenGLContext.cs
+++ b/src/Ryujinx/UI/Renderer/SPBOpenGLContext.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
index 6020f40e..6020f40e 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs
index 8f09568a..8f09568a 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/AmiiboWindowViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs b/src/Ryujinx/UI/ViewModels/BaseModel.cs
index 4db9cf81..4db9cf81 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/BaseModel.cs
+++ b/src/Ryujinx/UI/ViewModels/BaseModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/ControllerInputViewModel.cs
index 71ad2c12..71ad2c12 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/ControllerInputViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs
index 2cd714f4..2cd714f4 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index 17bd69b1..17bd69b1 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs
index 8321bf89..8321bf89 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/ModManagerViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs b/src/Ryujinx/UI/ViewModels/MotionInputViewModel.cs
index 0b12a51f..0b12a51f 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MotionInputViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs b/src/Ryujinx/UI/ViewModels/RumbleInputViewModel.cs
index 49de1993..49de1993 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/RumbleInputViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index bcaa0860..bcaa0860 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs
index 5989ce09..5989ce09 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs b/src/Ryujinx/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
index 89b59122..89b59122 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs b/src/Ryujinx/UI/ViewModels/UserProfileImageSelectorViewModel.cs
index 8e7d41a5..8e7d41a5 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/UserProfileImageSelectorViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/UserProfileImageSelectorViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs b/src/Ryujinx/UI/ViewModels/UserProfileViewModel.cs
index 70274847..70274847 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/UserProfileViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/UserSaveManagerViewModel.cs
index 85adef00..85adef00 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/UserSaveManagerViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/UserSaveManagerViewModel.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml
index 99f2b6b6..99f2b6b6 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
+++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs
index 35129706..35129706 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml b/src/Ryujinx/UI/Views/Input/MotionInputView.axaml
index a6b587f6..a6b587f6 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
+++ b/src/Ryujinx/UI/Views/Input/MotionInputView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs
index 1b340752..1b340752 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Input/MotionInputView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml
index 5b7087a4..5b7087a4 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
+++ b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs
index 9307f872..9307f872 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Input/RumbleInputView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
index 30358ada..30358ada 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
index 8dff5086..dc50ce26 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -55,7 +55,7 @@ namespace Ryujinx.Ava.UI.Views.Main
{
List<MenuItem> menuItems = new();
- string localePath = "Ryujinx.Ava/Assets/Locales";
+ string localePath = "Ryujinx/Assets/Locales";
string localeExt = ".json";
string[] localesPath = EmbeddedResources.GetAllAvailableResources(localePath, localeExt);
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
index f9e192e6..f9e192e6 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs
index 239a7cbf..239a7cbf 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainStatusBarView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml
index cc21b5c6..cc21b5c6 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml
+++ b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml.cs
index 02fd1bf5..02fd1bf5 100644
--- a/src/Ryujinx.Ava/UI/Views/Main/MainViewControls.axaml.cs
+++ b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsAudioView.axaml
index 657e07ee..657e07ee 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsAudioView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsAudioView.axaml.cs
index b672a0f2..b672a0f2 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsAudioView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsAudioView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml
index c74d3dd5..c74d3dd5 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml.cs
index a475971a..a475971a 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsCPUView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml
index 22449478..22449478 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml.cs
index 67341330..67341330 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml
index b4eae01e..b4eae01e 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
index b006d703..b006d703 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsHotkeysView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsInputView.axaml
index 81f4b68b..81f4b68b 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsInputView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsInputView.axaml.cs
index e75c9f0c..e75c9f0c 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsInputView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml
index 0fc9ea1b..0fc9ea1b 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml.cs
index c8df46b3..c8df46b3 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsLoggingView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsLoggingView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml
index 9bb81463..9bb81463 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs
index b771933e..b771933e 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsNetworkView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsNetworkView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml
index e6f7c6e4..e6f7c6e4 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs
index 2c9eac28..2c9eac28 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsSystemView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
index 6504637e..6504637e 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs
index 996d15cd..996d15cd 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsUIView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml b/src/Ryujinx/UI/Views/User/UserEditorView.axaml
index ab83c2cd..ab83c2cd 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserEditorView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs
index 588fa471..588fa471 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserEditorView.axaml.cs
+++ b/src/Ryujinx/UI/Views/User/UserEditorView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml b/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
index 21dfc909..21dfc909 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs
index b6376866..b6376866 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs
+++ b/src/Ryujinx/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml b/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml
index b1786430..b1786430 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs
index fabfaa4e..fabfaa4e 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserProfileImageSelectorView.axaml.cs
+++ b/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml b/src/Ryujinx/UI/Views/User/UserRecovererView.axaml
index 3fdb4ab9..3fdb4ab9 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserRecovererView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs b/src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs
index 31934349..31934349 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs
+++ b/src/Ryujinx/UI/Views/User/UserRecovererView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml
index 8bc5125a..8bc5125a 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs
index 00a229fa..00a229fa 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs
+++ b/src/Ryujinx/UI/Views/User/UserSaveManagerView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml b/src/Ryujinx/UI/Views/User/UserSelectorView.axaml
index 3a9de303..3a9de303 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml
+++ b/src/Ryujinx/UI/Views/User/UserSelectorView.axaml
diff --git a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserSelectorView.axaml.cs
index fa3383aa..fa3383aa 100644
--- a/src/Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs
+++ b/src/Ryujinx/UI/Views/User/UserSelectorView.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml b/src/Ryujinx/UI/Windows/AboutWindow.axaml
index 69fa8251..69fa8251 100644
--- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml
+++ b/src/Ryujinx/UI/Windows/AboutWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs b/src/Ryujinx/UI/Windows/AboutWindow.axaml.cs
index c32661b0..c32661b0 100644
--- a/src/Ryujinx.Ava/UI/Windows/AboutWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/AboutWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml b/src/Ryujinx/UI/Windows/AmiiboWindow.axaml
index c587aa87..c587aa87 100644
--- a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml
+++ b/src/Ryujinx/UI/Windows/AmiiboWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs b/src/Ryujinx/UI/Windows/AmiiboWindow.axaml.cs
index 8829cb10..8829cb10 100644
--- a/src/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/AmiiboWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml b/src/Ryujinx/UI/Windows/CheatWindow.axaml
index 57d5f7ef..57d5f7ef 100644
--- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
+++ b/src/Ryujinx/UI/Windows/CheatWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs
index d78e48a4..d78e48a4 100644
--- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml b/src/Ryujinx/UI/Windows/ContentDialogOverlayWindow.axaml
index 8b52bade..8b52bade 100644
--- a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml
+++ b/src/Ryujinx/UI/Windows/ContentDialogOverlayWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs b/src/Ryujinx/UI/Windows/ContentDialogOverlayWindow.axaml.cs
index 2b12d72f..2b12d72f 100644
--- a/src/Ryujinx.Ava/UI/Windows/ContentDialogOverlayWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/ContentDialogOverlayWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml
index 99cf28e7..99cf28e7 100644
--- a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml
+++ b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs
index 0c02fa0f..0c02fa0f 100644
--- a/src/Ryujinx.Ava/UI/Windows/DownloadableContentManagerWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs b/src/Ryujinx/UI/Windows/IconColorPicker.cs
index 4c75a5ff..4c75a5ff 100644
--- a/src/Ryujinx.Ava/UI/Windows/IconColorPicker.cs
+++ b/src/Ryujinx/UI/Windows/IconColorPicker.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml b/src/Ryujinx/UI/Windows/MainWindow.axaml
index 4def7c28..4def7c28 100644
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
+++ b/src/Ryujinx/UI/Windows/MainWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
index 33a9af5b..33a9af5b 100644
--- a/src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml
index 0ed05ce3..0ed05ce3 100644
--- a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml
+++ b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs
index d9ae0d4f..d9ae0d4f 100644
--- a/src/Ryujinx.Ava/UI/Windows/ModManagerWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml b/src/Ryujinx/UI/Windows/SettingsWindow.axaml
index 40cac90d..de3c2291 100644
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml
+++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml
@@ -76,7 +76,7 @@
Tag="CpuPage">
<ui:NavigationViewItem.IconSource>
<ui:FontIconSource
- FontFamily="avares://Ryujinx.Ava/Assets/Fonts#Segoe Fluent Icons"
+ FontFamily="avares://Ryujinx/Assets/Fonts#Segoe Fluent Icons"
Glyph="{helpers:GlyphValueConverter Chip}" />
</ui:NavigationViewItem.IconSource>
</ui:NavigationViewItem>
diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs
index d7bb0b88..d7bb0b88 100644
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/SettingsWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs b/src/Ryujinx/UI/Windows/StyleableWindow.cs
index a12d2b3e..a12d2b3e 100644
--- a/src/Ryujinx.Ava/UI/Windows/StyleableWindow.cs
+++ b/src/Ryujinx/UI/Windows/StyleableWindow.cs
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml b/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml
index 3eff389f..3eff389f 100644
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml
+++ b/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml
diff --git a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs b/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml.cs
index f3ac6960..f3ac6960 100644
--- a/src/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
+++ b/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml.cs
diff --git a/src/Ryujinx.Ava/app.manifest b/src/Ryujinx/app.manifest
index 920136fb..920136fb 100644
--- a/src/Ryujinx.Ava/app.manifest
+++ b/src/Ryujinx/app.manifest