diff options
Diffstat (limited to 'Ryujinx.Ava/AppHost.cs')
-rw-r--r-- | Ryujinx.Ava/AppHost.cs | 205 |
1 files changed, 112 insertions, 93 deletions
diff --git a/Ryujinx.Ava/AppHost.cs b/Ryujinx.Ava/AppHost.cs index 2cf53ef6..5a0910e8 100644 --- a/Ryujinx.Ava/AppHost.cs +++ b/Ryujinx.Ava/AppHost.cs @@ -1,4 +1,6 @@ using ARMeilleure.Translation; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Threading; using LibHac.Tools.FsSystem; @@ -13,6 +15,7 @@ using Ryujinx.Ava.Input; using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; +using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Windows; using Ryujinx.Common; using Ryujinx.Common.Configuration; @@ -42,7 +45,7 @@ using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; - +using Image = SixLabors.ImageSharp.Image; using InputManager = Ryujinx.Input.HLE.InputManager; using Key = Ryujinx.Input.Key; using MouseButton = Ryujinx.Input.MouseButton; @@ -67,7 +70,7 @@ namespace Ryujinx.Ava private readonly AccountManager _accountManager; private readonly UserChannelPersistence _userChannelPersistence; private readonly InputManager _inputManager; - private readonly MainWindow _parent; + private readonly MainWindowViewModel _viewModel; private readonly IKeyboard _keyboardInterface; private readonly GraphicsDebugLevel _glLogLevel; @@ -110,6 +113,7 @@ namespace Ryujinx.Ava public bool ScreenshotRequested { get; set; } private object _lockObject = new(); + private TopLevel _topLevel; public AppHost( RendererHost renderer, @@ -119,9 +123,10 @@ namespace Ryujinx.Ava ContentManager contentManager, AccountManager accountManager, UserChannelPersistence userChannelPersistence, - MainWindow parent) + MainWindowViewModel viewmodel, + TopLevel topLevel) { - _parent = parent; + _viewModel = viewmodel; _inputManager = inputManager; _accountManager = accountManager; _userChannelPersistence = userChannelPersistence; @@ -129,7 +134,8 @@ namespace Ryujinx.Ava _hideCursorOnIdle = ConfigurationState.Instance.HideCursorOnIdle; _lastCursorMoveTime = Stopwatch.GetTimestamp(); _glLogLevel = ConfigurationState.Instance.Logger.GraphicsDebugLevel; - _inputManager.SetMouseDriver(new AvaloniaMouseDriver(_parent, renderer)); + _topLevel = topLevel; + _inputManager.SetMouseDriver(new AvaloniaMouseDriver(_topLevel, renderer)); _keyboardInterface = (IKeyboard)_inputManager.KeyboardDriver.GetGamepad("0"); NpadManager = _inputManager.CreateNpadManager(); @@ -144,15 +150,15 @@ namespace Ryujinx.Ava if (ApplicationPath.StartsWith("@SystemContent")) { - ApplicationPath = _parent.VirtualFileSystem.SwitchPathToSystemPath(ApplicationPath); + ApplicationPath = _viewModel.VirtualFileSystem.SwitchPathToSystemPath(ApplicationPath); _isFirmwareTitle = true; } ConfigurationState.Instance.HideCursorOnIdle.Event += HideCursorState_Changed; - _parent.PointerLeave += Parent_PointerLeft; - _parent.PointerMoved += Parent_PointerMoved; + _topLevel.PointerLeave += TopLevel_PointerLeave; + _topLevel.PointerMoved += TopLevel_PointerMoved; ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState; ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState; @@ -162,25 +168,27 @@ namespace Ryujinx.Ava _gpuCancellationTokenSource = new CancellationTokenSource(); } - private void Parent_PointerMoved(object sender, PointerEventArgs e) + private void TopLevel_PointerMoved(object sender, PointerEventArgs e) { - _lastCursorMoveTime = Stopwatch.GetTimestamp(); - var p = e.GetCurrentPoint(_parent).Position; - var r = _parent.InputHitTest(p); - _isMouseInRenderer = r == Renderer; + if (sender is Control visual) + { + _lastCursorMoveTime = Stopwatch.GetTimestamp(); + var point = e.GetCurrentPoint(visual).Position; + _isMouseInRenderer = Equals(visual.InputHitTest(point), Renderer); + } } - private void Parent_PointerLeft(object sender, PointerEventArgs e) + private void TopLevel_PointerLeave(object sender, PointerEventArgs e) { _isMouseInRenderer = false; - _parent.Cursor = Cursor.Default; + _viewModel.Cursor = Cursor.Default; } private void SetRendererWindowSize(Size size) { if (_renderer != null) { - double scale = _parent.PlatformImpl.RenderScaling; + double scale = _topLevel.PlatformImpl.RenderScaling; _renderer.Window?.SetSize((int)(size.Width * scale), (int)(size.Height * scale)); } } @@ -256,7 +264,7 @@ namespace Ryujinx.Ava NpadManager.Initialize(Device, ConfigurationState.Instance.Hid.InputConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse); TouchScreenManager.Initialize(Device); - _parent.ViewModel.IsGameRunning = true; + _viewModel.IsGameRunning = true; string titleNameSection = string.IsNullOrWhiteSpace(Device.Application.TitleName) ? string.Empty @@ -276,10 +284,10 @@ namespace Ryujinx.Ava Dispatcher.UIThread.InvokeAsync(() => { - _parent.Title = $"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; + _viewModel.Title = $"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; }); - _parent.ViewModel.SetUiProgressHandlers(Device); + _viewModel.SetUIProgressHandlers(Device); Renderer.SizeChanged += Window_SizeChanged; @@ -287,7 +295,7 @@ namespace Ryujinx.Ava _renderingThread.Start(); - _parent.ViewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value; + _viewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value; MainLoop(); @@ -321,7 +329,7 @@ namespace Ryujinx.Ava Dispatcher.UIThread.Post(() => { var value = e.NewValue; - _parent.ViewModel.Volume = e.NewValue; + _viewModel.Volume = e.NewValue; }); } @@ -369,7 +377,7 @@ namespace Ryujinx.Ava { if (Device.Application != null) { - _parent.UpdateGameMetadata(Device.Application.TitleIdText); + _viewModel.UpdateGameMetadata(Device.Application.TitleIdText); } ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState; @@ -377,6 +385,9 @@ namespace Ryujinx.Ava ConfigurationState.Instance.System.EnableDockedMode.Event -= UpdateDockedModeState; ConfigurationState.Instance.System.AudioVolume.Event -= UpdateAudioVolumeState; + _topLevel.PointerLeave -= TopLevel_PointerLeave; + _topLevel.PointerMoved -= TopLevel_PointerMoved; + _gpuCancellationTokenSource.Cancel(); _gpuCancellationTokenSource.Dispose(); @@ -410,7 +421,7 @@ namespace Ryujinx.Ava } else { - _parent.Cursor = Cursor.Default; + _viewModel.Cursor = Cursor.Default; } }); } @@ -422,58 +433,66 @@ namespace Ryujinx.Ava SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion(); - if (!SetupValidator.CanStartApplication(ContentManager, ApplicationPath, out UserError userError)) + if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - if (SetupValidator.CanFixStartApplication(ContentManager, ApplicationPath, userError, out firmwareVersion)) + if (!SetupValidator.CanStartApplication(ContentManager, ApplicationPath, out UserError userError)) { - if (userError == UserError.NoFirmware) { - UserResult result = await ContentDialogHelper.CreateConfirmationDialog( - LocaleManager.Instance[LocaleKeys.DialogFirmwareNoFirmwareInstalledMessage], - string.Format(LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallEmbeddedMessage], firmwareVersion.VersionString), - LocaleManager.Instance[LocaleKeys.InputDialogYes], - LocaleManager.Instance[LocaleKeys.InputDialogNo], - ""); - - if (result != UserResult.Yes) + if (SetupValidator.CanFixStartApplication(ContentManager, ApplicationPath, userError, out firmwareVersion)) { - await UserErrorDialog.ShowUserErrorDialog(userError, _parent); - Device.Dispose(); - - return false; - } - } - - if (!SetupValidator.TryFixStartApplication(ContentManager, ApplicationPath, userError, out _)) - { - await UserErrorDialog.ShowUserErrorDialog(userError, _parent); - Device.Dispose(); + if (userError == UserError.NoFirmware) + { + UserResult result = await ContentDialogHelper.CreateConfirmationDialog( + LocaleManager.Instance[LocaleKeys.DialogFirmwareNoFirmwareInstalledMessage], + string.Format(LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallEmbeddedMessage], + firmwareVersion.VersionString), + LocaleManager.Instance[LocaleKeys.InputDialogYes], + LocaleManager.Instance[LocaleKeys.InputDialogNo], + ""); + + if (result != UserResult.Yes) + { + await UserErrorDialog.ShowUserErrorDialog(userError, (desktop.MainWindow as MainWindow)); + Device.Dispose(); + + return false; + } + } - return false; - } + if (!SetupValidator.TryFixStartApplication(ContentManager, ApplicationPath, userError, out _)) + { + await UserErrorDialog.ShowUserErrorDialog(userError, (desktop.MainWindow as MainWindow)); + Device.Dispose(); - // Tell the user that we installed a firmware for them. - if (userError == UserError.NoFirmware) - { - firmwareVersion = ContentManager.GetCurrentFirmwareVersion(); + return false; + } - _parent.RefreshFirmwareStatus(); + // Tell the user that we installed a firmware for them. + if (userError == UserError.NoFirmware) + { + firmwareVersion = ContentManager.GetCurrentFirmwareVersion(); + + _viewModel.RefreshFirmwareStatus(); + + await ContentDialogHelper.CreateInfoDialog( + string.Format(LocaleManager.Instance[LocaleKeys.DialogFirmwareInstalledMessage], + firmwareVersion.VersionString), + string.Format(LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallEmbeddedSuccessMessage], + firmwareVersion.VersionString), + LocaleManager.Instance[LocaleKeys.InputDialogOk], + "", + LocaleManager.Instance[LocaleKeys.RyujinxInfo]); + } + } + else + { + await UserErrorDialog.ShowUserErrorDialog(userError, (desktop.MainWindow as MainWindow)); + Device.Dispose(); - await ContentDialogHelper.CreateInfoDialog( - string.Format(LocaleManager.Instance[LocaleKeys.DialogFirmwareInstalledMessage], firmwareVersion.VersionString), - string.Format(LocaleManager.Instance[LocaleKeys.DialogFirmwareInstallEmbeddedSuccessMessage], firmwareVersion.VersionString), - LocaleManager.Instance[LocaleKeys.InputDialogOk], - "", - LocaleManager.Instance[LocaleKeys.RyujinxInfo]); + return false; + } } } - else - { - await UserErrorDialog.ShowUserErrorDialog(userError, _parent); - Device.Dispose(); - - return false; - } } Logger.Notice.Print(LogClass.Application, $"Using Firmware Version: {firmwareVersion?.VersionString}"); @@ -567,7 +586,7 @@ namespace Ryujinx.Ava DiscordIntegrationModule.SwitchToPlayingState(Device.Application.TitleIdText, Device.Application.TitleName); - _parent.ApplicationLibrary.LoadAndSaveMetaData(Device.Application.TitleIdText, appMetadata => + _viewModel.ApplicationLibrary.LoadAndSaveMetaData(Device.Application.TitleIdText, appMetadata => { appMetadata.LastPlayed = DateTime.UtcNow.ToString(); }); @@ -578,13 +597,13 @@ namespace Ryujinx.Ava internal void Resume() { Device?.System.TogglePauseEmulation(false); - _parent.ViewModel.IsPaused = false; + _viewModel.IsPaused = false; } internal void Pause() { Device?.System.TogglePauseEmulation(true); - _parent.ViewModel.IsPaused = true; + _viewModel.IsPaused = true; } private void InitializeSwitchInstance() @@ -632,7 +651,7 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Audio, "Found OpenAL, changing configuration."); ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.OpenAl; - MainWindow.SaveConfig(); + MainWindowViewModel.SaveConfig(); deviceDriver = new OpenALHardwareDeviceDriver(); } @@ -645,7 +664,7 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration."); ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.SoundIo; - MainWindow.SaveConfig(); + MainWindowViewModel.SaveConfig(); deviceDriver = new SoundIoHardwareDeviceDriver(); } @@ -671,7 +690,7 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Audio, "Found SDL2, changing configuration."); ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.SDL2; - MainWindow.SaveConfig(); + MainWindowViewModel.SaveConfig(); deviceDriver = new SDL2HardwareDeviceDriver(); } @@ -684,7 +703,7 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Audio, "Found OpenAL, changing configuration."); ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.OpenAl; - MainWindow.SaveConfig(); + MainWindowViewModel.SaveConfig(); deviceDriver = new OpenALHardwareDeviceDriver(); } @@ -710,7 +729,7 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Audio, "Found SDL2, changing configuration."); ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.SDL2; - MainWindow.SaveConfig(); + MainWindowViewModel.SaveConfig(); deviceDriver = new SDL2HardwareDeviceDriver(); } @@ -723,7 +742,7 @@ namespace Ryujinx.Ava Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration."); ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.SoundIo; - MainWindow.SaveConfig(); + MainWindowViewModel.SaveConfig(); deviceDriver = new SoundIoHardwareDeviceDriver(); } @@ -740,14 +759,14 @@ namespace Ryujinx.Ava IntegrityCheckLevel fsIntegrityCheckLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None; HLE.HLEConfiguration configuration = new HLE.HLEConfiguration(VirtualFileSystem, - _parent.LibHacHorizonManager, + _viewModel.LibHacHorizonManager, ContentManager, _accountManager, _userChannelPersistence, renderer, deviceDriver, memoryConfiguration, - _parent.UiHandler, + _viewModel.UiHandler, (SystemLanguage)ConfigurationState.Instance.System.Language.Value, (RegionCode)ConfigurationState.Instance.System.Region.Value, ConfigurationState.Instance.Graphics.EnableVsync, @@ -788,14 +807,14 @@ namespace Ryujinx.Ava { Dispatcher.UIThread.InvokeAsync(() => { - if (_parent.ViewModel.StartGamesInFullscreen) + if (_viewModel.StartGamesInFullscreen) { - _parent.WindowState = WindowState.FullScreen; + _viewModel.WindowState = WindowState.FullScreen; } - if (_parent.WindowState == WindowState.FullScreen) + if (_viewModel.WindowState == WindowState.FullScreen) { - _parent.ViewModel.ShowMenuAndStatusBar = false; + _viewModel.ShowMenuAndStatusBar = false; } }); @@ -819,7 +838,7 @@ namespace Ryujinx.Ava Width = (int)Renderer.Bounds.Width; Height = (int)Renderer.Bounds.Height; - _renderer.Window.SetSize((int)(Width * _parent.PlatformImpl.RenderScaling), (int)(Height * _parent.PlatformImpl.RenderScaling)); + _renderer.Window.SetSize((int)(Width * _topLevel.PlatformImpl.RenderScaling), (int)(Height * _topLevel.PlatformImpl.RenderScaling)); _chrono.Start(); @@ -847,7 +866,7 @@ namespace Ryujinx.Ava if (!_renderingStarted) { _renderingStarted = true; - _parent.SwitchToGameControl(); + _viewModel.SwitchToRenderer(false); } Device.PresentFrame(() => Renderer?.SwapBuffers()); @@ -914,7 +933,7 @@ namespace Ryujinx.Ava { Dispatcher.UIThread.Post(() => { - _parent.Cursor = _isMouseInRenderer ? InvisibleCursor : Cursor.Default; + _viewModel.Cursor = _isMouseInRenderer ? InvisibleCursor : Cursor.Default; }); } else @@ -925,7 +944,7 @@ namespace Ryujinx.Ava Dispatcher.UIThread.Post(() => { - _parent.Cursor = cursorMoveDelta >= CursorHideIdleTime * Stopwatch.Frequency ? InvisibleCursor : Cursor.Default; + _viewModel.Cursor = cursorMoveDelta >= CursorHideIdleTime * Stopwatch.Frequency ? InvisibleCursor : Cursor.Default; }); } } @@ -938,13 +957,13 @@ namespace Ryujinx.Ava return false; } - if (_parent.IsActive) + if (_viewModel.IsActive) { Dispatcher.UIThread.Post(() => { HandleScreenState(); - if (_keyboardInterface.GetKeyboardStateSnapshot().IsPressed(Key.Delete) && _parent.WindowState != WindowState.FullScreen) + if (_keyboardInterface.GetKeyboardStateSnapshot().IsPressed(Key.Delete) && _viewModel.WindowState != WindowState.FullScreen) { Device.Application.DiskCacheLoadState?.Cancel(); } @@ -953,7 +972,7 @@ namespace Ryujinx.Ava NpadManager.Update(ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat()); - if (_parent.IsActive) + if (_viewModel.IsActive) { KeyboardHotkeyState currentHotkeyState = GetHotkeyState(); @@ -969,10 +988,10 @@ namespace Ryujinx.Ava ScreenshotRequested = true; break; case KeyboardHotkeyState.ShowUi: - _parent.ViewModel.ShowMenuAndStatusBar = true; + _viewModel.ShowMenuAndStatusBar = true; break; case KeyboardHotkeyState.Pause: - if (_parent.ViewModel.IsPaused) + if (_viewModel.IsPaused) { Resume(); } @@ -991,7 +1010,7 @@ namespace Ryujinx.Ava Device.SetVolume(0); } - _parent.ViewModel.Volume = Device.GetVolume(); + _viewModel.Volume = Device.GetVolume(); break; case KeyboardHotkeyState.ResScaleUp: GraphicsConfig.ResScale = GraphicsConfig.ResScale % MaxResolutionScale + 1; @@ -1004,13 +1023,13 @@ namespace Ryujinx.Ava _newVolume = MathF.Round((Device.GetVolume() + VolumeDelta), 2); Device.SetVolume(_newVolume); - _parent.ViewModel.Volume = Device.GetVolume(); + _viewModel.Volume = Device.GetVolume(); break; case KeyboardHotkeyState.VolumeDown: _newVolume = MathF.Round((Device.GetVolume() - VolumeDelta), 2); Device.SetVolume(_newVolume); - _parent.ViewModel.Volume = Device.GetVolume(); + _viewModel.Volume = Device.GetVolume(); break; case KeyboardHotkeyState.None: (_keyboardInterface as AvaloniaKeyboard).Clear(); @@ -1030,7 +1049,7 @@ namespace Ryujinx.Ava // Touchscreen bool hasTouch = false; - if (_parent.IsActive && !ConfigurationState.Instance.Hid.EnableMouse) + if (_viewModel.IsActive && !ConfigurationState.Instance.Hid.EnableMouse) { hasTouch = TouchScreenManager.Update(true, (_inputManager.MouseDriver as AvaloniaMouseDriver).IsButtonPressed(MouseButton.Button1), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat()); } |