Compare commits
15 Commits
Canary-1.2
...
Canary-1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
290ac405ac | ||
|
|
bbd64fd5f0 | ||
|
|
09446fd80e | ||
|
|
4f014a89cf | ||
|
|
6482e566ab | ||
|
|
7fcd9b792e | ||
|
|
e676fd8b17 | ||
|
|
dd16e3cee1 | ||
|
|
31e5f74e05 | ||
|
|
f2f099bddb | ||
|
|
2616dc57fb | ||
|
|
0cdf7cfe21 | ||
|
|
2ecf999569 | ||
|
|
b612fc5155 | ||
|
|
25eb545409 |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -22,7 +22,7 @@ body:
|
|||||||
id: log
|
id: log
|
||||||
attributes:
|
attributes:
|
||||||
label: Log file
|
label: Log file
|
||||||
description: A log file will help our developers to better diagnose and fix the issue.
|
description: "A log file will help our developers to better diagnose and fix the issue. UPLOAD THE FILE. DO NOT COPY AND PASTE THE FILE'S CONTENT."
|
||||||
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<key>CSResourcesFileMapped</key>
|
<key>CSResourcesFileMapped</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string>
|
<string>Copyright © 2018 - 2025 Ryujinx Team and Contributors.</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@@ -965,6 +965,7 @@
|
|||||||
0100C4D00B608000,"Don't Sink",gpu,ingame,2021-02-26 15:41:11
|
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
|
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
|
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
|
0100C1F0051B6000,"Donkey Kong Country™: Tropical Freeze",,playable,2024-08-05 16:46:10
|
||||||
0100F2C00F060000,"Doodle Derby",,boots,2020-12-04 22:51:48
|
0100F2C00F060000,"Doodle Derby",,boots,2020-12-04 22:51:48
|
||||||
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
||||||
|
|||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -47,6 +47,9 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
public static readonly string[] DiscordGameAssetKeys =
|
public static readonly string[] DiscordGameAssetKeys =
|
||||||
[
|
[
|
||||||
|
"010008900705c000", // Dragon Quest Builders
|
||||||
|
"010042000a986000", // Dragon Quest Builders 2
|
||||||
|
|
||||||
"010055d009f78000", // Fire Emblem: Three Houses
|
"010055d009f78000", // Fire Emblem: Three Houses
|
||||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
||||||
"0100a6301214e000", // Fire Emblem Engage
|
"0100a6301214e000", // Fire Emblem Engage
|
||||||
@@ -105,17 +108,18 @@ namespace Ryujinx.Common
|
|||||||
"0100f4c009322000", // Pikmin 3 Deluxe
|
"0100f4c009322000", // Pikmin 3 Deluxe
|
||||||
"0100b7c00933a000", // Pikmin 4
|
"0100b7c00933a000", // Pikmin 4
|
||||||
|
|
||||||
|
"0100f4300bf2c000", // New Pokémon Snap
|
||||||
|
"0100000011d90000", // Pokémon Brilliant Diamond
|
||||||
|
"01001f5010dfa000", // Pokémon Legends: Arceus
|
||||||
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
"010003f003a34000", // Pokémon: Let's Go Pikachu!
|
||||||
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
"0100187003a36000", // Pokémon: Let's Go Eevee!
|
||||||
"0100abf008968000", // Pokémon Sword
|
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
||||||
"01008db008c2c000", // Pokémon Shield
|
|
||||||
"0100000011d90000", // Pokémon Brilliant Diamond
|
|
||||||
"010018e011d92000", // Pokémon Shining Pearl
|
|
||||||
"01001f5010dfa000", // Pokémon Legends: Arceus
|
|
||||||
"0100a3d008c5c000", // Pokémon Scarlet
|
"0100a3d008c5c000", // Pokémon Scarlet
|
||||||
|
"01008db008c2c000", // Pokémon Shield
|
||||||
|
"010018e011d92000", // Pokémon Shining Pearl
|
||||||
|
"0100abf008968000", // Pokémon Sword
|
||||||
"01008f6008c5e000", // Pokémon Violet
|
"01008f6008c5e000", // Pokémon Violet
|
||||||
"0100b3f000be2000", // Pokkén Tournament DX
|
"0100b3f000be2000", // Pokkén Tournament DX
|
||||||
"0100f4300bf2c000", // New Pokémon Snap
|
|
||||||
|
|
||||||
"01003bc0000a0000", // Splatoon 2 (US)
|
"01003bc0000a0000", // Splatoon 2 (US)
|
||||||
"0100f8f0000a2000", // Splatoon 2 (EU)
|
"0100f8f0000a2000", // Splatoon 2 (EU)
|
||||||
@@ -165,13 +169,21 @@ namespace Ryujinx.Common
|
|||||||
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
"01005ea01c0fc000", // SONIC X SHADOW GENERATIONS
|
||||||
"01005ea01c0fc001", // ^
|
"01005ea01c0fc001", // ^
|
||||||
|
|
||||||
|
"0100ff500e34a000", // Xenoblade Chronicles - Definitive Edition
|
||||||
|
"0100e95004038000", // Xenoblade Chronicles 2
|
||||||
|
"010074f013262000", // Xenoblade Chronicles 3
|
||||||
|
|
||||||
"010056e00853a000", // A Hat in Time
|
"010056e00853a000", // A Hat in Time
|
||||||
|
"0100fd1014726000", // Baldurs Gate: Dark Alliance
|
||||||
"0100dbf01000a000", // Burnout Paradise Remastered
|
"0100dbf01000a000", // Burnout Paradise Remastered
|
||||||
"0100744001588000", // Cars 3: Driven to Win
|
"0100744001588000", // Cars 3: Driven to Win
|
||||||
"0100b41013c82000", // Cruis'n Blast
|
"0100b41013c82000", // Cruis'n Blast
|
||||||
|
"010085900337e000", // Death Squared
|
||||||
"01001b300b9be000", // Diablo III: Eternal Collection
|
"01001b300b9be000", // Diablo III: Eternal Collection
|
||||||
"01008c8012920000", // Dying Light Platinum Edition
|
"01008c8012920000", // Dying Light Platinum Edition
|
||||||
"01001cc01b2d4000", // Goat Simulator 3
|
"01001cc01b2d4000", // Goat Simulator 3
|
||||||
|
"01003620068ea000", // Hand of Fate 2
|
||||||
|
"010085500130a000", // Lego City: Undercover
|
||||||
"010073c01af34000", // LEGO Horizon Adventures
|
"010073c01af34000", // LEGO Horizon Adventures
|
||||||
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
"0100770008dd8000", // Monster Hunter Generations Ultimate
|
||||||
"0100b04011742000", // Monster Hunter Rise
|
"0100b04011742000", // Monster Hunter Rise
|
||||||
@@ -190,6 +202,8 @@ namespace Ryujinx.Common
|
|||||||
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
"01000a10041ea000", // The Elder Scrolls V: Skyrim
|
||||||
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
"010057a01e4d4000", // TSUKIHIME -A piece of blue glass moon-
|
||||||
"010080b00ad66000", // Undertale
|
"010080b00ad66000", // Undertale
|
||||||
|
"010069401adb8000", // Unicorn Overlord
|
||||||
|
"0100534009ff2000", // Yonder - The cloud catcher chronicles
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
Dispatcher.UIThread.InvokeAsync(() =>
|
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);
|
_viewModel.SetUiProgressHandlers(Device);
|
||||||
@@ -872,7 +872,7 @@ namespace Ryujinx.Ava
|
|||||||
Device?.System.TogglePauseEmulation(false);
|
Device?.System.TogglePauseEmulation(false);
|
||||||
|
|
||||||
_viewModel.IsPaused = 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");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,7 +881,7 @@ namespace Ryujinx.Ava
|
|||||||
Device?.System.TogglePauseEmulation(true);
|
Device?.System.TogglePauseEmulation(true);
|
||||||
|
|
||||||
_viewModel.IsPaused = 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");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,11 +4,11 @@ namespace Ryujinx.Ava.Common
|
|||||||
{
|
{
|
||||||
public static class ThemeManager
|
public static class ThemeManager
|
||||||
{
|
{
|
||||||
public static event EventHandler ThemeChanged;
|
public static event Action ThemeChanged;
|
||||||
|
|
||||||
public static void OnThemeChanged()
|
public static void OnThemeChanged()
|
||||||
{
|
{
|
||||||
ThemeChanged?.Invoke(null, EventArgs.Empty);
|
ThemeChanged?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using DiscordRPC;
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using Humanizer.Localisation;
|
using Humanizer.Localisation;
|
||||||
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
@@ -97,7 +98,7 @@ namespace Ryujinx.Ava
|
|||||||
},
|
},
|
||||||
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
||||||
State = appMeta.LastPlayed.HasValue && appMeta.TimePlayed.TotalSeconds > 5
|
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",
|
: "Never played",
|
||||||
Timestamps = Timestamps.Now
|
Timestamps = Timestamps.Now
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -279,13 +279,13 @@ namespace Ryujinx.Ava.UI.Applet
|
|||||||
.ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav)));
|
.ForEach(profile => profiles.Add(new Models.UserProfile(profile, nav)));
|
||||||
|
|
||||||
profiles.Add(new Models.UserProfile(guest, nav));
|
profiles.Add(new Models.UserProfile(guest, nav));
|
||||||
UserSelectorDialogViewModel viewModel = new();
|
UserSelectorDialogViewModel viewModel = new()
|
||||||
viewModel.Profiles = profiles;
|
{
|
||||||
viewModel.SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId;
|
Profiles = profiles,
|
||||||
|
SelectedUserId = _parent.AccountManager.LastOpenedUser.UserId
|
||||||
|
};
|
||||||
UserSelectorDialog content = new(viewModel);
|
UserSelectorDialog content = new(viewModel);
|
||||||
(UserId id, _) = await UserSelectorDialog.ShowInputDialog(content);
|
(selected, _) = await UserSelectorDialog.ShowInputDialog(content);
|
||||||
|
|
||||||
selected = id;
|
|
||||||
|
|
||||||
dialogCloseEvent.Set();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
|
ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThemeManager_ThemeChanged(object sender, EventArgs e)
|
private void ThemeManager_ThemeChanged()
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
|
Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
|||||||
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
|
||||||
using Ryujinx.HLE.UI;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Silk.NET.Vulkan;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -43,7 +43,13 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
PauseEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Pause());
|
PauseEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Pause());
|
||||||
ResumeEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Resume());
|
ResumeEmulationMenuItem.Command = new RelayCommand(() => ViewModel.AppHost?.Resume());
|
||||||
StopEmulationMenuItem.Command = new AsyncRelayCommand(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
StopEmulationMenuItem.Command = new AsyncRelayCommand(() => ViewModel.AppHost?.ShowExitPrompt().OrCompleted());
|
||||||
CheatManagerMenuItem.Command = new AsyncRelayCommand(OpenCheatManagerForCurrentApp);
|
CheatManagerMenuItem.Command = new AsyncRelayCommand(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await OpenCheatManagerForCurrentApp();
|
||||||
|
} catch {}
|
||||||
|
});
|
||||||
InstallFileTypesMenuItem.Command = new AsyncRelayCommand(InstallFileTypes);
|
InstallFileTypesMenuItem.Command = new AsyncRelayCommand(InstallFileTypes);
|
||||||
UninstallFileTypesMenuItem.Command = new AsyncRelayCommand(UninstallFileTypes);
|
UninstallFileTypesMenuItem.Command = new AsyncRelayCommand(UninstallFileTypes);
|
||||||
XciTrimmerMenuItem.Command = new AsyncRelayCommand(() => XCITrimmerWindow.Show(ViewModel));
|
XciTrimmerMenuItem.Command = new AsyncRelayCommand(() => XCITrimmerWindow.Show(ViewModel));
|
||||||
@@ -138,14 +144,14 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
ViewModel.LoadConfigurableHotKeys();
|
ViewModel.LoadConfigurableHotKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly AppletMetadata MiiApplet = new("miiEdit", 0x0100000000001009);
|
public AppletMetadata MiiApplet => new(ViewModel.ContentManager, "miiEdit", 0x0100000000001009);
|
||||||
|
|
||||||
public async Task OpenMiiApplet()
|
public async Task OpenMiiApplet()
|
||||||
{
|
{
|
||||||
if (MiiApplet.CanStart(ViewModel.ContentManager, out var appData, out var nacpData))
|
if (!MiiApplet.CanStart(out var appData, out var nacpData))
|
||||||
{
|
return;
|
||||||
await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
|
||||||
}
|
await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OpenCheatManagerForCurrentApp()
|
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()
|
public static async Task ShowIntelMacWarningAsync()
|
||||||
{
|
{
|
||||||
if (!_intelMacWarningShown &&
|
if (_intelMacWarningShown) return;
|
||||||
(OperatingSystem.IsMacOS() &&
|
|
||||||
(RuntimeInformation.OSArchitecture == Architecture.X64 ||
|
|
||||||
RuntimeInformation.OSArchitecture == Architecture.X86)))
|
|
||||||
{
|
|
||||||
_intelMacWarningShown = true;
|
|
||||||
|
|
||||||
await Dispatcher.UIThread.InvokeAsync(async () => await ContentDialogHelper.CreateWarningDialog(
|
await Dispatcher.UIThread.InvokeAsync(async () => await ContentDialogHelper.CreateWarningDialog(
|
||||||
"Intel Mac Warning",
|
"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."));
|
"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."));
|
||||||
}
|
|
||||||
|
_intelMacWarningShown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,9 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
||||||
return false;
|
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
|
public class CompatibilityCsv
|
||||||
{
|
{
|
||||||
static CompatibilityCsv()
|
static CompatibilityCsv() => Load();
|
||||||
|
|
||||||
|
public static void Load()
|
||||||
{
|
{
|
||||||
using Stream csvStream = Assembly.GetExecutingAssembly()
|
using Stream csvStream = Assembly.GetExecutingAssembly()
|
||||||
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
|
.GetManifestResourceStream("RyujinxGameCompatibilityList")!;
|
||||||
@@ -37,15 +39,31 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
using SepReader reader = Sep.Reader().From(csvStream);
|
using SepReader reader = Sep.Reader().From(csvStream);
|
||||||
ColumnIndices columnIndices = new(reader.Header.IndexOf);
|
ColumnIndices columnIndices = new(reader.Header.IndexOf);
|
||||||
|
|
||||||
Entries = reader
|
_entries = reader
|
||||||
.Enumerate(row => new CompatibilityEntry(ref columnIndices, row))
|
.Enumerate(row => new CompatibilityEntry(ref columnIndices, row))
|
||||||
.OrderBy(it => it.GameName)
|
.OrderBy(it => it.GameName)
|
||||||
.ToArray();
|
.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
|
public class CompatibilityEntry
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using nietras.SeparatedValues;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Compat
|
namespace Ryujinx.Ava.Utilities.Compat
|
||||||
@@ -35,6 +32,8 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
contentDialog.Styles.Add(closeButtonParent);
|
contentDialog.Styles.Add(closeButtonParent);
|
||||||
|
|
||||||
await ContentDialogHelper.ShowAsync(contentDialog);
|
await ContentDialogHelper.ShowAsync(contentDialog);
|
||||||
|
|
||||||
|
CompatibilityCsv.Unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompatibilityList()
|
public CompatibilityList()
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using ExCSS;
|
|
||||||
using Gommon;
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Compat
|
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 IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Entries;
|
||||||
private readonly string[] _ownedGameTitleIds = [];
|
private string[] _ownedGameTitleIds = [];
|
||||||
private readonly ApplicationLibrary _appLibrary;
|
|
||||||
|
|
||||||
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
|
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
|
||||||
? _currentEntries.Where(x =>
|
? _currentEntries.Where(x =>
|
||||||
@@ -24,14 +23,23 @@ namespace Ryujinx.Ava.Utilities.Compat
|
|||||||
|
|
||||||
public CompatibilityViewModel(ApplicationLibrary appLibrary)
|
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) =>
|
_ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnlyShowOwnedGames
|
||||||
|
{
|
||||||
|
get => _onlyShowOwnedGames;
|
||||||
|
set
|
||||||
{
|
{
|
||||||
if (args.PropertyName is nameof(OnlyShowOwnedGames))
|
OnPropertyChanging();
|
||||||
OnPropertyChanged(nameof(CurrentEntries));
|
OnPropertyChanging(nameof(CurrentEntries));
|
||||||
};
|
_onlyShowOwnedGames = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
OnPropertyChanged(nameof(CurrentEntries));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Search(string searchTerm)
|
public void Search(string searchTerm)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
{
|
{
|
||||||
public static class TitleHelper
|
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)
|
if (activeProcess == null)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@@ -14,7 +14,9 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})";
|
string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})";
|
||||||
string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)";
|
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)
|
return !string.IsNullOrEmpty(pauseString)
|
||||||
? appTitle + $" ({pauseString})"
|
? appTitle + $" ({pauseString})"
|
||||||
|
|||||||
Reference in New Issue
Block a user