mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-09-13 07:02:18 -06:00
Merge branch 'master' of https://git.ryujinx.app/ryubing/ryujinx into Spanish-Translation-capitalization
This commit is contained in:
@ -19,8 +19,8 @@
|
||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
||||
<PackageVersion Include="Concentus" Version="2.2.2" />
|
||||
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
||||
<PackageVersion Include="DynamicData" Version="9.4.1" />
|
||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||
@ -42,11 +42,11 @@
|
||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" />
|
||||
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
|
||||
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.2.1" />
|
||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||
<PackageVersion Include="Sep" Version="0.11.1" />
|
||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
|
||||
|
@ -896,25 +896,25 @@
|
||||
"ID": "MenuBarFileActionsInstallKeysFromFile",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "Schlüssel (.KEYS oder .ZIP) installieren",
|
||||
"de_DE": "Schlüssel (.KEYS) installieren",
|
||||
"el_GR": "",
|
||||
"en_US": "Install Keys (.KEYS or .ZIP)",
|
||||
"es_ES": "Instalar Claves (.KEYS o .ZIP)",
|
||||
"fr_FR": "Installer des Clés (.KEYS ou .ZIP)",
|
||||
"en_US": "Install Keys (.KEYS)",
|
||||
"es_ES": "Instalar Claves (.KEYS)",
|
||||
"fr_FR": "Installer des Clés (.KEYS)",
|
||||
"he_IL": "",
|
||||
"it_IT": "Installa chiavi (.KEYS o .ZIP)",
|
||||
"it_IT": "Installa chiavi (.KEYS)",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "키 설치 (.KEYS 또는 .ZIP)",
|
||||
"no_NO": "Installer nøkler (.KEYS eller .ZIP)",
|
||||
"ko_KR": "키 설치 (.KEYS)",
|
||||
"no_NO": "Installer nøkler (.KEYS)",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "Instalar chaves (.KEYS ou .ZIP",
|
||||
"ru_RU": "Установить ключи (.KEYS или .ZIP)",
|
||||
"sv_SE": "Installera nycklar (.KEYS eller .ZIP)",
|
||||
"th_TH": "ติดตั้งคีย์ (.KEYS หรือ .ZIP)",
|
||||
"pt_BR": "Instalar chaves (.KEYS)",
|
||||
"ru_RU": "Установить ключи (.KEYS)",
|
||||
"sv_SE": "Installera nycklar (.KEYS)",
|
||||
"th_TH": "ติดตั้งคีย์ (.KEYS)",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "Встановити ключі (.KEYS або .ZIP)",
|
||||
"zh_CN": "安装密钥(.KEYS 或 .ZIP)",
|
||||
"zh_TW": "安裝金鑰(.KEYS 或 .ZIP)"
|
||||
"uk_UA": "Встановити ключі (.KEYS)",
|
||||
"zh_CN": "安装密钥(.KEYS)",
|
||||
"zh_TW": "安裝金鑰(.KEYS)"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -978,7 +978,7 @@
|
||||
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
|
||||
010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19
|
||||
01008CB01E52E000,"DOOM + DOOM II",opengl;ldn-untested;LAN,playable,2024-09-12 07:06:01
|
||||
010029D00E740000,"DOOM 3",crash,menus,2024-08-03 05:25:47
|
||||
010029D00E740000,"DOOM 3",crash;slow,menus,2024-08-03 05:25:47
|
||||
01005D700E742000,"DOOM 64",nvdec;vulkan,playable,2020-10-13 23:47:28
|
||||
0100D4F00DD02000,"DOOM II (Classic)",nvdec;online,playable,2021-06-03 20:10:01
|
||||
0100B1A00D8CE000,"DOOM® Eternal",gpu;slow;nvdec;online-broken,ingame,2024-08-28 15:57:17
|
||||
@ -1097,7 +1097,7 @@
|
||||
0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08
|
||||
010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14
|
||||
01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58
|
||||
010018f01e0a0000,"Eternights",,playable,2025-07-30 12:10:24
|
||||
010018F01E0A0000,"Eternights",,playable,2025-07-30 12:10:24
|
||||
0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32
|
||||
010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12
|
||||
01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30
|
||||
@ -1243,7 +1243,7 @@
|
||||
010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38
|
||||
010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27
|
||||
0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24
|
||||
0100c4e018a24000,"FRONT MISSION 2: Remake",,playable,2025-07-30 12:11:23
|
||||
0100C4E018A24000,"FRONT MISSION 2: Remake",,playable,2025-07-30 12:11:23
|
||||
01007E6019872000,"FRONT MISSION 3: Remake",,playable,2025-07-30 12:12:02
|
||||
0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59
|
||||
0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36
|
||||
@ -1450,6 +1450,7 @@
|
||||
0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35
|
||||
0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58
|
||||
0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56
|
||||
010013C00E930000,"Hollow Knight: Silksong",,playable,2025-09-04 17:23:22
|
||||
0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56
|
||||
0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56
|
||||
010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38
|
||||
@ -1888,7 +1889,7 @@
|
||||
010097800EA20000,"Monster Energy Supercross - The Official Videogame 3",UE4;audout;nvdec;online,playable,2021-06-14 12:37:54
|
||||
0100E9900ED74000,"Monster Farm",32-bit;nvdec,playable,2021-05-05 19:29:13
|
||||
0100770008DD8000,"Monster Hunter Generations Ultimate™",32-bit;online-broken;ldn-works,playable,2024-03-18 14:35:36
|
||||
0100B04011742000,"Monster Hunter Rise",gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works,ingame,2024-08-24 11:04:59
|
||||
0100B04011742000,"MONSTER HUNTER RISE",gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works,ingame,2024-08-24 11:04:59
|
||||
010093A01305C000,"Monster Hunter Rise Demo",online-broken;ldn-works;demo,playable,2022-10-18 23:04:17
|
||||
0100E21011446000,"Monster Hunter Stories 2: Wings of Ruin",services,ingame,2022-07-10 19:27:30
|
||||
010042501329E000,"MONSTER HUNTER STORIES 2: WINGS OF RUIN Trial Version",demo,playable,2022-11-13 22:20:26
|
||||
@ -2313,7 +2314,7 @@
|
||||
010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19
|
||||
010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45
|
||||
0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33
|
||||
0100c3a017834000,"Prodeus",,playable,2025-07-30 12:07:52
|
||||
0100C3A017834000,"Prodeus",,playable,2025-07-30 12:07:52
|
||||
0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12
|
||||
0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43
|
||||
01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27
|
||||
@ -2579,6 +2580,7 @@
|
||||
0100C610154CA000,"Shadowrun: Hong Kong - Extended Edition",gpu;Needs Update,ingame,2022-10-04 20:53:09
|
||||
010000000EEF0000,"Shadows 2: Perfidia",,playable,2020-08-07 12:43:46
|
||||
0100AD700CBBE000,"Shadows of Adam",,playable,2021-01-11 13:35:58
|
||||
010037A01F96C000,"Shadows of the Damned: Hella Remastered",,playable,2025-09-05 11:34:32
|
||||
01002A800C064000,"Shadowverse Champions Battle",,playable,2022-10-02 22:59:29
|
||||
01003B90136DA000,"Shadowverse: Champion's Battle",crash,nothing,2023-03-06 00:31:50
|
||||
0100820013612000,"Shady Part of Me",,playable,2022-10-20 11:31:55
|
||||
@ -2977,6 +2979,7 @@
|
||||
0100EBA01548E000,"The Cruel King and the Great Hero",gpu;services,ingame,2022-12-02 07:02:08
|
||||
010051800E922000,"The Dark Crystal: Age of Resistance Tactics",,playable,2020-08-11 13:43:41
|
||||
01003DE00918E000,"The Darkside Detective",,playable,2020-06-03 22:16:18
|
||||
010032B015D66000,"The DioField Chronicle",,playable,2025-09-05 11:35:50
|
||||
01000A10041EA000,"The Elder Scrolls V: Skyrim",gpu;crash,ingame,2024-07-14 03:21:31
|
||||
01004A9006B84000,"The End Is Nigh",,playable,2020-06-01 11:26:45
|
||||
0100CA100489C000,"The Escapists 2",nvdec,playable,2020-09-24 12:31:31
|
||||
|
|
@ -182,6 +182,7 @@ namespace Ryujinx.Common
|
||||
"01001cc01b2d4000", // Goat Simulator 3
|
||||
"01003620068ea000", // Hand of Fate 2
|
||||
"0100f7e00c70e000", // Hogwarts Legacy
|
||||
"010013c00e930000", // Hollow Knight: Silksong
|
||||
"010085500130a000", // Lego City: Undercover
|
||||
"010073c01af34000", // LEGO Horizon Adventures
|
||||
"0100d71004694000", // Minecraft
|
||||
|
@ -501,54 +501,14 @@ namespace Ryujinx.HLE.FileSystem
|
||||
|
||||
using FileStream file = File.OpenRead(keysSource);
|
||||
|
||||
switch (info.Extension)
|
||||
if (info.Extension is ".keys")
|
||||
{
|
||||
case ".zip":
|
||||
using (ZipArchive archive = ZipFile.OpenRead(keysSource))
|
||||
{
|
||||
InstallKeysFromZip(archive, installDirectory);
|
||||
}
|
||||
|
||||
break;
|
||||
case ".keys":
|
||||
VerifyKeysFile(keysSource);
|
||||
File.Copy(keysSource, Path.Combine(installDirectory, info.Name), true);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
else
|
||||
throw new InvalidFirmwarePackageException("Input file is not a valid key package");
|
||||
}
|
||||
}
|
||||
|
||||
private static void InstallKeysFromZip(ZipArchive archive, string installDirectory)
|
||||
{
|
||||
string temporaryDirectory = Path.Combine(installDirectory, "temp");
|
||||
if (Directory.Exists(temporaryDirectory))
|
||||
{
|
||||
Directory.Delete(temporaryDirectory, true);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(temporaryDirectory);
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
if (Path.GetExtension(entry.FullName).Equals(".keys", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string extractDestination = Path.Combine(temporaryDirectory, entry.Name);
|
||||
entry.ExtractToFile(extractDestination, overwrite: true);
|
||||
try
|
||||
{
|
||||
VerifyKeysFile(extractDestination);
|
||||
File.Move(extractDestination, Path.Combine(installDirectory, entry.Name), true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Directory.Delete(temporaryDirectory, true);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Directory.Delete(temporaryDirectory, true);
|
||||
}
|
||||
|
||||
private void FinishInstallation(string temporaryDirectory, string registeredDirectory)
|
||||
{
|
||||
|
@ -31,11 +31,13 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
private readonly KEvent _friendInvitationStorageChannelEvent;
|
||||
private readonly KEvent _notificationStorageChannelEvent;
|
||||
private readonly KEvent _healthWarningDisappearedSystemEvent;
|
||||
private readonly KEvent _unknownEvent;
|
||||
|
||||
private int _gpuErrorDetectedSystemEventHandle;
|
||||
private int _friendInvitationStorageChannelEventHandle;
|
||||
private int _notificationStorageChannelEventHandle;
|
||||
private int _healthWarningDisappearedSystemEventHandle;
|
||||
private int _unknownEventHandle;
|
||||
|
||||
private bool _gamePlayRecordingState;
|
||||
|
||||
@ -50,6 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
_friendInvitationStorageChannelEvent = new KEvent(system.KernelContext);
|
||||
_notificationStorageChannelEvent = new KEvent(system.KernelContext);
|
||||
_healthWarningDisappearedSystemEvent = new KEvent(system.KernelContext);
|
||||
_unknownEvent = new KEvent(system.KernelContext);
|
||||
|
||||
_horizon = system.LibHacHorizonManager.AmClient;
|
||||
}
|
||||
@ -648,6 +651,23 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(210)] // 20.0.0+
|
||||
// GetUnknownEvent() -> handle<copy>
|
||||
public ResultCode GetUnknownEvent(ServiceCtx context)
|
||||
{
|
||||
if (_unknownEventHandle == 0)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_unknownEvent.ReadableEvent, out _unknownEventHandle) != Result.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
}
|
||||
|
||||
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_unknownEventHandle);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(1001)] // 10.0.0+
|
||||
// PrepareForJit()
|
||||
public ResultCode PrepareForJit(ServiceCtx context)
|
||||
|
@ -39,9 +39,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
|
||||
|
||||
public ref AtomicStorage<T> GetCurrentAtomicEntryRef()
|
||||
{
|
||||
ulong countAvailaible = Math.Min(Math.Max(0, ReadCurrentCount()), 1);
|
||||
ulong countAvailable = Math.Min(Math.Max(0, ReadCurrentCount()), 1);
|
||||
|
||||
if (countAvailaible == 0)
|
||||
if (countAvailable == 0)
|
||||
{
|
||||
_storage[0] = default;
|
||||
|
||||
@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
|
||||
|
||||
while (true)
|
||||
{
|
||||
int inputEntryIndex = (int)((index + MaxEntries + 1 - countAvailaible) % MaxEntries);
|
||||
int inputEntryIndex = (int)((index + MaxEntries + 1 - countAvailable) % MaxEntries);
|
||||
|
||||
ref AtomicStorage<T> result = ref storageSpan[inputEntryIndex];
|
||||
|
||||
@ -63,9 +63,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
|
||||
|
||||
if (samplingNumber0 != samplingNumber1 && (result.SamplingNumber - result.SamplingNumber) != 1)
|
||||
{
|
||||
ulong tempCount = Math.Min(ReadCurrentCount(), countAvailaible);
|
||||
ulong tempCount = Math.Min(ReadCurrentCount(), countAvailable);
|
||||
|
||||
countAvailaible = Math.Min(tempCount, 1);
|
||||
countAvailable = Math.Min(tempCount, 1);
|
||||
index = ReadCurrentIndex();
|
||||
|
||||
continue;
|
||||
|
@ -0,0 +1,23 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
|
||||
{
|
||||
struct NpadCondition
|
||||
{
|
||||
#pragma warning disable CS0414 // Field is assigned but its value is never used
|
||||
private uint _00;
|
||||
private uint _04;
|
||||
private NpadJoyHoldType _holdType;
|
||||
private uint _0C;
|
||||
#pragma warning restore CS0414 // Field is assigned but its value is never used
|
||||
|
||||
public static NpadCondition Create()
|
||||
{
|
||||
return new NpadCondition()
|
||||
{
|
||||
_00 = 0,
|
||||
_04 = 1,
|
||||
_holdType = NpadJoyHoldType.Horizontal,
|
||||
_0C = 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
|
||||
public NpadLarkType LarkTypeRight;
|
||||
public NpadLuciaType LuciaType;
|
||||
public uint Unknown43EC;
|
||||
public ulong SixAxisSensorPropertiesArray;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 123, Pack = 1)]
|
||||
private struct Reserved2Struct { }
|
||||
|
@ -53,6 +53,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory
|
||||
[FieldOffset(0x3DC00)]
|
||||
public RingLifo<DebugMouseState> DebugMouse;
|
||||
|
||||
/// <summary>
|
||||
/// Pad Condition.
|
||||
/// </summary>
|
||||
[FieldOffset(0x3e200)]
|
||||
public NpadCondition Condition;
|
||||
|
||||
public static SharedMemory Create()
|
||||
{
|
||||
SharedMemory result = new()
|
||||
@ -61,6 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory
|
||||
TouchScreen = RingLifo<TouchScreenState>.Create(),
|
||||
Mouse = RingLifo<MouseState>.Create(),
|
||||
Keyboard = RingLifo<KeyboardState>.Create(),
|
||||
Condition = NpadCondition.Create(),
|
||||
};
|
||||
|
||||
Span<NpadState> npadsSpan = result.Npads.AsSpan();
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using Gommon;
|
||||
using LibHac;
|
||||
using LibHac.Account;
|
||||
using LibHac.Common;
|
||||
@ -411,7 +410,7 @@ namespace Ryujinx.Ava.Common
|
||||
|
||||
public static async Task ExtractAoc(IStorageProvider storageProvider, string updateFilePath, string updateName)
|
||||
{
|
||||
Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||
Gommon.Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle]
|
||||
});
|
||||
@ -424,7 +423,7 @@ namespace Ryujinx.Ava.Common
|
||||
|
||||
public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
|
||||
{
|
||||
Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||
Gommon.Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle]
|
||||
});
|
||||
|
@ -1045,7 +1045,7 @@ namespace Ryujinx.Ava.Systems
|
||||
_viewModel.Window.TitleBar.ExtendsContentIntoTitleBar = true;
|
||||
}
|
||||
|
||||
if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUI)
|
||||
if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUi)
|
||||
{
|
||||
_viewModel.ShowMenuAndStatusBar = false;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ namespace Ryujinx.Ava.Systems.AppLibrary
|
||||
|
||||
using UniqueRef<IFile> npdmFile = new();
|
||||
|
||||
Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
|
||||
LibHac.Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
|
||||
|
||||
if (ResultFs.PathNotFound.Includes(result))
|
||||
{
|
||||
|
@ -98,7 +98,9 @@ namespace Ryujinx.Ava.Systems.PlayReport
|
||||
_ => FormattedValue.ForceReset
|
||||
};
|
||||
|
||||
return $"{playStatus} in {locations}";
|
||||
return locations.Reset
|
||||
? FormattedValue.ForceReset
|
||||
: $"{playStatus} in {locations}";
|
||||
}
|
||||
|
||||
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)
|
||||
|
@ -7,6 +7,7 @@ using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Systems.Update.Client;
|
||||
using Ryujinx.Systems.Update.Common;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.Systems
|
||||
@ -14,9 +15,11 @@ namespace Ryujinx.Ava.Systems
|
||||
internal static partial class Updater
|
||||
{
|
||||
private static VersionResponse _versionResponse;
|
||||
private static UpdateClient _updateClient;
|
||||
|
||||
private static UpdateClient CreateUpdateClient()
|
||||
=> UpdateClient.Builder()
|
||||
private static async Task<Return<VersionResponse>> QueryLatestVersionAsync()
|
||||
{
|
||||
_updateClient ??= UpdateClient.Builder()
|
||||
.WithServerEndpoint("https://update.ryujinx.app") // This is the default, and doesn't need to be provided; it's here for transparency.
|
||||
.WithLogger((format, args, caller) =>
|
||||
Logger.Info?.Print(
|
||||
@ -25,6 +28,26 @@ namespace Ryujinx.Ava.Systems
|
||||
caller: caller)
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
return await _updateClient.QueryLatestAsync(ReleaseInformation.IsCanaryBuild
|
||||
? ReleaseChannel.Canary
|
||||
: ReleaseChannel.Stable);
|
||||
}
|
||||
catch (HttpRequestException hre)
|
||||
when (hre.HttpRequestError is HttpRequestError.ConnectionError)
|
||||
{
|
||||
return Return<VersionResponse>.Failure(
|
||||
new MessageError("Connection error occurred. Is your internet down?"));
|
||||
}
|
||||
catch (HttpRequestException hre)
|
||||
when (hre.HttpRequestError is HttpRequestError.NameResolutionError)
|
||||
{
|
||||
return Return<VersionResponse>.Failure(
|
||||
new MessageError("DNS resolution error occurred. Is your internet down?"));
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false)
|
||||
{
|
||||
if (!Version.TryParse(Program.Version, out Version currentVersion))
|
||||
@ -41,17 +64,13 @@ namespace Ryujinx.Ava.Systems
|
||||
return default;
|
||||
}
|
||||
|
||||
using UpdateClient updateClient = CreateUpdateClient();
|
||||
|
||||
try
|
||||
{
|
||||
_versionResponse = await updateClient.QueryLatestAsync(ReleaseInformation.IsCanaryBuild
|
||||
? ReleaseChannel.Canary
|
||||
: ReleaseChannel.Stable);
|
||||
_versionResponse = await QueryLatestVersionAsync().Then(x => x.Unwrap());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"An error occurred when requesting for updates ({e.GetType().AsFullNamePrettyString()}): {e.Message}");
|
||||
Logger.Error?.Print(LogClass.Application, $"{e.GetType().AsPrettyString()} thrown when requesting updates: {e.Message}");
|
||||
|
||||
_running = false;
|
||||
return default;
|
||||
|
@ -562,7 +562,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool StartGamesWithoutUI
|
||||
public bool StartGamesWithoutUi
|
||||
{
|
||||
get => ConfigurationState.Instance.UI.StartNoUI;
|
||||
set
|
||||
@ -975,8 +975,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
string dialogTitle = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallTitle);
|
||||
string dialogMessage = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallMessage);
|
||||
|
||||
bool alreadyKesyInstalled = ContentManager.AreKeysAlredyPresent(systemDirectory);
|
||||
if (alreadyKesyInstalled)
|
||||
if (ContentManager.AreKeysAlredyPresent(systemDirectory))
|
||||
{
|
||||
dialogMessage += LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallSubMessage);
|
||||
}
|
||||
@ -994,7 +993,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
if (result == UserResult.Yes)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Application, $"Installing Keys");
|
||||
Logger.Info?.Print(LogClass.Application, $"Installing keys from {filename}");
|
||||
|
||||
Thread thread = new(() =>
|
||||
{
|
||||
@ -1206,15 +1205,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
private async Task LoadContentFromFolder(LocaleKeys localeMessageAddedKey, LocaleKeys localeMessageRemovedKey, LoadContentFromFolderDelegate onDirsSelected, LocaleKeys dirSelectDialogTitle)
|
||||
{
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
Optional<IReadOnlyList<IStorageFolder>> result = await StorageProvider.OpenMultiFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[dirSelectDialogTitle],
|
||||
AllowMultiple = true,
|
||||
Title = LocaleManager.Instance[dirSelectDialogTitle]
|
||||
});
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.TryGet(out IReadOnlyList<IStorageFolder> foldersToLoad))
|
||||
{
|
||||
List<string> dirs = result.Select(it => it.Path.LocalPath).ToList();
|
||||
List<string> dirs = foldersToLoad.Select(it => it.Path.LocalPath).ToList();
|
||||
int numAdded = onDirsSelected(dirs, out int numRemoved);
|
||||
|
||||
string msg = string.Join("\n",
|
||||
@ -1270,51 +1268,26 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public void TakeScreenshot()
|
||||
{
|
||||
AppHost.ScreenshotRequested = true;
|
||||
}
|
||||
public void TakeScreenshot() => AppHost.ScreenshotRequested = true;
|
||||
|
||||
public void HideUi()
|
||||
{
|
||||
ShowMenuAndStatusBar = false;
|
||||
}
|
||||
public void HideUi() => ShowMenuAndStatusBar = false;
|
||||
|
||||
public void ToggleStartGamesInFullscreen()
|
||||
{
|
||||
StartGamesInFullscreen = !StartGamesInFullscreen;
|
||||
}
|
||||
public void ToggleStartGamesInFullscreen() => StartGamesInFullscreen = !StartGamesInFullscreen;
|
||||
|
||||
public void ToggleStartGamesWithoutUI()
|
||||
{
|
||||
StartGamesWithoutUI = !StartGamesWithoutUI;
|
||||
}
|
||||
public void ToggleStartGamesWithoutUi() => StartGamesWithoutUi = !StartGamesWithoutUi;
|
||||
|
||||
public void ToggleShowConsole()
|
||||
{
|
||||
ShowConsole = !ShowConsole;
|
||||
}
|
||||
public void ToggleShowConsole() => ShowConsole = !ShowConsole;
|
||||
|
||||
public void SetListMode()
|
||||
{
|
||||
Glyph = Glyph.List;
|
||||
}
|
||||
public void SetListMode() => Glyph = Glyph.List;
|
||||
|
||||
public void SetGridMode()
|
||||
{
|
||||
Glyph = Glyph.Grid;
|
||||
}
|
||||
public void SetGridMode() => Glyph = Glyph.Grid;
|
||||
|
||||
public void SetAspectRatio(AspectRatio aspectRatio)
|
||||
{
|
||||
ConfigurationState.Instance.Graphics.AspectRatio.Value = aspectRatio;
|
||||
}
|
||||
public void SetAspectRatio(AspectRatio aspectRatio) => ConfigurationState.Instance.Graphics.AspectRatio.Value = aspectRatio;
|
||||
|
||||
public async Task InstallFirmwareFromFile()
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
{
|
||||
new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
|
||||
@ -1338,69 +1311,50 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
},
|
||||
});
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.HasValue)
|
||||
{
|
||||
await HandleFirmwareInstallation(result[0].Path.LocalPath);
|
||||
await HandleFirmwareInstallation(result.Value.Path.LocalPath);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InstallFirmwareFromFolder()
|
||||
{
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
});
|
||||
Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync();
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.HasValue)
|
||||
{
|
||||
await HandleFirmwareInstallation(result[0].Path.LocalPath);
|
||||
await HandleFirmwareInstallation(result.Value.Path.LocalPath);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InstallKeysFromFile()
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
{
|
||||
new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
|
||||
{
|
||||
Patterns = ["*.keys", "*.zip"],
|
||||
AppleUniformTypeIdentifiers = ["com.ryujinx.xci", "public.zip-archive"],
|
||||
MimeTypes = ["application/keys", "application/zip"],
|
||||
},
|
||||
new("KEYS")
|
||||
{
|
||||
Patterns = ["*.keys"],
|
||||
AppleUniformTypeIdentifiers = ["com.ryujinx.xci"],
|
||||
MimeTypes = ["application/keys"],
|
||||
},
|
||||
new("ZIP")
|
||||
{
|
||||
Patterns = ["*.zip"],
|
||||
AppleUniformTypeIdentifiers = ["public.zip-archive"],
|
||||
MimeTypes = ["application/zip"],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.HasValue)
|
||||
{
|
||||
await HandleKeysInstallation(result[0].Path.LocalPath);
|
||||
await HandleKeysInstallation(result.Value.Path.LocalPath);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InstallKeysFromFolder()
|
||||
{
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
});
|
||||
Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync();
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.HasValue)
|
||||
{
|
||||
await HandleKeysInstallation(result[0].Path.LocalPath);
|
||||
await HandleKeysInstallation(result.Value.Path.LocalPath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1503,10 +1457,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public async Task OpenFile()
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.LoadApplicationFromFileDialogTitle],
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
{
|
||||
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
|
||||
@ -1562,9 +1515,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
},
|
||||
});
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.HasValue)
|
||||
{
|
||||
if (ApplicationLibrary.TryGetApplicationsFromFile(result[0].Path.LocalPath,
|
||||
if (ApplicationLibrary.TryGetApplicationsFromFile(result.Value.Path.LocalPath,
|
||||
out List<ApplicationData> applications))
|
||||
{
|
||||
await LoadApplication(applications[0]);
|
||||
@ -1596,18 +1549,17 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
public async Task OpenFolder()
|
||||
{
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.LoadUnpackedGameFromFolderDialogTitle],
|
||||
AllowMultiple = false,
|
||||
Title = LocaleManager.Instance[LocaleKeys.LoadUnpackedGameFromFolderDialogTitle]
|
||||
});
|
||||
|
||||
if (result.Count > 0)
|
||||
if (result.TryGet(out IStorageFolder value))
|
||||
{
|
||||
ApplicationData applicationData = new()
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(result[0].Path.LocalPath),
|
||||
Path = result[0].Path.LocalPath,
|
||||
Name = Path.GetFileNameWithoutExtension(value.Path.LocalPath),
|
||||
Path = value.Path.LocalPath,
|
||||
};
|
||||
|
||||
await LoadApplication(applicationData);
|
||||
@ -1812,10 +1764,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
if (AppHost.Device.System.SearchingForAmiibo(out _) && IsGameRunning)
|
||||
{
|
||||
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = new List<FilePickerFileType>
|
||||
{
|
||||
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
|
||||
@ -1824,9 +1775,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
});
|
||||
if (result.Count > 0)
|
||||
|
||||
if (result.HasValue)
|
||||
{
|
||||
AppHost.Device.System.ScanAmiiboFromBin(result[0].Path.LocalPath);
|
||||
AppHost.Device.System.ScanAmiiboFromBin(result.Value.Path.LocalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,14 +92,14 @@
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
Padding="0"
|
||||
Command="{Binding ToggleStartGamesWithoutUI}"
|
||||
Command="{Binding ToggleStartGamesWithoutUi}"
|
||||
Header="{ext:Locale MenuBarOptionsStartGamesWithoutUI}"
|
||||
Classes="withCheckbox">
|
||||
<MenuItem.Icon>
|
||||
<CheckBox
|
||||
MinWidth="{DynamicResource CheckBoxSize}"
|
||||
MinHeight="{DynamicResource CheckBoxSize}"
|
||||
IsChecked="{Binding StartGamesWithoutUI, Mode=TwoWay}"
|
||||
IsChecked="{Binding StartGamesWithoutUi, Mode=TwoWay}"
|
||||
Padding="0" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
Reference in New Issue
Block a user