mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-09-12 22:52:17 -06:00
Compare commits
20 Commits
Canary-1.3
...
Canary-1.3
Author | SHA1 | Date | |
---|---|---|---|
23eb9a3043 | |||
931ec44406 | |||
d68efa98ba | |||
ded76801d1 | |||
6084df7473 | |||
f3953c6039 | |||
91f5247e7f | |||
5658402c6b | |||
1b2c93e188 | |||
9e599ff325 | |||
7a5f430b59 | |||
1e340ce2f3 | |||
dbb4e63e1e | |||
d00ab52fa2 | |||
959af3613d | |||
3309fb2351 | |||
e1e8628a6f | |||
3969191605 | |||
07c7b39053 | |||
053efaa414 |
@ -1,18 +0,0 @@
|
||||
function pub {
|
||||
dotnet publish -c release
|
||||
}
|
||||
|
||||
function package {
|
||||
cd src/$1
|
||||
pub
|
||||
mv bin/Release/$1.1.0.0.nupkg ../../pkgs/$1.1.0.0.nupkg
|
||||
cd ../../
|
||||
}
|
||||
|
||||
rm -rf pkgs
|
||||
mkdir pkgs
|
||||
|
||||
package ARMeilleure
|
||||
package Ryujinx.Memory
|
||||
|
||||
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs
|
40
CHANGELOG.md
40
CHANGELOG.md
@ -21,8 +21,8 @@ Additionally, 1.2.74 & 75 were fixes for uploading Windows build artifacts.
|
||||
|
||||
1.2.76 fixes a rare crash on startup.
|
||||
|
||||
## [1.2.72](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.72>) - 2024-11-03
|
||||
PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://github.com/GreemDev/Ryujinx/pull/164>), [#139](<https://github.com/GreemDev/Ryujinx/pull/139>)
|
||||
## [1.2.72](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.72>) - 2024-11-03
|
||||
PRs [#163](<https://web.archive.org/web/20241123015123/https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://web.archive.org/web/20250307192526/https://github.com/Ryubing/Ryujinx/pull/164>), [#139](<https://web.archive.org/web/20250306123457/https://github.com/Ryubing/Ryujinx/pull/139>)
|
||||
### HLE:
|
||||
- Add DebugMouse HID device.
|
||||
- Fixes "Clock Tower Rewind" crashing while loading.
|
||||
@ -32,7 +32,7 @@ PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://gith
|
||||
### misc:
|
||||
- Update macOS distribution .icns.
|
||||
|
||||
## [1.2.69](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.69>) - 2024-11-01
|
||||
## [1.2.69](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.69>) - 2024-11-01
|
||||
### Infra:
|
||||
- Compile the native libraries into the Ryujinx executable.
|
||||
- Remove `libarmeilleure-jitsupport.dylib` from Windows & Linux releases (dylibs are macOS-only)
|
||||
@ -42,8 +42,8 @@ PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://gith
|
||||
- Replace "" with `string.Empty`.
|
||||
- Code cleanups & simplifications.
|
||||
|
||||
## [1.2.67](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.67>) - 2024-11-01
|
||||
PRs [#36](<https://github.com/GreemDev/Ryujinx/pull/36>), [#135](<https://github.com/GreemDev/Ryujinx/pull/135>)
|
||||
## [1.2.67](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.67>) - 2024-11-01
|
||||
PRs [#36](<https://web.archive.org/web/20250306215917/https://github.com/Ryubing/Ryujinx/pull/36>), [#135](<https://web.archive.org/web/20241122135125/https://github.com/GreemDev/Ryujinx/pull/135>)
|
||||
|
||||
### GUI:
|
||||
- Set UseFloatingWatermark to false when watermark is empty
|
||||
@ -54,8 +54,8 @@ PRs [#36](<https://github.com/GreemDev/Ryujinx/pull/36>), [#135](<https://github
|
||||
- Fix homebrew loading.
|
||||
|
||||
|
||||
## [1.2.64](https://github.com/GreemDev/Ryujinx/releases/tag/1.2.64) - 2024-10-30
|
||||
PRs [#92](https://github.com/GreemDev/Ryujinx/pull/92), [#96](https://github.com/GreemDev/Ryujinx/pull/96), [#97](https://github.com/GreemDev/Ryujinx/pull/97), [#101](https://github.com/GreemDev/Ryujinx/pull/101), [#103](https://github.com/GreemDev/Ryujinx/pull/103)
|
||||
## [1.2.64](https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.64) - 2024-10-30
|
||||
PRs [#92](https://web.archive.org/web/20241118052724/https://github.com/GreemDev/Ryujinx/pull/92), ~~[#96](https://github.com/GreemDev/Ryujinx/pull/96)~~, ~~[#97](https://github.com/GreemDev/Ryujinx/pull/97)~~, [#101](https://web.archive.org/web/20250306223605/https://github.com/Ryubing/Ryujinx/pull/101), ~~[#103](https://github.com/GreemDev/Ryujinx/pull/103)~~
|
||||
### GUI:
|
||||
- Option to show classic-style title bar. Requires restart of emulator to take effect.
|
||||
- This is only relevant on Windows. Other Operating Systems default to this being on and not being changeable, because the custom (current) title bar only works on Windows in the first place.
|
||||
@ -71,14 +71,14 @@ PRs [#92](https://github.com/GreemDev/Ryujinx/pull/92), [#96](https://github.com
|
||||
|
||||
## 1.2.59 - 2024-10-27
|
||||
|
||||
PRs [#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87)
|
||||
PRs ~~[#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87)~~
|
||||
### i18n:
|
||||
- fr_FR:
|
||||
- Add missing translations for new features & fix a couple wrong ones.
|
||||
- Fix Ignore Missing Services / Ignore Applet tooltip.
|
||||
|
||||
## 1.2.57 - 2024-10-27
|
||||
PRs [#60](https://github.com/GreemDev/Ryujinx/pull/60), [#42](https://github.com/GreemDev/Ryujinx/pull/42)
|
||||
PRs ~~[#60](https://github.com/GreemDev/Ryujinx/pull/60)~~, [#42](https://web.archive.org/web/20241126203614/https://github.com/GreemDev/Ryujinx/pull/42)
|
||||
### GUI:
|
||||
- Automatically remove invalid DLC & updates as part of autoload.
|
||||
- Added Thai translation for Ignore Applet hover tooltip.
|
||||
@ -104,7 +104,7 @@ PRs [#60](https://github.com/GreemDev/Ryujinx/pull/60), [#42](https://github.com
|
||||
- Code cleanup.
|
||||
|
||||
## 1.2.44 - 2024-10-25
|
||||
PR [#59](https://github.com/GreemDev/Ryujinx/pull/59)
|
||||
PR [#59](https://web.archive.org/web/20241125060420/https://github.com/GreemDev/Ryujinx/pull/59)
|
||||
### GUI:
|
||||
- Add descriptions for "ignoring applet" translated into other languages.
|
||||
|
||||
@ -117,9 +117,9 @@ NOTE: The translation isn't referenced in the code yet, it will be in the next u
|
||||
## 1.2.42 - 2024-10-24
|
||||
Sources:
|
||||
|
||||
Init function: https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9
|
||||
Init function: [archive of github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9](https://web.archive.org/web/20241122193401/https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9)
|
||||
|
||||
Shader counter: https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357
|
||||
Shader counter: ~~https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357~~ Original commit has been lost
|
||||
|
||||
Thanks MutantAura :D
|
||||
### GUI:
|
||||
@ -127,14 +127,14 @@ Thanks MutantAura :D
|
||||
- Remove graphics backend / GPU name event logic in favor of a single init function.
|
||||
|
||||
## 1.2.41 - 2024-10-24
|
||||
PR [#54](https://github.com/GreemDev/Ryujinx/pull/54)
|
||||
PR ~~[#54](https://github.com/GreemDev/Ryujinx/pull/54)~~
|
||||
|
||||
Thanks Whitescatz!
|
||||
### i18n:
|
||||
- th_TH (Thai): Added missing translations, reduce transliterated words, fix grammar.
|
||||
|
||||
## 1.2.40 - 2024-10-23
|
||||
PR [#40](https://github.com/GreemDev/Ryujinx/pull/40)
|
||||
PR ~~[#40](https://github.com/GreemDev/Ryujinx/pull/40)~~
|
||||
|
||||
Thanks Вова С!
|
||||
### GUI:
|
||||
@ -148,30 +148,30 @@ Thanks Вова С!
|
||||
- Should prevent crashing on config loads in some circumstances.
|
||||
|
||||
## 1.2.38 - 2024-10-23
|
||||
PR [#51](https://github.com/GreemDev/Ryujinx/pull/51)
|
||||
PR [#51](https://web.archive.org/web/20241127022413/https://github.com/GreemDev/Ryujinx/pull/51)
|
||||
### i18n:
|
||||
- zh_CH (Simplified Chinese): Add some missing translations.
|
||||
|
||||
## 1.2.37 - 2024-10-23
|
||||
PR [#37](https://github.com/GreemDev/Ryujinx/pull/37)
|
||||
PR [#37](https://web.archive.org/web/20241123010103/https://github.com/GreemDev/Ryujinx/pull/37)
|
||||
|
||||
Thanks Last Breath!
|
||||
### GUI:
|
||||
- Set the default controller to the Pro Controller.
|
||||
|
||||
## 1.2.36 - 2024-10-21
|
||||
PR [#30](https://github.com/GreemDev/Ryujinx/pull/30)
|
||||
PR ~~[#30](https://github.com/GreemDev/Ryujinx/pull/30)~~
|
||||
### GUI:
|
||||
- Fix repeated dialog popup notifying you of new updates when there aren't any, while having a bundled update inside an XCI and an external update file.
|
||||
|
||||
## 1.2.35 - 2024-10-21
|
||||
PR [#32](https://github.com/GreemDev/Ryujinx/pull/32)
|
||||
PR [#32](https://web.archive.org/web/20241127010942/https://github.com/GreemDev/Ryujinx/pull/32)
|
||||
### GUI:
|
||||
- Replace "expand DRAM" option with a DRAM size dropdown.
|
||||
- Allows for using mods which require a ridiculous amount of memory to allocate from.
|
||||
|
||||
## 1.2.34 - 2024-10-21
|
||||
PR [#29](https://github.com/GreemDev/Ryujinx/pull/29)
|
||||
PR [#29](https://web.archive.org/web/20241125093029/https://github.com/GreemDev/Ryujinx/pull/29)
|
||||
### GUI:
|
||||
- Fix duplicate controller names when 2 controllers of the same type are connected.
|
||||
### INPUT:
|
||||
@ -248,7 +248,7 @@ Added Low-power PPTC mode strings to the translation files.
|
||||
## 1.2.1-1.2.19 - 2024-10-08 - 2024-10-11
|
||||
### GUI/INFRA/MISC:
|
||||
- Remove GTK UI.
|
||||
- Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)).
|
||||
- Autoload DLC/Updates from dir ([#12](https://web.archive.org/web/20241127004005/https://github.com/GreemDev/Ryujinx/pull/12)).
|
||||
- Changed executable icon to rainbow logo.
|
||||
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
|
||||
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.
|
||||
|
@ -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" />
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
|
@ -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,53 +501,13 @@ 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:
|
||||
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);
|
||||
VerifyKeysFile(keysSource);
|
||||
File.Copy(keysSource, Path.Combine(installDirectory, info.Name), true);
|
||||
}
|
||||
else
|
||||
throw new InvalidFirmwarePackageException("Input file is not a valid key package");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -647,6 +650,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()
|
||||
|
@ -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 { }
|
||||
|
@ -52,6 +52,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory
|
||||
/// </summary>
|
||||
[FieldOffset(0x3DC00)]
|
||||
public RingLifo<DebugMouseState> DebugMouse;
|
||||
|
||||
/// <summary>
|
||||
/// Pad Condition.
|
||||
/// </summary>
|
||||
[FieldOffset(0x3e200)]
|
||||
public NpadCondition Condition;
|
||||
|
||||
public static SharedMemory Create()
|
||||
{
|
||||
@ -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();
|
||||
|
@ -20,6 +20,18 @@ namespace Ryujinx.HLE
|
||||
{
|
||||
public class Switch : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently running emulated Switch, if there is one.
|
||||
/// <para>
|
||||
/// Proper usage of this property null checks it before use, unless the caller is certain that the emulation is running.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// In case the emulation is running, there might be a way to directly pass the <see cref="Switch" /> instance, which is preferred.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The instance is set to <c>this</c> on any <see cref="Switch" /> instantiation, and set to <c>null</c> on any <see cref="Switch" /> disposal.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static Switch Shared { get; private set; }
|
||||
|
||||
public HleConfiguration Configuration { get; }
|
||||
|
@ -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]
|
||||
});
|
||||
|
@ -19,7 +19,7 @@ namespace Ryujinx.Ava.Common.Locale
|
||||
private readonly Dictionary<LocaleKeys, string> _localeStrings;
|
||||
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
|
||||
private string _localeLanguageCode;
|
||||
|
||||
public string CurrentLanguageCode => _localeLanguageCode;
|
||||
public static LocaleManager Instance { get; } = new();
|
||||
public event Action LocaleChanged;
|
||||
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -97,8 +97,10 @@ namespace Ryujinx.Ava.Systems.PlayReport
|
||||
//TODO DLC Locations
|
||||
_ => 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,16 +15,38 @@ 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(
|
||||
LogClass.Application,
|
||||
args.Length is 0 ? format : format.Format(args),
|
||||
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)
|
||||
{
|
||||
@ -41,22 +64,18 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
if (_versionResponse == null)
|
||||
{
|
||||
// logging is done via the UpdateClient library
|
||||
|
@ -71,12 +71,12 @@
|
||||
Command="{Binding OpenTitleUpdateManager}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuManageTitleUpdates}"
|
||||
Icon="{ext:Icon fa-solid fa-code-compare}" />
|
||||
Icon="{ext:Icon fa-solid fa-diagram-predecessor}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenDownloadableContentManager}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuManageDlc}"
|
||||
Icon="{ext:Icon fa-solid fa-download}" />
|
||||
Icon="{ext:Icon fa-solid fa-puzzle-piece}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenCheatManager}"
|
||||
CommandParameter="{Binding}"
|
||||
@ -92,12 +92,12 @@
|
||||
Command="{Binding OpenModsDirectory}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuOpenModsDirectory}"
|
||||
Icon="{ext:Icon fa-solid fa-folder}" />
|
||||
Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenSdModsDirectory}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuOpenSdModsDirectory}"
|
||||
Icon="{ext:Icon fa-solid fa-folder}"
|
||||
Icon="{ext:Icon fa-solid fa-folder-closed}"
|
||||
ToolTip.Tip="{ext:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
@ -128,12 +128,12 @@
|
||||
Command="{Binding OpenPtcDirectory}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
|
||||
Icon="{ext:Icon fa-solid fa-folder}" />
|
||||
Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenShaderCacheDirectory}"
|
||||
CommandParameter="{Binding}"
|
||||
Header="{ext:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
|
||||
Icon="{ext:Icon fa-solid fa-folder}" />
|
||||
Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{ext:Locale GameListContextMenuExtractData}" Icon="{ext:Icon fa-solid fa-file-export}">
|
||||
<MenuItem
|
||||
|
@ -2,7 +2,8 @@
|
||||
x:Class="Ryujinx.Ava.RyujinxApp"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:sty="using:FluentAvalonia.Styling">
|
||||
xmlns:sty="using:FluentAvalonia.Styling"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
@ -19,7 +20,7 @@
|
||||
</Application.Styles>
|
||||
<NativeMenu.Menu>
|
||||
<NativeMenu>
|
||||
<NativeMenuItem Header="About Ryujinx" Click="AboutRyujinx_OnClick" />
|
||||
<NativeMenuItem Header="{ext:Locale MenuBarHelpAbout}" Click="AboutRyujinx_OnClick" />
|
||||
</NativeMenu>
|
||||
</NativeMenu.Menu>
|
||||
</Application>
|
||||
|
@ -562,7 +562,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool StartGamesWithoutUI
|
||||
public bool StartGamesWithoutUi
|
||||
{
|
||||
get => ConfigurationState.Instance.UI.StartNoUI;
|
||||
set
|
||||
@ -974,9 +974,8 @@ 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(() =>
|
||||
{
|
||||
@ -1204,17 +1203,16 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
_rendererWaitEvent.Set();
|
||||
}
|
||||
|
||||
private async Task LoadContentFromFolder(LocaleKeys localeMessageAddedKey, LocaleKeys localeMessageRemovedKey, LoadContentFromFolderDelegate onDirsSelected)
|
||||
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[LocaleKeys.OpenFolderDialogTitle],
|
||||
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.OpenFileDialogTitle],
|
||||
AllowMultiple = false,
|
||||
Title = LocaleManager.Instance[LocaleKeys.LoadApplicationFromFileDialogTitle],
|
||||
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]);
|
||||
@ -1581,7 +1534,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
await LoadContentFromFolder(
|
||||
LocaleKeys.AutoloadDlcAddedMessage,
|
||||
LocaleKeys.AutoloadDlcRemovedMessage,
|
||||
ApplicationLibrary.AutoLoadDownloadableContents);
|
||||
ApplicationLibrary.AutoLoadDownloadableContents,
|
||||
LocaleKeys.LoadDLCFromFolderDialogTitle);
|
||||
}
|
||||
|
||||
public async Task LoadTitleUpdatesFromFolder()
|
||||
@ -1589,23 +1543,23 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
await LoadContentFromFolder(
|
||||
LocaleKeys.AutoloadUpdateAddedMessage,
|
||||
LocaleKeys.AutoloadUpdateRemovedMessage,
|
||||
ApplicationLibrary.AutoLoadTitleUpdates);
|
||||
ApplicationLibrary.AutoLoadTitleUpdates,
|
||||
LocaleKeys.LoadTitleUpdatesFromFolderDialogTitle);
|
||||
}
|
||||
|
||||
public async Task OpenFolder()
|
||||
{
|
||||
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.OpenFolderDialogTitle],
|
||||
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);
|
||||
@ -1810,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])
|
||||
@ -1822,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,36 +39,29 @@
|
||||
Header="{ext:Locale MenuBarFileOpenUnpacked}"
|
||||
Icon="{ext:Icon fa-solid fa-folder-open}"
|
||||
IsEnabled="{Binding EnableNonGameRunningControls}" />
|
||||
<MenuItem
|
||||
Command="{Binding LoadDlcFromFolder}"
|
||||
Header="{ext:Locale MenuBarFileLoadDlcFromFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-download}"
|
||||
IsEnabled="{Binding EnableNonGameRunningControls}" />
|
||||
<MenuItem
|
||||
Command="{Binding LoadTitleUpdatesFromFolder}"
|
||||
Header="{ext:Locale MenuBarFileLoadTitleUpdatesFromFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-code-compare}"
|
||||
Icon="{ext:Icon fa-solid fa-diagram-predecessor}"
|
||||
IsEnabled="{Binding EnableNonGameRunningControls}" />
|
||||
<MenuItem
|
||||
Command="{Binding LoadDlcFromFolder}"
|
||||
Header="{ext:Locale MenuBarFileLoadDlcFromFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-puzzle-piece}"
|
||||
IsEnabled="{Binding EnableNonGameRunningControls}" />
|
||||
<MenuItem Header="{ext:Locale MenuBarFileOpenApplet}" IsEnabled="{Binding IsAppletMenuActive}" Icon="{ext:Icon fa-solid fa-microchip}">
|
||||
<MenuItem
|
||||
Name="MiiAppletMenuItem"
|
||||
Header="{ext:Locale MenuBarFileOpenAppletOpenMiiApplet}"
|
||||
Icon="{ext:Icon fa-solid fa-person}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarFileOpenAppletOpenMiiAppletToolTip}" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Command="{Binding OpenRyujinxFolder}"
|
||||
Header="{ext:Locale MenuBarFileOpenEmuFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenScreenshotsFolder}"
|
||||
Header="{ext:Locale MenuBarFileOpenScreenshotsFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-desktop}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenLogsFolder}"
|
||||
Header="{ext:Locale MenuBarFileOpenLogsFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-file-lines}" />
|
||||
Icon="{ext:Icon fa-solid fa-terminal}" />
|
||||
<MenuItem
|
||||
Command="{Binding OpenScreenshotsFolder}"
|
||||
Header="{ext:Locale MenuBarFileOpenScreenshotsFolder}"
|
||||
Icon="{ext:Icon fa-solid fa-image}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Name="CloseRyujinxMenuItem"
|
||||
@ -99,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>
|
||||
@ -132,11 +125,6 @@
|
||||
Icon="{ext:Icon fa-solid fa-globe}"
|
||||
Classes="withCheckbox">
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
Name="ToggleFileTypesMenuItem"
|
||||
Padding="-10,0,0,0"
|
||||
Header="{ext:Locale MenuBarShowFileTypes}" />
|
||||
<Separator />
|
||||
<MenuItem
|
||||
Name="OpenSettingsMenuItem"
|
||||
Padding="0"
|
||||
@ -222,20 +210,25 @@
|
||||
<MenuItem Command="{Binding InstallFirmwareFromFile}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromFile}" Icon="{ext:Icon fa-solid fa-file-code}" />
|
||||
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromDirectory}" Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="{ext:Locale MenuBarActionsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
||||
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
||||
<MenuItem Name="UninstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsUninstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered}" />
|
||||
<MenuItem Header="{ext:Locale MenuBarActionsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}" Icon="{ext:Icon fa-solid fa-clipboard}">
|
||||
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" Icon="{ext:Icon fa-solid fa-square-plus}" />
|
||||
<MenuItem Name="UninstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsUninstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered}" Icon="{ext:Icon fa-solid fa-square-minus}" />
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Name="XciTrimmerMenuItem" Header="{ext:Locale MenuBarActionsXCITrimmer}" Icon="{ext:Icon fa-solid fa-scissors}" />
|
||||
<MenuItem Header="{ext:Locale MenuBarActionsTools}" Icon="{ext:Icon fa-solid fa-toolbox}">
|
||||
<MenuItem
|
||||
Name="MiiAppletMenuItem" Header="{ext:Locale MenuBarActionsOpenMiiEditor}" Icon="{ext:Icon fa-solid fa-face-grin-wide}" ToolTip.Tip="{ext:Locale MenuBarActionsOpenMiiEditorToolTip}" />
|
||||
<MenuItem Name="XciTrimmerMenuItem" Header="{ext:Locale MenuBarActionsXCITrimmer}" Icon="{ext:Icon fa-solid fa-scissors}" />
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarView}">
|
||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}">
|
||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarViewWindow}" Icon="{ext:Icon fa-solid fa-window-restore}">
|
||||
<MenuItem Name="WindowSize720PMenuItem" Header="{ext:Locale MenuBarViewWindow720}" CommandParameter="1280 720" />
|
||||
<MenuItem Name="WindowSize1080PMenuItem" Header="{ext:Locale MenuBarViewWindow1080}" CommandParameter="1920 1080" />
|
||||
<MenuItem Name="WindowSize1440PMenuItem" Header="{ext:Locale MenuBarViewWindow1440}" CommandParameter="2560 1440" />
|
||||
<MenuItem Name="WindowSize2160PMenuItem" Header="{ext:Locale MenuBarViewWindow2160}" CommandParameter="3840 2160" />
|
||||
</MenuItem>
|
||||
<MenuItem Name="ToggleFileTypesMenuItem" Header="{ext:Locale MenuBarShowFileTypes}" Icon="{ext:Icon fa-solid fa-tags}" />
|
||||
</MenuItem>
|
||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelp}">
|
||||
<MenuItem
|
||||
@ -258,12 +251,6 @@
|
||||
IsEnabled="{Binding IsRyuLdnEnabled}"/>
|
||||
<Separator />
|
||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelpFaqAndGuides}" Icon="{ext:Icon fa-solid fa-question}" >
|
||||
<MenuItem
|
||||
Name="FaqMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpFaq}"
|
||||
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||
CommandParameter="{x:Static common:SharedConstants.FaqWikiUrl}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
||||
<MenuItem
|
||||
Name="SetupGuideMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpSetup}"
|
||||
@ -276,6 +263,12 @@
|
||||
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||
CommandParameter="{x:Static common:SharedConstants.MultiplayerWikiUrl}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
||||
<MenuItem
|
||||
Name="FaqMenuItem"
|
||||
Header="{ext:Locale MenuBarHelpFaq}"
|
||||
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||
CommandParameter="{x:Static common:SharedConstants.FaqWikiUrl}"
|
||||
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
@ -61,6 +61,14 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
WindowSize1080PMenuItem.Command =
|
||||
WindowSize1440PMenuItem.Command =
|
||||
WindowSize2160PMenuItem.Command = Commands.Create<string>(ChangeWindowSize);
|
||||
|
||||
LocaleManager.Instance.LocaleChanged += OnLocaleChanged;
|
||||
}
|
||||
|
||||
private void OnLocaleChanged()
|
||||
{
|
||||
ChangeLanguageMenuItem.ItemsSource = GenerateLanguageMenuItems();
|
||||
Menu.Close();
|
||||
}
|
||||
|
||||
private IEnumerable<CheckBox> GenerateToggleFileTypeItems() =>
|
||||
@ -80,6 +88,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
const string LocalePath = "Ryujinx/Assets/Locale.json";
|
||||
|
||||
string languageJson = EmbeddedResources.ReadAllText(LocalePath);
|
||||
string currentLanguageCode = LocaleManager.Instance.CurrentLanguageCode;
|
||||
|
||||
LocalesJson locales = JsonHelper.Deserialize(languageJson, LocalesJsonContext.Default.LocalesJson);
|
||||
|
||||
@ -105,7 +114,7 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||
Padding = new Thickness(15, 0, 0, 0),
|
||||
Margin = new Thickness(3, 0, 3, 0),
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||
Header = languageName,
|
||||
Header = language == currentLanguageCode ? $"{languageName} ✔" : languageName,
|
||||
Command = Commands.Create(() => MainWindowViewModel.ChangeLanguage(language))
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user