diff options
| author | Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> | 2022-12-29 14:24:05 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-29 15:24:05 +0100 |
| commit | 76671d63d4f3ea18f8ad99e9ce9f0b2ec9a2599d (patch) | |
| tree | 05013214e4696a9254369d0706173f58877f6a83 /Ryujinx.Ava/UI/Models | |
| parent | 3d1a0bf3749afa14da5b5ba1e0666fdb78c99beb (diff) | |
Ava GUI: Restructure `Ryujinx.Ava` (#4165)
* Restructure `Ryujinx.Ava`
* Stylistic consistency
* Update Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Controls/UserSelector.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/ViewModels/UserProfileViewModel.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Ava/UI/Helpers/EmbeddedWindow.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Fix redundancies
* Remove redunancies
* Add back elses
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
Diffstat (limited to 'Ryujinx.Ava/UI/Models')
| -rw-r--r-- | Ryujinx.Ava/UI/Models/Amiibo.cs | 72 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/CheatModel.cs | 40 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/CheatsList.cs | 51 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/ControllerModel.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/DeviceType.cs | 9 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/DownloadableContentModel.cs | 32 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs | 33 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/InputConfiguration.cs | 456 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/PlayerModel.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/ProfileImageModel.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/SaveModel.cs | 123 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs | 28 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/TempProfile.cs | 58 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/TimeZone.cs | 16 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/TitleUpdateModel.cs | 25 | ||||
| -rw-r--r-- | Ryujinx.Ava/UI/Models/UserProfile.cs | 69 |
16 files changed, 1038 insertions, 0 deletions
diff --git a/Ryujinx.Ava/UI/Models/Amiibo.cs b/Ryujinx.Ava/UI/Models/Amiibo.cs new file mode 100644 index 00000000..d0ccafd0 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/Amiibo.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Ryujinx.Ava.UI.Models +{ + public class Amiibo + { + public struct AmiiboJson + { + [JsonPropertyName("amiibo")] public List<AmiiboApi> Amiibo { get; set; } + [JsonPropertyName("lastUpdated")] public DateTime LastUpdated { get; set; } + } + + public struct AmiiboApi + { + [JsonPropertyName("name")] public string Name { get; set; } + [JsonPropertyName("head")] public string Head { get; set; } + [JsonPropertyName("tail")] public string Tail { get; set; } + [JsonPropertyName("image")] public string Image { get; set; } + [JsonPropertyName("amiiboSeries")] public string AmiiboSeries { get; set; } + [JsonPropertyName("character")] public string Character { get; set; } + [JsonPropertyName("gameSeries")] public string GameSeries { get; set; } + [JsonPropertyName("type")] public string Type { get; set; } + + [JsonPropertyName("release")] public Dictionary<string, string> Release { get; set; } + + [JsonPropertyName("gamesSwitch")] public List<AmiiboApiGamesSwitch> GamesSwitch { get; set; } + + public override string ToString() + { + return Name; + } + + public string GetId() + { + return Head + Tail; + } + + public override bool Equals(object obj) + { + if (obj is AmiiboApi amiibo) + { + return amiibo.Head + amiibo.Tail == Head + Tail; + } + + return false; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + + public class AmiiboApiGamesSwitch + { + [JsonPropertyName("amiiboUsage")] public List<AmiiboApiUsage> AmiiboUsage { get; set; } + + [JsonPropertyName("gameID")] public List<string> GameId { get; set; } + + [JsonPropertyName("gameName")] public string GameName { get; set; } + } + + public class AmiiboApiUsage + { + [JsonPropertyName("Usage")] public string Usage { get; set; } + + [JsonPropertyName("write")] public bool Write { get; set; } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/CheatModel.cs b/Ryujinx.Ava/UI/Models/CheatModel.cs new file mode 100644 index 00000000..a7507add --- /dev/null +++ b/Ryujinx.Ava/UI/Models/CheatModel.cs @@ -0,0 +1,40 @@ +using Ryujinx.Ava.UI.ViewModels; +using System; + +namespace Ryujinx.Ava.UI.Models +{ + public class CheatModel : BaseModel + { + private bool _isEnabled; + + public event EventHandler<bool> EnableToggled; + + public CheatModel(string name, string buildId, bool isEnabled) + { + Name = name; + BuildId = buildId; + IsEnabled = isEnabled; + } + + public bool IsEnabled + { + get => _isEnabled; + set + { + _isEnabled = value; + + EnableToggled?.Invoke(this, _isEnabled); + + OnPropertyChanged(); + } + } + + public string BuildId { get; } + + public string BuildIdKey => $"{BuildId}-{Name}"; + + public string Name { get; } + + public string CleanName => Name.Substring(1, Name.Length - 8); + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/CheatsList.cs b/Ryujinx.Ava/UI/Models/CheatsList.cs new file mode 100644 index 00000000..e674f4eb --- /dev/null +++ b/Ryujinx.Ava/UI/Models/CheatsList.cs @@ -0,0 +1,51 @@ +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Linq; + +namespace Ryujinx.Ava.UI.Models +{ + public class CheatsList : ObservableCollection<CheatModel> + { + public CheatsList(string buildId, string path) + { + BuildId = buildId; + Path = path; + + CollectionChanged += CheatsList_CollectionChanged; + } + + public string BuildId { get; } + public string Path { get; } + + public bool IsEnabled + { + get + { + return this.ToList().TrueForAll(x => x.IsEnabled); + } + set + { + foreach (var cheat in this) + { + cheat.IsEnabled = value; + } + + OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled))); + } + } + + private void CheatsList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + (e.NewItems[0] as CheatModel).EnableToggled += Item_EnableToggled; + } + } + + private void Item_EnableToggled(object sender, bool e) + { + OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsEnabled))); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/ControllerModel.cs b/Ryujinx.Ava/UI/Models/ControllerModel.cs new file mode 100644 index 00000000..2af2d13b --- /dev/null +++ b/Ryujinx.Ava/UI/Models/ControllerModel.cs @@ -0,0 +1,6 @@ +using Ryujinx.Common.Configuration.Hid; + +namespace Ryujinx.Ava.UI.Models +{ + internal record ControllerModel(ControllerType Type, string Name); +} diff --git a/Ryujinx.Ava/UI/Models/DeviceType.cs b/Ryujinx.Ava/UI/Models/DeviceType.cs new file mode 100644 index 00000000..fa2e620c --- /dev/null +++ b/Ryujinx.Ava/UI/Models/DeviceType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Ava.UI.Models +{ + public enum DeviceType + { + None, + Keyboard, + Controller + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs b/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs new file mode 100644 index 00000000..3070fc02 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/DownloadableContentModel.cs @@ -0,0 +1,32 @@ +using Ryujinx.Ava.UI.ViewModels; + +namespace Ryujinx.Ava.UI.Models +{ + public class DownloadableContentModel : BaseModel + { + private bool _enabled; + + public bool Enabled + { + get => _enabled; + set + { + _enabled = value; + + OnPropertyChanged(); + } + } + + public string TitleId { get; } + public string ContainerPath { get; } + public string FullPath { get; } + + public DownloadableContentModel(string titleId, string containerPath, string fullPath, bool enabled) + { + TitleId = titleId; + ContainerPath = containerPath; + FullPath = fullPath; + Enabled = enabled; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs b/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs new file mode 100644 index 00000000..b322ed64 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs @@ -0,0 +1,33 @@ +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ui.App.Common; +using System; +using System.Collections.Generic; + +namespace Ryujinx.Ava.UI.Models.Generic +{ + internal class LastPlayedSortComparer : IComparer<ApplicationData> + { + public LastPlayedSortComparer() { } + public LastPlayedSortComparer(bool isAscending) { IsAscending = isAscending; } + + public bool IsAscending { get; } + + public int Compare(ApplicationData x, ApplicationData y) + { + string aValue = x.LastPlayed; + string bValue = y.LastPlayed; + + if (aValue == LocaleManager.Instance["Never"]) + { + aValue = DateTime.UnixEpoch.ToString(); + } + + if (bValue == LocaleManager.Instance["Never"]) + { + bValue = DateTime.UnixEpoch.ToString(); + } + + return (IsAscending ? 1 : -1) * DateTime.Compare(DateTime.Parse(bValue), DateTime.Parse(aValue)); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/InputConfiguration.cs b/Ryujinx.Ava/UI/Models/InputConfiguration.cs new file mode 100644 index 00000000..2acd716b --- /dev/null +++ b/Ryujinx.Ava/UI/Models/InputConfiguration.cs @@ -0,0 +1,456 @@ +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Configuration.Hid.Controller.Motion; +using Ryujinx.Common.Configuration.Hid.Keyboard; +using System; + +namespace Ryujinx.Ava.UI.Models +{ + internal class InputConfiguration<Key, Stick> : BaseModel + { + private float _deadzoneRight; + private float _triggerThreshold; + private float _deadzoneLeft; + private double _gyroDeadzone; + private int _sensitivity; + private bool enableMotion; + private float weakRumble; + private float strongRumble; + private float _rangeLeft; + private float _rangeRight; + + public InputBackendType Backend { get; set; } + + /// <summary> + /// Controller id + /// </summary> + public string Id { get; set; } + + /// <summary> + /// Controller's Type + /// </summary> + public ControllerType ControllerType { get; set; } + + /// <summary> + /// Player's Index for the controller + /// </summary> + public PlayerIndex PlayerIndex { get; set; } + + public Stick LeftJoystick { get; set; } + public bool LeftInvertStickX { get; set; } + public bool LeftInvertStickY { get; set; } + public bool RightRotate90 { get; set; } + public Key LeftControllerStickButton { get; set; } + + public Stick RightJoystick { get; set; } + public bool RightInvertStickX { get; set; } + public bool RightInvertStickY { get; set; } + public bool LeftRotate90 { get; set; } + public Key RightControllerStickButton { get; set; } + + public float DeadzoneLeft + { + get => _deadzoneLeft; + set + { + _deadzoneLeft = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float RangeLeft + { + get => _rangeLeft; + set + { + _rangeLeft = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float DeadzoneRight + { + get => _deadzoneRight; + set + { + _deadzoneRight = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float RangeRight + { + get => _rangeRight; + set + { + _rangeRight = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public float TriggerThreshold + { + get => _triggerThreshold; + set + { + _triggerThreshold = MathF.Round(value, 3); + + OnPropertyChanged(); + } + } + + public MotionInputBackendType MotionBackend { get; set; } + + public Key ButtonMinus { get; set; } + public Key ButtonL { get; set; } + public Key ButtonZl { get; set; } + public Key LeftButtonSl { get; set; } + public Key LeftButtonSr { get; set; } + public Key DpadUp { get; set; } + public Key DpadDown { get; set; } + public Key DpadLeft { get; set; } + public Key DpadRight { get; set; } + + public Key ButtonPlus { get; set; } + public Key ButtonR { get; set; } + public Key ButtonZr { get; set; } + public Key RightButtonSl { get; set; } + public Key RightButtonSr { get; set; } + public Key ButtonX { get; set; } + public Key ButtonB { get; set; } + public Key ButtonY { get; set; } + public Key ButtonA { get; set; } + + + public Key LeftStickUp { get; set; } + public Key LeftStickDown { get; set; } + public Key LeftStickLeft { get; set; } + public Key LeftStickRight { get; set; } + public Key LeftKeyboardStickButton { get; set; } + + public Key RightStickUp { get; set; } + public Key RightStickDown { get; set; } + public Key RightStickLeft { get; set; } + public Key RightStickRight { get; set; } + public Key RightKeyboardStickButton { get; set; } + + public int Sensitivity + { + get => _sensitivity; + set + { + _sensitivity = value; + + OnPropertyChanged(); + } + } + + public double GyroDeadzone + { + get => _gyroDeadzone; + set + { + _gyroDeadzone = Math.Round(value, 3); + + OnPropertyChanged(); + } + } + + public bool EnableMotion + { + get => enableMotion; set + { + enableMotion = value; + + OnPropertyChanged(); + } + } + + public bool EnableCemuHookMotion { get; set; } + public int Slot { get; set; } + public int AltSlot { get; set; } + public bool MirrorInput { get; set; } + public string DsuServerHost { get; set; } + public int DsuServerPort { get; set; } + + public bool EnableRumble { get; set; } + public float WeakRumble + { + get => weakRumble; set + { + weakRumble = value; + + OnPropertyChanged(); + } + } + public float StrongRumble + { + get => strongRumble; set + { + strongRumble = value; + + OnPropertyChanged(); + } + } + + public InputConfiguration(InputConfig config) + { + if (config != null) + { + Backend = config.Backend; + Id = config.Id; + ControllerType = config.ControllerType; + PlayerIndex = config.PlayerIndex; + + if (config is StandardKeyboardInputConfig keyboardConfig) + { + LeftStickUp = (Key)(object)keyboardConfig.LeftJoyconStick.StickUp; + LeftStickDown = (Key)(object)keyboardConfig.LeftJoyconStick.StickDown; + LeftStickLeft = (Key)(object)keyboardConfig.LeftJoyconStick.StickLeft; + LeftStickRight = (Key)(object)keyboardConfig.LeftJoyconStick.StickRight; + LeftKeyboardStickButton = (Key)(object)keyboardConfig.LeftJoyconStick.StickButton; + + RightStickUp = (Key)(object)keyboardConfig.RightJoyconStick.StickUp; + RightStickDown = (Key)(object)keyboardConfig.RightJoyconStick.StickDown; + RightStickLeft = (Key)(object)keyboardConfig.RightJoyconStick.StickLeft; + RightStickRight = (Key)(object)keyboardConfig.RightJoyconStick.StickRight; + RightKeyboardStickButton = (Key)(object)keyboardConfig.RightJoyconStick.StickButton; + + ButtonA = (Key)(object)keyboardConfig.RightJoycon.ButtonA; + ButtonB = (Key)(object)keyboardConfig.RightJoycon.ButtonB; + ButtonX = (Key)(object)keyboardConfig.RightJoycon.ButtonX; + ButtonY = (Key)(object)keyboardConfig.RightJoycon.ButtonY; + ButtonR = (Key)(object)keyboardConfig.RightJoycon.ButtonR; + RightButtonSl = (Key)(object)keyboardConfig.RightJoycon.ButtonSl; + RightButtonSr = (Key)(object)keyboardConfig.RightJoycon.ButtonSr; + ButtonZr = (Key)(object)keyboardConfig.RightJoycon.ButtonZr; + ButtonPlus = (Key)(object)keyboardConfig.RightJoycon.ButtonPlus; + + DpadUp = (Key)(object)keyboardConfig.LeftJoycon.DpadUp; + DpadDown = (Key)(object)keyboardConfig.LeftJoycon.DpadDown; + DpadLeft = (Key)(object)keyboardConfig.LeftJoycon.DpadLeft; + DpadRight = (Key)(object)keyboardConfig.LeftJoycon.DpadRight; + ButtonMinus = (Key)(object)keyboardConfig.LeftJoycon.ButtonMinus; + LeftButtonSl = (Key)(object)keyboardConfig.LeftJoycon.ButtonSl; + LeftButtonSr = (Key)(object)keyboardConfig.LeftJoycon.ButtonSr; + ButtonZl = (Key)(object)keyboardConfig.LeftJoycon.ButtonZl; + ButtonL = (Key)(object)keyboardConfig.LeftJoycon.ButtonL; + } + else if (config is StandardControllerInputConfig controllerConfig) + { + LeftJoystick = (Stick)(object)controllerConfig.LeftJoyconStick.Joystick; + LeftInvertStickX = controllerConfig.LeftJoyconStick.InvertStickX; + LeftInvertStickY = controllerConfig.LeftJoyconStick.InvertStickY; + LeftRotate90 = controllerConfig.LeftJoyconStick.Rotate90CW; + LeftControllerStickButton = (Key)(object)controllerConfig.LeftJoyconStick.StickButton; + + RightJoystick = (Stick)(object)controllerConfig.RightJoyconStick.Joystick; + RightInvertStickX = controllerConfig.RightJoyconStick.InvertStickX; + RightInvertStickY = controllerConfig.RightJoyconStick.InvertStickY; + RightRotate90 = controllerConfig.RightJoyconStick.Rotate90CW; + RightControllerStickButton = (Key)(object)controllerConfig.RightJoyconStick.StickButton; + + ButtonA = (Key)(object)controllerConfig.RightJoycon.ButtonA; + ButtonB = (Key)(object)controllerConfig.RightJoycon.ButtonB; + ButtonX = (Key)(object)controllerConfig.RightJoycon.ButtonX; + ButtonY = (Key)(object)controllerConfig.RightJoycon.ButtonY; + ButtonR = (Key)(object)controllerConfig.RightJoycon.ButtonR; + RightButtonSl = (Key)(object)controllerConfig.RightJoycon.ButtonSl; + RightButtonSr = (Key)(object)controllerConfig.RightJoycon.ButtonSr; + ButtonZr = (Key)(object)controllerConfig.RightJoycon.ButtonZr; + ButtonPlus = (Key)(object)controllerConfig.RightJoycon.ButtonPlus; + + DpadUp = (Key)(object)controllerConfig.LeftJoycon.DpadUp; + DpadDown = (Key)(object)controllerConfig.LeftJoycon.DpadDown; + DpadLeft = (Key)(object)controllerConfig.LeftJoycon.DpadLeft; + DpadRight = (Key)(object)controllerConfig.LeftJoycon.DpadRight; + ButtonMinus = (Key)(object)controllerConfig.LeftJoycon.ButtonMinus; + LeftButtonSl = (Key)(object)controllerConfig.LeftJoycon.ButtonSl; + LeftButtonSr = (Key)(object)controllerConfig.LeftJoycon.ButtonSr; + ButtonZl = (Key)(object)controllerConfig.LeftJoycon.ButtonZl; + ButtonL = (Key)(object)controllerConfig.LeftJoycon.ButtonL; + + DeadzoneLeft = controllerConfig.DeadzoneLeft; + DeadzoneRight = controllerConfig.DeadzoneRight; + RangeLeft = controllerConfig.RangeLeft; + RangeRight = controllerConfig.RangeRight; + TriggerThreshold = controllerConfig.TriggerThreshold; + + if (controllerConfig.Motion != null) + { + EnableMotion = controllerConfig.Motion.EnableMotion; + MotionBackend = controllerConfig.Motion.MotionBackend; + GyroDeadzone = controllerConfig.Motion.GyroDeadzone; + Sensitivity = controllerConfig.Motion.Sensitivity; + + if (controllerConfig.Motion is CemuHookMotionConfigController cemuHook) + { + EnableCemuHookMotion = true; + DsuServerHost = cemuHook.DsuServerHost; + DsuServerPort = cemuHook.DsuServerPort; + Slot = cemuHook.Slot; + AltSlot = cemuHook.AltSlot; + MirrorInput = cemuHook.MirrorInput; + } + + if (controllerConfig.Rumble != null) + { + EnableRumble = controllerConfig.Rumble.EnableRumble; + WeakRumble = controllerConfig.Rumble.WeakRumble; + StrongRumble = controllerConfig.Rumble.StrongRumble; + } + } + } + } + } + + public InputConfiguration() + { + } + + public InputConfig GetConfig() + { + if (Backend == InputBackendType.WindowKeyboard) + { + return new StandardKeyboardInputConfig() + { + Id = Id, + Backend = Backend, + PlayerIndex = PlayerIndex, + ControllerType = ControllerType, + LeftJoycon = new LeftJoyconCommonConfig<Ryujinx.Common.Configuration.Hid.Key>() + { + DpadUp = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadUp, + DpadDown = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadDown, + DpadLeft = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadLeft, + DpadRight = (Ryujinx.Common.Configuration.Hid.Key)(object)DpadRight, + ButtonL = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonL, + ButtonZl = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonZl, + ButtonSl = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftButtonSl, + ButtonSr = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftButtonSr, + ButtonMinus = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonMinus + }, + RightJoycon = new RightJoyconCommonConfig<Ryujinx.Common.Configuration.Hid.Key>() + { + ButtonA = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonA, + ButtonB = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonB, + ButtonX = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonX, + ButtonY = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonY, + ButtonPlus = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonPlus, + ButtonSl = (Ryujinx.Common.Configuration.Hid.Key)(object)RightButtonSl, + ButtonSr = (Ryujinx.Common.Configuration.Hid.Key)(object)RightButtonSr, + ButtonR = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonR, + ButtonZr = (Ryujinx.Common.Configuration.Hid.Key)(object)ButtonZr + }, + LeftJoyconStick = new JoyconConfigKeyboardStick<Ryujinx.Common.Configuration.Hid.Key>() + { + StickUp = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickUp, + StickDown = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickDown, + StickRight = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickRight, + StickLeft = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftStickLeft, + StickButton = (Ryujinx.Common.Configuration.Hid.Key)(object)LeftKeyboardStickButton + }, + RightJoyconStick = new JoyconConfigKeyboardStick<Ryujinx.Common.Configuration.Hid.Key>() + { + StickUp = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickUp, + StickDown = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickDown, + StickLeft = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickLeft, + StickRight = (Ryujinx.Common.Configuration.Hid.Key)(object)RightStickRight, + StickButton = (Ryujinx.Common.Configuration.Hid.Key)(object)RightKeyboardStickButton + }, + Version = InputConfig.CurrentVersion + }; + + } + else if (Backend == InputBackendType.GamepadSDL2) + { + var config = new StandardControllerInputConfig() + { + Id = Id, + Backend = Backend, + PlayerIndex = PlayerIndex, + ControllerType = ControllerType, + LeftJoycon = new LeftJoyconCommonConfig<GamepadInputId>() + { + DpadUp = (GamepadInputId)(object)DpadUp, + DpadDown = (GamepadInputId)(object)DpadDown, + DpadLeft = (GamepadInputId)(object)DpadLeft, + DpadRight = (GamepadInputId)(object)DpadRight, + ButtonL = (GamepadInputId)(object)ButtonL, + ButtonZl = (GamepadInputId)(object)ButtonZl, + ButtonSl = (GamepadInputId)(object)LeftButtonSl, + ButtonSr = (GamepadInputId)(object)LeftButtonSr, + ButtonMinus = (GamepadInputId)(object)ButtonMinus, + }, + RightJoycon = new RightJoyconCommonConfig<GamepadInputId>() + { + ButtonA = (GamepadInputId)(object)ButtonA, + ButtonB = (GamepadInputId)(object)ButtonB, + ButtonX = (GamepadInputId)(object)ButtonX, + ButtonY = (GamepadInputId)(object)ButtonY, + ButtonPlus = (GamepadInputId)(object)ButtonPlus, + ButtonSl = (GamepadInputId)(object)RightButtonSl, + ButtonSr = (GamepadInputId)(object)RightButtonSr, + ButtonR = (GamepadInputId)(object)ButtonR, + ButtonZr = (GamepadInputId)(object)ButtonZr, + }, + LeftJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>() + { + Joystick = (StickInputId)(object)LeftJoystick, + InvertStickX = LeftInvertStickX, + InvertStickY = LeftInvertStickY, + Rotate90CW = LeftRotate90, + StickButton = (GamepadInputId)(object)LeftControllerStickButton, + }, + RightJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>() + { + Joystick = (StickInputId)(object)RightJoystick, + InvertStickX = RightInvertStickX, + InvertStickY = RightInvertStickY, + Rotate90CW = RightRotate90, + StickButton = (GamepadInputId)(object)RightControllerStickButton, + }, + Rumble = new RumbleConfigController() + { + EnableRumble = EnableRumble, + WeakRumble = WeakRumble, + StrongRumble = StrongRumble + }, + Version = InputConfig.CurrentVersion, + DeadzoneLeft = DeadzoneLeft, + DeadzoneRight = DeadzoneRight, + RangeLeft = RangeLeft, + RangeRight = RangeRight, + TriggerThreshold = TriggerThreshold, + Motion = EnableCemuHookMotion + ? new CemuHookMotionConfigController() + { + DsuServerHost = DsuServerHost, + DsuServerPort = DsuServerPort, + Slot = Slot, + AltSlot = AltSlot, + MirrorInput = MirrorInput, + MotionBackend = MotionInputBackendType.CemuHook + } + : new StandardMotionConfigController() + { + MotionBackend = MotionInputBackendType.GamepadDriver + } + }; + + config.Motion.Sensitivity = Sensitivity; + config.Motion.EnableMotion = EnableMotion; + config.Motion.GyroDeadzone = GyroDeadzone; + + return config; + } + + return null; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/PlayerModel.cs b/Ryujinx.Ava/UI/Models/PlayerModel.cs new file mode 100644 index 00000000..f0b1bf7a --- /dev/null +++ b/Ryujinx.Ava/UI/Models/PlayerModel.cs @@ -0,0 +1,6 @@ +using Ryujinx.Common.Configuration.Hid; + +namespace Ryujinx.Ava.UI.Models +{ + public record PlayerModel(PlayerIndex Id, string Name); +} diff --git a/Ryujinx.Ava/UI/Models/ProfileImageModel.cs b/Ryujinx.Ava/UI/Models/ProfileImageModel.cs new file mode 100644 index 00000000..63da7b44 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/ProfileImageModel.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.Ava.UI.Models +{ + public class ProfileImageModel + { + public ProfileImageModel(string name, byte[] data) + { + Name = name; + Data = data; + } + + public string Name { get; set; } + public byte[] Data { get; set; } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/SaveModel.cs b/Ryujinx.Ava/UI/Models/SaveModel.cs new file mode 100644 index 00000000..c9311104 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/SaveModel.cs @@ -0,0 +1,123 @@ +using LibHac; +using LibHac.Fs; +using LibHac.Fs.Shim; +using LibHac.Ncm; +using Ryujinx.Ava.Common; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Controls; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.Windows; +using Ryujinx.HLE.FileSystem; +using Ryujinx.Ui.App.Common; +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace Ryujinx.Ava.UI.Models +{ + public class SaveModel : BaseModel + { + private readonly HorizonClient _horizonClient; + private long _size; + + public Action DeleteAction { get; set; } + public ulong SaveId { get; } + public ProgramId TitleId { get; } + public string TitleIdString => $"{TitleId.Value:X16}"; + public UserId UserId { get; } + public bool InGameList { get; } + public string Title { get; } + public byte[] Icon { get; } + + public long Size + { + get => _size; set + { + _size = value; + SizeAvailable = true; + OnPropertyChanged(); + OnPropertyChanged(nameof(SizeString)); + OnPropertyChanged(nameof(SizeAvailable)); + } + } + + public bool SizeAvailable { get; set; } + + public string SizeString => $"{((float)_size * 0.000000954):0.###}MB"; + + public SaveModel(SaveDataInfo info, HorizonClient horizonClient, VirtualFileSystem virtualFileSystem) + { + _horizonClient = horizonClient; + SaveId = info.SaveDataId; + TitleId = info.ProgramId; + UserId = info.UserId; + + var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.TitleId.ToUpper() == TitleIdString); + + InGameList = appData != null; + + if (InGameList) + { + Icon = appData.Icon; + Title = appData.TitleName; + } + else + { + var appMetadata = MainWindow.MainWindowViewModel.ApplicationLibrary.LoadAndSaveMetaData(TitleIdString); + Title = appMetadata.Title ?? TitleIdString; + } + + Task.Run(() => + { + var saveRoot = System.IO.Path.Combine(virtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}"); + + long total_size = GetDirectorySize(saveRoot); + long GetDirectorySize(string path) + { + long size = 0; + if (Directory.Exists(path)) + { + var directories = Directory.GetDirectories(path); + foreach (var directory in directories) + { + size += GetDirectorySize(directory); + } + + var files = Directory.GetFiles(path); + foreach (var file in files) + { + size += new FileInfo(file).Length; + } + } + + return size; + } + + Size = total_size; + }); + + } + + public void OpenLocation() + { + ApplicationHelper.OpenSaveDir(SaveId); + } + + public async void Delete() + { + var result = await ContentDialogHelper.CreateConfirmationDialog(LocaleManager.Instance["DeleteUserSave"], + LocaleManager.Instance["IrreversibleActionNote"], + LocaleManager.Instance["InputDialogYes"], + LocaleManager.Instance["InputDialogNo"], ""); + + if (result == UserResult.Yes) + { + _horizonClient.Fs.DeleteSaveData(SaveDataSpaceId.User, SaveId); + + DeleteAction?.Invoke(); + } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs b/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs new file mode 100644 index 00000000..ea2b9038 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/StatusUpdatedEventArgs.cs @@ -0,0 +1,28 @@ +using System; + +namespace Ryujinx.Ava.UI.Models +{ + internal class StatusUpdatedEventArgs : EventArgs + { + public bool VSyncEnabled { get; } + public string VolumeStatus { get; } + public string GpuBackend { get; } + public string AspectRatio { get; } + public string DockedMode { get; } + public string FifoStatus { get; } + public string GameStatus { get; } + public string GpuName { get; } + + public StatusUpdatedEventArgs(bool vSyncEnabled, string volumeStatus, string gpuBackend, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, string gpuName) + { + VSyncEnabled = vSyncEnabled; + VolumeStatus = volumeStatus; + GpuBackend = gpuBackend; + DockedMode = dockedMode; + AspectRatio = aspectRatio; + GameStatus = gameStatus; + FifoStatus = fifoStatus; + GpuName = gpuName; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/TempProfile.cs b/Ryujinx.Ava/UI/Models/TempProfile.cs new file mode 100644 index 00000000..2dd7a6c8 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/TempProfile.cs @@ -0,0 +1,58 @@ +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.HLE.HOS.Services.Account.Acc; +using System; + +namespace Ryujinx.Ava.UI.Models +{ + public class TempProfile : BaseModel + { + private readonly UserProfile _profile; + private byte[] _image = null; + private string _name = String.Empty; + private UserId _userId; + + public byte[] Image + { + get => _image; + set + { + _image = value; + OnPropertyChanged(); + } + } + + public UserId UserId + { + get => _userId; + set + { + _userId = value; + OnPropertyChanged(); + } + } + + public string Name + { + get => _name; + set + { + _name = value; + OnPropertyChanged(); + } + } + + public TempProfile(UserProfile profile) + { + _profile = profile; + + if (_profile != null) + { + Image = profile.Image; + Name = profile.Name; + UserId = profile.UserId; + } + } + + public TempProfile(){} + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/TimeZone.cs b/Ryujinx.Ava/UI/Models/TimeZone.cs new file mode 100644 index 00000000..cb6cc2fd --- /dev/null +++ b/Ryujinx.Ava/UI/Models/TimeZone.cs @@ -0,0 +1,16 @@ +namespace Ryujinx.Ava.UI.Models +{ + internal class TimeZone + { + public TimeZone(string utcDifference, string location, string abbreviation) + { + UtcDifference = utcDifference; + Location = location; + Abbreviation = abbreviation; + } + + public string UtcDifference { get; set; } + public string Location { get; set; } + public string Abbreviation { get; set; } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs b/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs new file mode 100644 index 00000000..77203222 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/TitleUpdateModel.cs @@ -0,0 +1,25 @@ +using LibHac.Ns; +using Ryujinx.Ava.Common.Locale; + +namespace Ryujinx.Ava.UI.Models +{ + internal class TitleUpdateModel + { + public bool IsEnabled { get; set; } + public bool IsNoUpdate { get; } + public ApplicationControlProperty Control { get; } + public string Path { get; } + + public string Label => IsNoUpdate + ? LocaleManager.Instance["NoUpdate"] + : string.Format(LocaleManager.Instance["TitleUpdateVersionLabel"], Control.DisplayVersionString.ToString(), + Path); + + public TitleUpdateModel(ApplicationControlProperty control, string path, bool isNoUpdate = false) + { + Control = control; + Path = path; + IsNoUpdate = isNoUpdate; + } + } +}
\ No newline at end of file diff --git a/Ryujinx.Ava/UI/Models/UserProfile.cs b/Ryujinx.Ava/UI/Models/UserProfile.cs new file mode 100644 index 00000000..869db661 --- /dev/null +++ b/Ryujinx.Ava/UI/Models/UserProfile.cs @@ -0,0 +1,69 @@ +using Ryujinx.Ava.UI.Controls; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.HLE.HOS.Services.Account.Acc; +using Profile = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile; + +namespace Ryujinx.Ava.UI.Models +{ + public class UserProfile : BaseModel + { + private readonly Profile _profile; + private readonly NavigationDialogHost _owner; + private byte[] _image; + private string _name; + private UserId _userId; + + public byte[] Image + { + get => _image; + set + { + _image = value; + OnPropertyChanged(); + } + } + + public UserId UserId + { + get => _userId; + set + { + _userId = value; + OnPropertyChanged(); + } + } + + public string Name + { + get => _name; + set + { + _name = value; + OnPropertyChanged(); + } + } + + public UserProfile(Profile profile, NavigationDialogHost owner) + { + _profile = profile; + _owner = owner; + + Image = profile.Image; + Name = profile.Name; + UserId = profile.UserId; + } + + public bool IsOpened => _profile.AccountState == AccountState.Open; + + public void UpdateState() + { + OnPropertyChanged(nameof(IsOpened)); + OnPropertyChanged(nameof(Name)); + } + + public void Recover(UserProfile userProfile) + { + _owner.Navigate(typeof(UserEditor), (_owner, userProfile, true)); + } + } +}
\ No newline at end of file |
