Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
b2c0083a73
@ -19,7 +19,7 @@
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
|
||||
<string>Copyright © 2018 - 2025 Ryujinx Team and Contributors.</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
@ -965,6 +965,7 @@
|
||||
0100C4D00B608000,"Don't Sink",gpu,ingame,2021-02-26 15:41:11
|
||||
0100751007ADA000,"Don't Starve: Nintendo Switch Edition",nvdec,playable,2022-02-05 20:43:34
|
||||
010088B010DD2000,"Dongo Adventure",,playable,2022-10-04 16:22:26
|
||||
01009D901BC56000,"Donkey Kong Country™ Returns HD",gpu;crashes,ingame,2025-01-19 18:26:53
|
||||
0100C1F0051B6000,"Donkey Kong Country™: Tropical Freeze",,playable,2024-08-05 16:46:10
|
||||
0100F2C00F060000,"Doodle Derby",,boots,2020-12-04 22:51:48
|
||||
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
||||
|
|
@ -489,7 +489,7 @@ namespace Ryujinx.Ava
|
||||
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version);
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar);
|
||||
});
|
||||
|
||||
_viewModel.SetUiProgressHandlers(Device);
|
||||
@ -872,7 +872,7 @@ namespace Ryujinx.Ava
|
||||
Device?.System.TogglePauseEmulation(false);
|
||||
|
||||
_viewModel.IsPaused = false;
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version);
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar);
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
||||
}
|
||||
|
||||
@ -881,7 +881,7 @@ namespace Ryujinx.Ava
|
||||
Device?.System.TogglePauseEmulation(true);
|
||||
|
||||
_viewModel.IsPaused = true;
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, LocaleManager.Instance[LocaleKeys.Paused]);
|
||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar, LocaleManager.Instance[LocaleKeys.Paused]);
|
||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ using DiscordRPC;
|
||||
using Gommon;
|
||||
using Humanizer;
|
||||
using Humanizer.Localisation;
|
||||
using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using Ryujinx.Ava.Utilities.Configuration;
|
||||
using Ryujinx.Common;
|
||||
@ -97,7 +98,7 @@ namespace Ryujinx.Ava
|
||||
},
|
||||
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
||||
State = appMeta.LastPlayed.HasValue && appMeta.TimePlayed.TotalSeconds > 5
|
||||
? $"Total play time: {appMeta.TimePlayed.Humanize(2, false, maxUnit: TimeUnit.Hour)}"
|
||||
? $"Total play time: {ValueFormatUtils.FormatTimeSpan(appMeta.TimePlayed)}"
|
||||
: "Never played",
|
||||
Timestamps = Timestamps.Now
|
||||
});
|
||||
|
@ -279,13 +279,13 @@ namespace Ryujinx.Ava.UI.Applet
|
||||
.ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav)));
|
||||
|
||||
profiles.Add(new Models.UserProfile(guest, nav));
|
||||
UserSelectorDialogViewModel viewModel = new();
|
||||
viewModel.Profiles = profiles;
|
||||
viewModel.SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId;
|
||||
UserSelectorDialogViewModel viewModel = new()
|
||||
{
|
||||
Profiles = profiles,
|
||||
SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
|
||||
};
|
||||
UserSelectorDialog content = new(viewModel);
|
||||
(UserId id, _) = await UserSelectorDialog.ShowInputDialog(content);
|
||||
|
||||
selected = id;
|
||||
(selected, _) = await UserSelectorDialog.ShowInputDialog(content);
|
||||
|
||||
dialogCloseEvent.Set();
|
||||
});
|
||||
|
48
src/Ryujinx/UI/Helpers/Commands.cs
Normal file
48
src/Ryujinx/UI/Helpers/Commands.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Helpers
|
||||
{
|
||||
#nullable enable
|
||||
public static class Commands
|
||||
{
|
||||
public static RelayCommand Create(Action action)
|
||||
=> new(action);
|
||||
public static RelayCommand CreateConditional(Action action, Func<bool> canExecute)
|
||||
=> new(action, canExecute);
|
||||
|
||||
public static RelayCommand<T> CreateWithArg<T>(Action<T?> action)
|
||||
=> new(action);
|
||||
public static RelayCommand<T> CreateConditionalWithArg<T>(Action<T?> action, Predicate<T?> canExecute)
|
||||
=> new(action, canExecute);
|
||||
|
||||
public static AsyncRelayCommand Create(Func<Task> action)
|
||||
=> new(action, AsyncRelayCommandOptions.None);
|
||||
public static AsyncRelayCommand CreateConcurrent(Func<Task> action)
|
||||
=> new(action, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
||||
public static AsyncRelayCommand CreateSilentFail(Func<Task> action)
|
||||
=> new(action, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||
|
||||
public static AsyncRelayCommand<T> CreateWithArg<T>(Func<T?, Task> action)
|
||||
=> new(action, AsyncRelayCommandOptions.None);
|
||||
public static AsyncRelayCommand<T> CreateConcurrentWithArg<T>(Func<T?, Task> action)
|
||||
=> new(action, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
||||
public static AsyncRelayCommand<T> CreateSilentFailWithArg<T>(Func<T?, Task> action)
|
||||
=> new(action, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||
|
||||
public static AsyncRelayCommand CreateConditional(Func<Task> action, Func<bool> canExecute)
|
||||
=> new(action, canExecute, AsyncRelayCommandOptions.None);
|
||||
public static AsyncRelayCommand CreateConcurrentConditional(Func<Task> action, Func<bool> canExecute)
|
||||
=> new(action, canExecute, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
||||
public static AsyncRelayCommand CreateSilentFailConditional(Func<Task> action, Func<bool> canExecute)
|
||||
=> new(action, canExecute, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||
|
||||
public static AsyncRelayCommand<T> CreateConditionalWithArg<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
||||
=> new(action, canExecute, AsyncRelayCommandOptions.None);
|
||||
public static AsyncRelayCommand<T> CreateConcurrentConditionalWithArg<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
||||
=> new(action, canExecute, AsyncRelayCommandOptions.AllowConcurrentExecutions);
|
||||
public static AsyncRelayCommand<T> CreateSilentFailConditionalWithArg<T>(Func<T?, Task> action, Predicate<T?> canExecute)
|
||||
=> new(action, canExecute, AsyncRelayCommandOptions.FlowExceptionsToTaskScheduler);
|
||||
}
|
||||
}
|
@ -38,7 +38,6 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
||||
using Ryujinx.HLE.UI;
|
||||
using Ryujinx.Input.HLE;
|
||||
using Silk.NET.Vulkan;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -144,14 +144,14 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
ViewModel.LoadConfigurableHotKeys();
|
||||
}
|
||||
|
||||
public static readonly AppletMetadata MiiApplet = new("miiEdit", 0x0100000000001009);
|
||||
|
||||
public AppletMetadata MiiApplet => new(ViewModel.ContentManager, "miiEdit", 0x0100000000001009);
|
||||
|
||||
public async Task OpenMiiApplet()
|
||||
{
|
||||
if (MiiApplet.CanStart(ViewModel.ContentManager, out var appData, out var nacpData))
|
||||
{
|
||||
await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
||||
}
|
||||
if (!MiiApplet.CanStart(out var appData, out var nacpData))
|
||||
return;
|
||||
|
||||
await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
||||
}
|
||||
|
||||
public async Task OpenCheatManagerForCurrentApp()
|
||||
|
@ -735,21 +735,19 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
});
|
||||
}
|
||||
|
||||
private static bool _intelMacWarningShown;
|
||||
private static bool _intelMacWarningShown = !(OperatingSystem.IsMacOS() &&
|
||||
(RuntimeInformation.OSArchitecture == Architecture.X64 ||
|
||||
RuntimeInformation.OSArchitecture == Architecture.X86));
|
||||
|
||||
public static async Task ShowIntelMacWarningAsync()
|
||||
{
|
||||
if (!_intelMacWarningShown &&
|
||||
(OperatingSystem.IsMacOS() &&
|
||||
(RuntimeInformation.OSArchitecture == Architecture.X64 ||
|
||||
RuntimeInformation.OSArchitecture == Architecture.X86)))
|
||||
{
|
||||
_intelMacWarningShown = true;
|
||||
if (_intelMacWarningShown) return;
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(async () => await ContentDialogHelper.CreateWarningDialog(
|
||||
"Intel Mac Warning",
|
||||
"Intel Macs are not supported and will not work properly.\nIf you continue, do not come to our Discord asking for support;\nand do not report bugs on the GitHub. They will be closed."));
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(async () => await ContentDialogHelper.CreateWarningDialog(
|
||||
"Intel Mac Warning",
|
||||
"Intel Macs are not supported and will not work properly.\nIf you continue, do not come to our Discord asking for support."));
|
||||
}
|
||||
_intelMacWarningShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,5 +54,9 @@ namespace Ryujinx.Ava.Utilities
|
||||
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanStart(out ApplicationData appData,
|
||||
out BlitStruct<ApplicationControlProperty> appControl)
|
||||
=> CanStart(null, out appData, out appControl);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||
|
||||
public class CompatibilityCsv
|
||||
{
|
||||
static CompatibilityCsv()
|
||||
static CompatibilityCsv() => Load();
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
using Stream csvStream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
|
||||
@ -37,15 +39,31 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||
using SepReader reader = Sep.Reader().From(csvStream);
|
||||
ColumnIndices columnIndices = new(reader.Header.IndexOf);
|
||||
|
||||
Entries = reader
|
||||
_entries = reader
|
||||
.Enumerate(row => new CompatibilityEntry(ref columnIndices, row))
|
||||
.OrderBy(it => it.GameName)
|
||||
.ToArray();
|
||||
|
||||
Logger.Debug?.Print(LogClass.UI, "Compatibility CSV loaded.", "LoadCompatCsv");
|
||||
Logger.Debug?.Print(LogClass.UI, "Compatibility CSV loaded.", "LoadCompatibility");
|
||||
}
|
||||
|
||||
public static CompatibilityEntry[] Entries { get; private set; }
|
||||
public static void Unload()
|
||||
{
|
||||
_entries = null;
|
||||
}
|
||||
|
||||
private static CompatibilityEntry[] _entries;
|
||||
|
||||
public static CompatibilityEntry[] Entries
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_entries == null)
|
||||
Load();
|
||||
|
||||
return _entries;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CompatibilityEntry
|
||||
|
@ -1,11 +1,8 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using nietras.SeparatedValues;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Utilities.Compat
|
||||
@ -35,6 +32,8 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||
contentDialog.Styles.Add(closeButtonParent);
|
||||
|
||||
await ContentDialogHelper.ShowAsync(contentDialog);
|
||||
|
||||
CompatibilityCsv.Unload();
|
||||
}
|
||||
|
||||
public CompatibilityList()
|
||||
|
@ -1,19 +1,18 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using ExCSS;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Ava.Utilities.Compat
|
||||
{
|
||||
public partial class CompatibilityViewModel : ObservableObject
|
||||
public class CompatibilityViewModel : BaseModel
|
||||
{
|
||||
[ObservableProperty] private bool _onlyShowOwnedGames = true;
|
||||
private bool _onlyShowOwnedGames = true;
|
||||
|
||||
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Entries;
|
||||
private readonly string[] _ownedGameTitleIds = [];
|
||||
private readonly ApplicationLibrary _appLibrary;
|
||||
private string[] _ownedGameTitleIds = [];
|
||||
|
||||
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
|
||||
? _currentEntries.Where(x =>
|
||||
@ -24,14 +23,23 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||
|
||||
public CompatibilityViewModel(ApplicationLibrary appLibrary)
|
||||
{
|
||||
_appLibrary = appLibrary;
|
||||
appLibrary.ApplicationCountUpdated += (_, _)
|
||||
=> _ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
||||
|
||||
_ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
||||
}
|
||||
|
||||
PropertyChanged += (_, args) =>
|
||||
public bool OnlyShowOwnedGames
|
||||
{
|
||||
get => _onlyShowOwnedGames;
|
||||
set
|
||||
{
|
||||
if (args.PropertyName is nameof(OnlyShowOwnedGames))
|
||||
OnPropertyChanged(nameof(CurrentEntries));
|
||||
};
|
||||
OnPropertyChanging();
|
||||
OnPropertyChanging(nameof(CurrentEntries));
|
||||
_onlyShowOwnedGames = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(CurrentEntries));
|
||||
}
|
||||
}
|
||||
|
||||
public void Search(string searchTerm)
|
||||
|
@ -4,7 +4,7 @@ namespace Ryujinx.Ava.Utilities
|
||||
{
|
||||
public static class TitleHelper
|
||||
{
|
||||
public static string ActiveApplicationTitle(ProcessResult activeProcess, string applicationVersion, string pauseString = "")
|
||||
public static string ActiveApplicationTitle(ProcessResult activeProcess, string applicationVersion, bool customTitlebar, string pauseString = "")
|
||||
{
|
||||
if (activeProcess == null)
|
||||
return string.Empty;
|
||||
@ -14,7 +14,9 @@ namespace Ryujinx.Ava.Utilities
|
||||
string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})";
|
||||
string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)";
|
||||
|
||||
string appTitle = $"Ryujinx {applicationVersion} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}";
|
||||
string appTitle = customTitlebar
|
||||
? $"Ryujinx {applicationVersion}\n{titleNameSection.Trim()}\n{titleVersionSection.Trim()}\n{titleIdSection.Trim()}{titleArchSection}"
|
||||
: $"Ryujinx {applicationVersion} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}";
|
||||
|
||||
return !string.IsNullOrEmpty(pauseString)
|
||||
? appTitle + $" ({pauseString})"
|
||||
|
Loading…
x
Reference in New Issue
Block a user