Merge branch 'master' into patch-1

This commit is contained in:
Daenorth 2024-12-07 22:22:33 +01:00 committed by GitHub
commit 44f639baf8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
63 changed files with 631 additions and 297 deletions

View File

@ -38,7 +38,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" /> <PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.6.6" /> <PackageVersion Include="Gommon" Version="2.6.8" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />

View File

@ -40,11 +40,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.1</string> <string>1.2</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.1.0</string> <string>1.2.0</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<true/> <true/>
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>

View File

@ -17,7 +17,7 @@ error_handler() {
set the button_pressed to the button returned of the result set the button_pressed to the button returned of the result
if the button_pressed is \"Open Download Page\" then if the button_pressed is \"Open Download Page\" then
open location \"https://ryujinx.org/download\" open location \"https://ryujinx.app/download\"
end if end if
""" """
@ -54,4 +54,4 @@ if [ "$#" -le 3 ]; then
open -a "$INSTALL_DIRECTORY" open -a "$INSTALL_DIRECTORY"
else else
open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}" open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
fi fi

View File

@ -88,7 +88,7 @@ namespace ARMeilleure.Instructions
EmitSetTpidrEl0(context); EmitSetTpidrEl0(context);
return; return;
case 0b11_011_1101_0000_101: case 0b11_011_1101_0000_101:
EmitGetTpidr2El0(context); EmitSetTpidr2El0(context);
return; return;
default: default:
@ -291,5 +291,16 @@ namespace ARMeilleure.Instructions
context.Store(context.Add(nativeContext, Const((ulong)NativeContext.GetTpidrEl0Offset())), value); context.Store(context.Add(nativeContext, Const((ulong)NativeContext.GetTpidrEl0Offset())), value);
} }
private static void EmitSetTpidr2El0(ArmEmitterContext context)
{
OpCodeSystem op = (OpCodeSystem)context.CurrOp;
Operand value = GetIntOrZR(context, op.Rt);
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
context.Store(context.Add(nativeContext, Const((ulong)NativeContext.GetTpidr2El0Offset())), value);
}
} }
} }

View File

@ -1,6 +1,8 @@
namespace Ryujinx.Common.Configuration.Hid.Controller namespace Ryujinx.Common.Configuration.Hid.Controller
{ {
public class JoyconConfigControllerStick<TButton, TStick> where TButton : unmanaged where TStick : unmanaged public class JoyconConfigControllerStick<TButton, TStick>
where TButton : unmanaged
where TStick : unmanaged
{ {
public TStick Joystick { get; set; } public TStick Joystick { get; set; }
public bool InvertStickX { get; set; } public bool InvertStickX { get; set; }

View File

@ -1,5 +1,6 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Applets.Browser; using Ryujinx.HLE.HOS.Applets.Browser;
using Ryujinx.HLE.HOS.Applets.Cabinet;
using Ryujinx.HLE.HOS.Applets.Dummy; using Ryujinx.HLE.HOS.Applets.Dummy;
using Ryujinx.HLE.HOS.Applets.Error; using Ryujinx.HLE.HOS.Applets.Error;
using Ryujinx.HLE.HOS.Services.Am.AppletAE; using Ryujinx.HLE.HOS.Services.Am.AppletAE;
@ -23,14 +24,14 @@ namespace Ryujinx.HLE.HOS.Applets
case AppletId.SoftwareKeyboard: case AppletId.SoftwareKeyboard:
return new SoftwareKeyboardApplet(system); return new SoftwareKeyboardApplet(system);
case AppletId.LibAppletWeb: case AppletId.LibAppletWeb:
return new BrowserApplet(system);
case AppletId.LibAppletShop: case AppletId.LibAppletShop:
return new BrowserApplet(system);
case AppletId.LibAppletOff: case AppletId.LibAppletOff:
return new BrowserApplet(system); return new BrowserApplet();
case AppletId.MiiEdit: case AppletId.MiiEdit:
Logger.Warning?.Print(LogClass.Application, $"Please use the MiiEdit inside File/Open Applet"); Logger.Warning?.Print(LogClass.Application, $"Please use the MiiEdit inside File/Open Applet");
return new DummyApplet(system); return new DummyApplet(system);
case AppletId.Cabinet:
return new CabinetApplet(system);
} }
Logger.Warning?.Print(LogClass.Application, $"Applet {applet} not implemented!"); Logger.Warning?.Print(LogClass.Application, $"Applet {applet} not implemented!");

View File

@ -18,13 +18,6 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
private List<BrowserArgument> _arguments; private List<BrowserArgument> _arguments;
private ShimKind _shimKind; private ShimKind _shimKind;
public BrowserApplet(Horizon system) { }
public ResultCode GetResult()
{
return ResultCode.Success;
}
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession) public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{ {
_normalSession = normalSession; _normalSession = normalSession;

View File

@ -0,0 +1,182 @@
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
using Ryujinx.HLE.HOS.Services.Hid.HidServer;
using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.HLE.HOS.Services.Nfc.Nfp;
using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace Ryujinx.HLE.HOS.Applets.Cabinet
{
internal unsafe class CabinetApplet : IApplet
{
private readonly Horizon _system;
private AppletSession _normalSession;
public event EventHandler AppletStateChanged;
public CabinetApplet(Horizon system)
{
_system = system;
}
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{
_normalSession = normalSession;
byte[] launchParams = _normalSession.Pop();
byte[] startParamBytes = _normalSession.Pop();
StartParamForAmiiboSettings startParam = IApplet.ReadStruct<StartParamForAmiiboSettings>(startParamBytes);
Logger.Stub?.PrintStub(LogClass.ServiceAm, $"CabinetApplet Start Type: {startParam.Type}");
switch (startParam.Type)
{
case 0:
StartNicknameAndOwnerSettings(ref startParam);
break;
case 1:
case 3:
StartFormatter(ref startParam);
break;
default:
Logger.Error?.Print(LogClass.ServiceAm, $"Unknown AmiiboSettings type: {startParam.Type}");
break;
}
// Prepare the response
ReturnValueForAmiiboSettings returnValue = new()
{
AmiiboSettingsReturnFlag = (byte)AmiiboSettingsReturnFlag.HasRegisterInfo,
DeviceHandle = new DeviceHandle
{
Handle = 0 // Dummy device handle
},
RegisterInfo = startParam.RegisterInfo
};
// Push the response
_normalSession.Push(BuildResponse(returnValue));
AppletStateChanged?.Invoke(this, null);
_system.ReturnFocus();
return ResultCode.Success;
}
public ResultCode GetResult()
{
_system.Device.System.NfpDevices.RemoveAt(0);
return ResultCode.Success;
}
private void StartFormatter(ref StartParamForAmiiboSettings startParam)
{
// Initialize RegisterInfo
startParam.RegisterInfo = new RegisterInfo();
}
private void StartNicknameAndOwnerSettings(ref StartParamForAmiiboSettings startParam)
{
_system.Device.UIHandler.DisplayCabinetDialog(out string newName);
byte[] nameBytes = Encoding.UTF8.GetBytes(newName);
Array41<byte> nickName = new Array41<byte>();
nameBytes.CopyTo(nickName.AsSpan());
startParam.RegisterInfo.Nickname = nickName;
NfpDevice devicePlayer1 = new()
{
NpadIdType = NpadIdType.Player1,
Handle = HidUtils.GetIndexFromNpadIdType(NpadIdType.Player1),
State = NfpDeviceState.SearchingForTag,
};
_system.Device.System.NfpDevices.Add(devicePlayer1);
_system.Device.UIHandler.DisplayCabinetMessageDialog();
string amiiboId = string.Empty;
bool scanned = false;
while (!scanned)
{
for (int i = 0; i < _system.Device.System.NfpDevices.Count; i++)
{
if (_system.Device.System.NfpDevices[i].State == NfpDeviceState.TagFound)
{
amiiboId = _system.Device.System.NfpDevices[i].AmiiboId;
scanned = true;
}
}
}
VirtualAmiibo.UpdateNickName(amiiboId, newName);
}
private static byte[] BuildResponse(ReturnValueForAmiiboSettings returnValue)
{
int size = Unsafe.SizeOf<ReturnValueForAmiiboSettings>();
byte[] bytes = new byte[size];
fixed (byte* bytesPtr = bytes)
{
Unsafe.Write(bytesPtr, returnValue);
}
return bytes;
}
#region Structs
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct TagInfo
{
public fixed byte Data[0x58];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct StartParamForAmiiboSettings
{
public byte ZeroValue; // Left at zero by sdknso
public byte Type;
public byte Flags;
public byte AmiiboSettingsStartParamOffset28;
public ulong AmiiboSettingsStartParam0;
public TagInfo TagInfo; // Only enabled when flags bit 1 is set
public RegisterInfo RegisterInfo; // Only enabled when flags bit 2 is set
public fixed byte StartParamExtraData[0x20];
public fixed byte Reserved[0x24];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct ReturnValueForAmiiboSettings
{
public byte AmiiboSettingsReturnFlag;
private byte Padding1;
private byte Padding2;
private byte Padding3;
public DeviceHandle DeviceHandle;
public TagInfo TagInfo;
public RegisterInfo RegisterInfo;
public fixed byte IgnoredBySdknso[0x24];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DeviceHandle
{
public ulong Handle;
}
public enum AmiiboSettingsReturnFlag : byte
{
Cancel = 0,
HasTagInfo = 2,
HasRegisterInfo = 4,
HasTagInfoAndRegisterInfo = 6
}
#endregion
}
}

View File

@ -117,11 +117,6 @@ namespace Ryujinx.HLE.HOS.Applets
return ResultCode.Success; return ResultCode.Success;
} }
public ResultCode GetResult()
{
return ResultCode.Success;
}
private static byte[] BuildResponse(ControllerSupportResultInfo result) private static byte[] BuildResponse(ControllerSupportResultInfo result)
{ {
using MemoryStream stream = MemoryStreamManager.Shared.GetStream(); using MemoryStream stream = MemoryStreamManager.Shared.GetStream();

View File

@ -11,11 +11,14 @@ namespace Ryujinx.HLE.HOS.Applets.Dummy
{ {
private readonly Horizon _system; private readonly Horizon _system;
private AppletSession _normalSession; private AppletSession _normalSession;
public event EventHandler AppletStateChanged; public event EventHandler AppletStateChanged;
public DummyApplet(Horizon system) public DummyApplet(Horizon system)
{ {
_system = system; _system = system;
} }
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession) public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{ {
_normalSession = normalSession; _normalSession = normalSession;
@ -24,10 +27,7 @@ namespace Ryujinx.HLE.HOS.Applets.Dummy
_system.ReturnFocus(); _system.ReturnFocus();
return ResultCode.Success; return ResultCode.Success;
} }
private static T ReadStruct<T>(byte[] data) where T : struct
{
return MemoryMarshal.Read<T>(data.AsSpan());
}
private static byte[] BuildResponse() private static byte[] BuildResponse()
{ {
using MemoryStream stream = MemoryStreamManager.Shared.GetStream(); using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
@ -35,9 +35,5 @@ namespace Ryujinx.HLE.HOS.Applets.Dummy
writer.Write((ulong)ResultCode.Success); writer.Write((ulong)ResultCode.Success);
return stream.ToArray(); return stream.ToArray();
} }
public ResultCode GetResult()
{
return ResultCode.Success;
}
} }
} }

View File

@ -203,10 +203,5 @@ namespace Ryujinx.HLE.HOS.Applets.Error
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber} (Details)", "\n" + detailsText, buttons.ToArray()); _horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber} (Details)", "\n" + detailsText, buttons.ToArray());
} }
} }
public ResultCode GetResult()
{
return ResultCode.Success;
}
} }
} }

View File

@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Applets
ResultCode Start(AppletSession normalSession, ResultCode Start(AppletSession normalSession,
AppletSession interactiveSession); AppletSession interactiveSession);
ResultCode GetResult(); ResultCode GetResult() => ResultCode.Success;
bool DrawTo(RenderingSurfaceInfo surfaceInfo, IVirtualMemoryManager destination, ulong position) => false; bool DrawTo(RenderingSurfaceInfo surfaceInfo, IVirtualMemoryManager destination, ulong position) => false;

View File

@ -37,11 +37,6 @@ namespace Ryujinx.HLE.HOS.Applets
return ResultCode.Success; return ResultCode.Success;
} }
public ResultCode GetResult()
{
return ResultCode.Success;
}
private byte[] BuildResponse() private byte[] BuildResponse()
{ {
UserProfile currentUser = _system.AccountManager.LastOpenedUser; UserProfile currentUser = _system.AccountManager.LastOpenedUser;

View File

@ -144,11 +144,6 @@ namespace Ryujinx.HLE.HOS.Applets
} }
} }
public ResultCode GetResult()
{
return ResultCode.Success;
}
private bool IsKeyboardActive() private bool IsKeyboardActive()
{ {
return _backgroundState >= InlineKeyboardState.Appearing && _backgroundState < InlineKeyboardState.Disappearing; return _backgroundState >= InlineKeyboardState.Appearing && _backgroundState < InlineKeyboardState.Disappearing;

View File

@ -2,7 +2,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{ {
/// <summary> /// <summary>
/// Wraps a type in a class so it gets stored in the GC managed heap. This is used as communication mechanism /// Wraps a type in a class so it gets stored in the GC managed heap. This is used as communication mechanism
/// between classed that need to be disposed and, thus, can't share their references. /// between classes that need to be disposed and, thus, can't share their references.
/// </summary> /// </summary>
/// <typeparam name="T">The internal type.</typeparam> /// <typeparam name="T">The internal type.</typeparam>
class TRef<T> class TRef<T>

View File

@ -24,6 +24,15 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
return ResultCode.Success; return ResultCode.Success;
} }
[CommandCmif(776)]
// DestroyGroup()
public ResultCode DestroyGroup(ServiceCtx context)
{
Logger.Stub?.PrintStub(LogClass.ServiceLdn);
return ResultCode.Success;
}
[CommandCmif(1536)] [CommandCmif(1536)]
// SendToOtherGroup(nn::lp2p::MacAddress, nn::lp2p::GroupId, s16, s16, u32, buffer<unknown, 0x21>) // SendToOtherGroup(nn::lp2p::MacAddress, nn::lp2p::GroupId, s16, s16, u32, buffer<unknown, 0x21>)
public ResultCode SendToOtherGroup(ServiceCtx context) public ResultCode SendToOtherGroup(ServiceCtx context)

View File

@ -1,3 +1,5 @@
using Gommon;
using Humanizer;
using NetCoreServer; using NetCoreServer;
using Open.Nat; using Open.Nat;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
@ -153,7 +155,10 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy
if (_publicPort != 0) if (_publicPort != 0)
{ {
_ = Task.Delay(PortLeaseRenew * 1000, _disposedCancellation.Token).ContinueWith((task) => Task.Run(RefreshLease)); _ = Executor.ExecuteAfterDelayAsync(
PortLeaseRenew.Seconds(),
_disposedCancellation.Token,
RefreshLease);
} }
_natDevice = device; _natDevice = device;
@ -257,7 +262,10 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy
} }
_ = Task.Delay(PortLeaseRenew, _disposedCancellation.Token).ContinueWith((task) => Task.Run(RefreshLease)); _ = Executor.ExecuteAfterDelayAsync(
PortLeaseRenew.Milliseconds(),
_disposedCancellation.Token,
RefreshLease);
} }
public bool TryRegisterUser(P2pProxySession session, ExternalProxyConfig config) public bool TryRegisterUser(P2pProxySession session, ExternalProxyConfig config)

View File

@ -93,6 +93,13 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
return registerInfo; return registerInfo;
} }
public static void UpdateNickName(string amiiboId, string newNickName)
{
VirtualAmiiboFile virtualAmiiboFile = LoadAmiiboFile(amiiboId);
virtualAmiiboFile.NickName = newNickName;
SaveAmiiboFile(virtualAmiiboFile);
}
public static bool OpenApplicationArea(string amiiboId, uint applicationAreaId) public static bool OpenApplicationArea(string amiiboId, uint applicationAreaId)
{ {
VirtualAmiiboFile virtualAmiiboFile = LoadAmiiboFile(amiiboId); VirtualAmiiboFile virtualAmiiboFile = LoadAmiiboFile(amiiboId);

View File

@ -26,7 +26,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
{ {
private static readonly TitleUpdateMetadataJsonSerializerContext _applicationSerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly TitleUpdateMetadataJsonSerializerContext _applicationSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public static ProcessResult Load(this Nca nca, Switch device, Nca patchNca, Nca controlNca) public static ProcessResult Load(this Nca nca, Switch device, Nca patchNca, Nca controlNca, BlitStruct<ApplicationControlProperty>? customNacpData = null)
{ {
// Extract RomFs and ExeFs from NCA. // Extract RomFs and ExeFs from NCA.
IStorage romFs = nca.GetRomFs(device, patchNca); IStorage romFs = nca.GetRomFs(device, patchNca);
@ -55,6 +55,10 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
{ {
nacpData = controlNca.GetNacp(device); nacpData = controlNca.GetNacp(device);
} }
else if (customNacpData != null) // if the Application doesn't provide a nacp file but the Application provides an override, use the provided nacp override
{
nacpData = (BlitStruct<ApplicationControlProperty>)customNacpData;
}
/* TODO: Rework this since it's wrong and doesn't work as it takes the DisplayVersion from a "potential" non-existent update. /* TODO: Rework this since it's wrong and doesn't work as it takes the DisplayVersion from a "potential" non-existent update.

View File

@ -98,12 +98,12 @@ namespace Ryujinx.HLE.Loaders.Processes
return false; return false;
} }
public bool LoadNca(string path) public bool LoadNca(string path, BlitStruct<ApplicationControlProperty>? customNacpData = null)
{ {
FileStream file = new(path, FileMode.Open, FileAccess.Read); FileStream file = new(path, FileMode.Open, FileAccess.Read);
Nca nca = new(_device.Configuration.VirtualFileSystem.KeySet, file.AsStorage(false)); Nca nca = new(_device.Configuration.VirtualFileSystem.KeySet, file.AsStorage(false));
ProcessResult processResult = nca.Load(_device, null, null); ProcessResult processResult = nca.Load(_device, null, null, customNacpData);
if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult)) if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult))
{ {

View File

@ -84,12 +84,19 @@ namespace Ryujinx.HLE.Loaders.Processes
return false; return false;
} }
bool isFirmware = ProgramId is >= 0x0100000000000819 and <= 0x010000000000081C;
bool isFirmwareApplication = ProgramId <= 0x0100000000007FFF;
string name = !isFirmware
? (isFirmwareApplication ? "Firmware Application " : "") + (!string.IsNullOrWhiteSpace(Name) ? Name : "<Unknown Name>")
: "Firmware";
// TODO: LibHac npdm currently doesn't support version field. // TODO: LibHac npdm currently doesn't support version field.
string version = ProgramId > 0x0100000000007FFF string version = !isFirmware
? DisplayVersion ? (!string.IsNullOrWhiteSpace(DisplayVersion) ? DisplayVersion : "<Unknown Version>")
: device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? "?"; : device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? "?";
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {Name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]"); Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]");
return true; return true;
} }

View File

@ -0,0 +1,37 @@
using LibHac.Common;
using LibHac.Ns;
using System;
using System.Text;
namespace Ryujinx.HLE
{
public static class StructHelpers
{
public static BlitStruct<ApplicationControlProperty> CreateCustomNacpData(string name, string version)
{
// https://switchbrew.org/wiki/NACP
const int OffsetOfDisplayVersion = 0x3060;
// https://switchbrew.org/wiki/NACP#ApplicationTitle
const int TotalApplicationTitles = 0x10;
const int SizeOfApplicationTitle = 0x300;
const int OffsetOfApplicationPublisherStrings = 0x200;
var nacpData = new BlitStruct<ApplicationControlProperty>(1);
// name and publisher buffer
// repeat once for each locale (the ApplicationControlProperty has 16 locales)
for (int i = 0; i < TotalApplicationTitles; i++)
{
Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(nacpData.ByteSpan[(i * SizeOfApplicationTitle)..]);
"Ryujinx"u8.CopyTo(nacpData.ByteSpan[(i * SizeOfApplicationTitle + OffsetOfApplicationPublisherStrings)..]);
}
// version buffer
Encoding.ASCII.GetBytes(version).AsSpan().CopyTo(nacpData.ByteSpan[OffsetOfDisplayVersion..]);
return nacpData;
}
}
}

View File

@ -1,3 +1,5 @@
using LibHac.Common;
using LibHac.Ns;
using Ryujinx.Audio.Backends.CompatLayer; using Ryujinx.Audio.Backends.CompatLayer;
using Ryujinx.Audio.Integration; using Ryujinx.Audio.Integration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
@ -111,7 +113,7 @@ namespace Ryujinx.HLE
public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile); public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile);
public bool LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId); public bool LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId);
public bool LoadNca(string ncaFile) => Processes.LoadNca(ncaFile); public bool LoadNca(string ncaFile, BlitStruct<ApplicationControlProperty>? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData);
public bool LoadNsp(string nspFile, ulong applicationId = 0) => Processes.LoadNsp(nspFile, applicationId); public bool LoadNsp(string nspFile, ulong applicationId = 0) => Processes.LoadNsp(nspFile, applicationId);
public bool LoadProgram(string fileName) => Processes.LoadNxo(fileName); public bool LoadProgram(string fileName) => Processes.LoadNxo(fileName);

View File

@ -24,6 +24,18 @@ namespace Ryujinx.HLE.UI
/// <returns>True when OK is pressed, False otherwise.</returns> /// <returns>True when OK is pressed, False otherwise.</returns>
bool DisplayMessageDialog(ControllerAppletUIArgs args); bool DisplayMessageDialog(ControllerAppletUIArgs args);
/// <summary>
/// Displays an Input Dialog box to the user so they can enter the Amiibo's new name
/// </summary>
/// <param name="userText">Text that the user entered. Set to `null` on internal errors</param>
/// <returns>True when OK is pressed, False otherwise. Also returns True on internal errors</returns>
bool DisplayCabinetDialog(out string userText);
/// <summary>
/// Displays a Message Dialog box to the user to notify them to scan the Amiibo.
/// </summary>
void DisplayCabinetMessageDialog();
/// <summary> /// <summary>
/// Tell the UI that we need to transition to another program. /// Tell the UI that we need to transition to another program.
/// </summary> /// </summary>

View File

@ -1,4 +1,5 @@
using CommandLine; using CommandLine;
using Gommon;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Common; using Ryujinx.Common;
@ -96,8 +97,13 @@ namespace Ryujinx.Headless.SDL2
} }
Parser.Default.ParseArguments<Options>(args) Parser.Default.ParseArguments<Options>(args)
.WithParsed(Load) .WithParsed(Load)
.WithNotParsed(errors => errors.Output()); .WithNotParsed(errors =>
{
Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:");
errors.ForEach(err => Logger.Error?.PrintMsg(LogClass.Application, $" - {err.Tag}"));
});
} }
private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
@ -579,8 +585,8 @@ namespace Ryujinx.Headless.SDL2
options.MultiplayerLanInterfaceId, options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled, Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
false, false,
"", string.Empty,
"", string.Empty,
options.CustomVSyncInterval); options.CustomVSyncInterval);
return new Switch(configuration); return new Switch(configuration);

View File

@ -1,4 +1,5 @@
using Humanizer; using Humanizer;
using LibHac.Tools.Fs;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
@ -485,6 +486,19 @@ namespace Ryujinx.Headless.SDL2
return true; return true;
} }
public bool DisplayCabinetDialog(out string userText)
{
// SDL2 doesn't support input dialogs
userText = "Ryujinx";
return true;
}
public void DisplayCabinetMessageDialog()
{
SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_INFORMATION, "Cabinet Dialog", "Please scan your Amiibo now.", WindowHandle);
}
public bool DisplayMessageDialog(ControllerAppletUIArgs args) public bool DisplayMessageDialog(ControllerAppletUIArgs args)
{ {
if (_ignoreControllerApplet) return false; if (_ignoreControllerApplet) return false;

View File

@ -1,5 +1,4 @@
using DynamicData; using DynamicData;
using DynamicData.Kernel;
using Gommon; using Gommon;
using LibHac; using LibHac;
using LibHac.Common; using LibHac.Common;
@ -37,14 +36,13 @@ using System.Threading.Tasks;
using ContentType = LibHac.Ncm.ContentType; using ContentType = LibHac.Ncm.ContentType;
using MissingKeyException = LibHac.Common.Keys.MissingKeyException; using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
using Path = System.IO.Path; using Path = System.IO.Path;
using SpanHelpers = LibHac.Common.SpanHelpers;
using TimeSpan = System.TimeSpan; using TimeSpan = System.TimeSpan;
namespace Ryujinx.UI.App.Common namespace Ryujinx.UI.App.Common
{ {
public class ApplicationLibrary public class ApplicationLibrary
{ {
public static string DefaultLanPlayWebHost = "ryuldnweb.vudjun.com"; public const string DefaultLanPlayWebHost = "ryuldnweb.vudjun.com";
public Language DesiredLanguage { get; set; } public Language DesiredLanguage { get; set; }
public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated; public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated;
public event EventHandler<LdnGameDataReceivedEventArgs> LdnGameDataReceived; public event EventHandler<LdnGameDataReceivedEventArgs> LdnGameDataReceived;
@ -191,12 +189,9 @@ namespace Ryujinx.UI.App.Common
} }
} }
if (isExeFs) return isExeFs
{ ? GetApplicationFromExeFs(pfs, filePath)
return GetApplicationFromExeFs(pfs, filePath); : null;
}
return null;
} }
/// <exception cref="LibHac.Common.Keys.MissingKeyException">The configured key set is missing a key.</exception> /// <exception cref="LibHac.Common.Keys.MissingKeyException">The configured key set is missing a key.</exception>
@ -512,10 +507,6 @@ namespace Ryujinx.UI.App.Common
case ".xci": case ".xci":
case ".nsp": case ".nsp":
{ {
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
using IFileSystem pfs = PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem); using IFileSystem pfs = PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca")) foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
@ -604,7 +595,7 @@ namespace Ryujinx.UI.App.Common
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None) controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None)
.OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read) .OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read)
.ThrowIfFailure(); .ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), nacpFile.Get.Read(out _, 0, LibHac.Common.SpanHelpers.AsByteSpan(ref controlData),
ReadOption.None).ThrowIfFailure(); ReadOption.None).ThrowIfFailure();
var displayVersion = controlData.DisplayVersionString.ToString(); var displayVersion = controlData.DisplayVersionString.ToString();
@ -827,7 +818,7 @@ namespace Ryujinx.UI.App.Common
{ {
_downloadableContents.Edit(it => _downloadableContents.Edit(it =>
{ {
DownloadableContentsHelper.SaveDownloadableContentsJson(_virtualFileSystem, application.IdBase, dlcs); DownloadableContentsHelper.SaveDownloadableContentsJson(application.IdBase, dlcs);
it.Remove(it.Items.Where(item => item.Dlc.TitleIdBase == application.IdBase)); it.Remove(it.Items.Where(item => item.Dlc.TitleIdBase == application.IdBase));
it.AddOrUpdate(dlcs); it.AddOrUpdate(dlcs);
@ -839,7 +830,7 @@ namespace Ryujinx.UI.App.Common
{ {
_titleUpdates.Edit(it => _titleUpdates.Edit(it =>
{ {
TitleUpdatesHelper.SaveTitleUpdatesJson(_virtualFileSystem, application.IdBase, updates); TitleUpdatesHelper.SaveTitleUpdatesJson(application.IdBase, updates);
it.Remove(it.Items.Where(item => item.TitleUpdate.TitleIdBase == application.IdBase)); it.Remove(it.Items.Where(item => item.TitleUpdate.TitleIdBase == application.IdBase));
it.AddOrUpdate(updates); it.AddOrUpdate(updates);
@ -1088,14 +1079,15 @@ namespace Ryujinx.UI.App.Common
private bool AddAndAutoSelectUpdate(TitleUpdateModel update) private bool AddAndAutoSelectUpdate(TitleUpdateModel update)
{ {
var currentlySelected = TitleUpdates.Items.FirstOrOptional(it => if (update == null) return false;
var currentlySelected = TitleUpdates.Items.FindFirst(it =>
it.TitleUpdate.TitleIdBase == update.TitleIdBase && it.IsSelected); it.TitleUpdate.TitleIdBase == update.TitleIdBase && it.IsSelected);
var shouldSelect = !currentlySelected.HasValue || var shouldSelect = currentlySelected.Check(curr => curr.TitleUpdate?.Version < update.Version);
currentlySelected.Value.TitleUpdate.Version < update.Version;
_titleUpdates.AddOrUpdate((update, shouldSelect)); _titleUpdates.AddOrUpdate((update, shouldSelect));
if (currentlySelected.HasValue && shouldSelect) if (currentlySelected.HasValue && shouldSelect)
{ {
_titleUpdates.AddOrUpdate((currentlySelected.Value.TitleUpdate, false)); _titleUpdates.AddOrUpdate((currentlySelected.Value.TitleUpdate, false));
@ -1464,7 +1456,7 @@ namespace Ryujinx.UI.App.Common
if (addedNewDlc) if (addedNewDlc)
{ {
var gameDlcs = it.Items.Where(dlc => dlc.Dlc.TitleIdBase == application.IdBase).ToList(); var gameDlcs = it.Items.Where(dlc => dlc.Dlc.TitleIdBase == application.IdBase).ToList();
DownloadableContentsHelper.SaveDownloadableContentsJson(_virtualFileSystem, application.IdBase, DownloadableContentsHelper.SaveDownloadableContentsJson(application.IdBase,
gameDlcs); gameDlcs);
} }
} }
@ -1483,11 +1475,11 @@ namespace Ryujinx.UI.App.Common
TitleUpdatesHelper.LoadTitleUpdatesJson(_virtualFileSystem, application.IdBase); TitleUpdatesHelper.LoadTitleUpdatesJson(_virtualFileSystem, application.IdBase);
it.AddOrUpdate(savedUpdates); it.AddOrUpdate(savedUpdates);
var selectedUpdate = savedUpdates.FirstOrOptional(update => update.IsSelected); var selectedUpdate = savedUpdates.FindFirst(update => update.IsSelected);
if (TryGetTitleUpdatesFromFile(application.Path, out var bundledUpdates)) if (TryGetTitleUpdatesFromFile(application.Path, out var bundledUpdates))
{ {
var savedUpdateLookup = savedUpdates.Select(update => update.Item1).ToHashSet(); var savedUpdateLookup = savedUpdates.Select(update => update.Update).ToHashSet();
bool updatesChanged = false; bool updatesChanged = false;
foreach (var update in bundledUpdates.OrderByDescending(bundled => bundled.Version)) foreach (var update in bundledUpdates.OrderByDescending(bundled => bundled.Version))
@ -1495,12 +1487,11 @@ namespace Ryujinx.UI.App.Common
if (!savedUpdateLookup.Contains(update)) if (!savedUpdateLookup.Contains(update))
{ {
bool shouldSelect = false; bool shouldSelect = false;
if (!selectedUpdate.HasValue || selectedUpdate.Value.Item1.Version < update.Version) if (selectedUpdate.Check(su => su.Update?.Version < update.Version))
{ {
shouldSelect = true; shouldSelect = true;
if (selectedUpdate.HasValue) _titleUpdates.AddOrUpdate((selectedUpdate.Value.Update, false));
_titleUpdates.AddOrUpdate((selectedUpdate.Value.Item1, false)); selectedUpdate = (update, true);
selectedUpdate = DynamicData.Kernel.Optional<(TitleUpdateModel, bool IsSelected)>.Create((update, true));
} }
modifiedVersion = modifiedVersion || shouldSelect; modifiedVersion = modifiedVersion || shouldSelect;
@ -1513,7 +1504,7 @@ namespace Ryujinx.UI.App.Common
if (updatesChanged) if (updatesChanged)
{ {
var gameUpdates = it.Items.Where(update => update.TitleUpdate.TitleIdBase == application.IdBase).ToList(); var gameUpdates = it.Items.Where(update => update.TitleUpdate.TitleIdBase == application.IdBase).ToList();
TitleUpdatesHelper.SaveTitleUpdatesJson(_virtualFileSystem, application.IdBase, gameUpdates); TitleUpdatesHelper.SaveTitleUpdatesJson(application.IdBase, gameUpdates);
} }
} }
}); });
@ -1525,14 +1516,14 @@ namespace Ryujinx.UI.App.Common
private void SaveDownloadableContentsForGame(ulong titleIdBase) private void SaveDownloadableContentsForGame(ulong titleIdBase)
{ {
var dlcs = DownloadableContents.Items.Where(dlc => dlc.Dlc.TitleIdBase == titleIdBase).ToList(); var dlcs = DownloadableContents.Items.Where(dlc => dlc.Dlc.TitleIdBase == titleIdBase).ToList();
DownloadableContentsHelper.SaveDownloadableContentsJson(_virtualFileSystem, titleIdBase, dlcs); DownloadableContentsHelper.SaveDownloadableContentsJson(titleIdBase, dlcs);
} }
// Save the _currently tracked_ update state for the game // Save the _currently tracked_ update state for the game
private void SaveTitleUpdatesForGame(ulong titleIdBase) private void SaveTitleUpdatesForGame(ulong titleIdBase)
{ {
var updates = TitleUpdates.Items.Where(update => update.TitleUpdate.TitleIdBase == titleIdBase).ToList(); var updates = TitleUpdates.Items.Where(update => update.TitleUpdate.TitleIdBase == titleIdBase).ToList();
TitleUpdatesHelper.SaveTitleUpdatesJson(_virtualFileSystem, titleIdBase, updates); TitleUpdatesHelper.SaveTitleUpdatesJson(titleIdBase, updates);
} }
// ApplicationData isnt live-updating (e.g. when an update gets applied) and so this is meant to trigger a refresh // ApplicationData isnt live-updating (e.g. when an update gets applied) and so this is meant to trigger a refresh

View File

@ -1,16 +1,12 @@
using ARMeilleure;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System; using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Configuration.UI; using Ryujinx.UI.Common.Configuration.UI;
using System; using System;
using System.Collections.Generic;
namespace Ryujinx.UI.Common.Configuration namespace Ryujinx.UI.Common.Configuration
{ {
@ -21,10 +17,10 @@ namespace Ryujinx.UI.Common.Configuration
if (Instance != null) if (Instance != null)
{ {
throw new InvalidOperationException("Configuration is already initialized"); throw new InvalidOperationException("Configuration is already initialized");
} }
Instance = new ConfigurationState(); Instance = new ConfigurationState();
} }
public ConfigurationFileFormat ToFileFormat() public ConfigurationFileFormat ToFileFormat()
{ {

View File

@ -7,6 +7,24 @@ namespace Ryujinx.UI.Common.Helper
{ {
public static partial class ConsoleHelper public static partial class ConsoleHelper
{ {
[SupportedOSPlatform("windows")]
[LibraryImport("kernel32")]
private static partial nint GetConsoleWindow();
[SupportedOSPlatform("windows")]
[LibraryImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool ShowWindow(nint hWnd, int nCmdShow);
[SupportedOSPlatform("windows")]
[LibraryImport("user32")]
private static partial nint GetForegroundWindow();
[SupportedOSPlatform("windows")]
[LibraryImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool SetForegroundWindow(nint hWnd);
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows(); public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
public static void SetConsoleWindowState(bool show) public static void SetConsoleWindowState(bool show)
@ -35,16 +53,11 @@ namespace Ryujinx.UI.Common.Helper
return; return;
} }
SetForegroundWindow(hWnd);
hWnd = GetForegroundWindow();
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
} }
[SupportedOSPlatform("windows")]
[LibraryImport("kernel32")]
private static partial nint GetConsoleWindow();
[SupportedOSPlatform("windows")]
[LibraryImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool ShowWindow(nint hWnd, int nCmdShow);
} }
} }

View File

@ -42,7 +42,7 @@ namespace Ryujinx.UI.Common.Helper
} }
} }
public static void SaveDownloadableContentsJson(VirtualFileSystem vfs, ulong applicationIdBase, List<(DownloadableContentModel, bool IsEnabled)> dlcs) public static void SaveDownloadableContentsJson(ulong applicationIdBase, List<(DownloadableContentModel, bool IsEnabled)> dlcs)
{ {
DownloadableContentContainer container = default; DownloadableContentContainer container = default;
List<DownloadableContentContainer> downloadableContentContainerList = new(); List<DownloadableContentContainer> downloadableContentContainerList = new();

View File

@ -28,7 +28,7 @@ namespace Ryujinx.UI.Common.Helper
{ {
private static readonly TitleUpdateMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly TitleUpdateMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public static List<(TitleUpdateModel, bool IsSelected)> LoadTitleUpdatesJson(VirtualFileSystem vfs, ulong applicationIdBase) public static List<(TitleUpdateModel Update, bool IsSelected)> LoadTitleUpdatesJson(VirtualFileSystem vfs, ulong applicationIdBase)
{ {
var titleUpdatesJsonPath = PathToGameUpdatesJson(applicationIdBase); var titleUpdatesJsonPath = PathToGameUpdatesJson(applicationIdBase);
@ -49,7 +49,7 @@ namespace Ryujinx.UI.Common.Helper
} }
} }
public static void SaveTitleUpdatesJson(VirtualFileSystem vfs, ulong applicationIdBase, List<(TitleUpdateModel, bool IsSelected)> updates) public static void SaveTitleUpdatesJson(ulong applicationIdBase, List<(TitleUpdateModel, bool IsSelected)> updates)
{ {
var titleUpdateWindowData = new TitleUpdateMetadata var titleUpdateWindowData = new TitleUpdateMetadata
{ {
@ -77,7 +77,7 @@ namespace Ryujinx.UI.Common.Helper
JsonHelper.SerializeToFile(titleUpdatesJsonPath, titleUpdateWindowData, _serializerContext.TitleUpdateMetadata); JsonHelper.SerializeToFile(titleUpdatesJsonPath, titleUpdateWindowData, _serializerContext.TitleUpdateMetadata);
} }
private static List<(TitleUpdateModel, bool IsSelected)> LoadTitleUpdates(VirtualFileSystem vfs, TitleUpdateMetadata titleUpdateMetadata, ulong applicationIdBase) private static List<(TitleUpdateModel Update, bool IsSelected)> LoadTitleUpdates(VirtualFileSystem vfs, TitleUpdateMetadata titleUpdateMetadata, ulong applicationIdBase)
{ {
var result = new List<(TitleUpdateModel, bool IsSelected)>(); var result = new List<(TitleUpdateModel, bool IsSelected)>();

View File

@ -11,7 +11,7 @@
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>
<Application.Styles> <Application.Styles>
<sty:FluentAvaloniaTheme PreferSystemTheme="False" /> <sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
<StyleInclude Source="/Assets/Styles/Styles.xaml" /> <StyleInclude Source="/Assets/Styles/Styles.xaml" />
</Application.Styles> </Application.Styles>
</Application> </Application>

View File

@ -3,6 +3,8 @@ using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Threading; using Avalonia.Threading;
using LibHac.Common;
using LibHac.Ns;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.Dummy; using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.OpenAL;
@ -670,7 +672,7 @@ namespace Ryujinx.Ava
_cursorState = CursorStates.ForceChangeCursor; _cursorState = CursorStates.ForceChangeCursor;
} }
public async Task<bool> LoadGuestApplication() public async Task<bool> LoadGuestApplication(BlitStruct<ApplicationControlProperty>? customNacpData = null)
{ {
InitializeSwitchInstance(); InitializeSwitchInstance();
MainWindow.UpdateGraphicsConfig(); MainWindow.UpdateGraphicsConfig();
@ -740,7 +742,7 @@ namespace Ryujinx.Ava
{ {
Logger.Info?.Print(LogClass.Application, "Loading as Firmware Title (NCA)."); Logger.Info?.Print(LogClass.Application, "Loading as Firmware Title (NCA).");
if (!Device.LoadNca(ApplicationPath)) if (!Device.LoadNca(ApplicationPath, customNacpData))
{ {
Device.Dispose(); Device.Dispose();
@ -1137,7 +1139,7 @@ namespace Ryujinx.Ava
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%", LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
dockedMode, dockedMode,
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
LocaleManager.Instance[LocaleKeys.Game] + $": {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)",
$"FIFO: {Device.Statistics.GetFifoPercent():00.00} %", $"FIFO: {Device.Statistics.GetFifoPercent():00.00} %",
_displayCount)); _displayCount));
} }

View File

@ -702,6 +702,9 @@
"Never": "مطلقا", "Never": "مطلقا",
"SwkbdMinCharacters": "يجب أن يبلغ طوله {0} حرفا على الأقل", "SwkbdMinCharacters": "يجب أن يبلغ طوله {0} حرفا على الأقل",
"SwkbdMinRangeCharacters": "يجب أن يتكون من {0}-{1} حرفا", "SwkbdMinRangeCharacters": "يجب أن يتكون من {0}-{1} حرفا",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "لوحة المفاتيح البرمجية", "SoftwareKeyboard": "لوحة المفاتيح البرمجية",
"SoftwareKeyboardModeNumeric": "يجب أن يكون 0-9 أو '.' فقط", "SoftwareKeyboardModeNumeric": "يجب أن يكون 0-9 أو '.' فقط",
"SoftwareKeyboardModeAlphabet": "يجب أن تكون الأحرف غير CJK فقط", "SoftwareKeyboardModeAlphabet": "يجب أن تكون الأحرف غير CJK فقط",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "إضافة ملفات جديدة...", "UpdaterAddingFiles": "إضافة ملفات جديدة...",
"UpdaterExtracting": "استخراج التحديث...", "UpdaterExtracting": "استخراج التحديث...",
"UpdaterDownloading": "تحميل التحديث...", "UpdaterDownloading": "تحميل التحديث...",
"Game": "لعبة",
"Docked": "تركيب بالمنصة", "Docked": "تركيب بالمنصة",
"Handheld": "محمول", "Handheld": "محمول",
"ConnectionError": "خطأ في الاتصال", "ConnectionError": "خطأ في الاتصال",
@ -786,7 +788,7 @@
"CheatWindowHeading": "الغش متوفر لـ {0} [{1}]", "CheatWindowHeading": "الغش متوفر لـ {0} [{1}]",
"BuildId": "معرف البناء:", "BuildId": "معرف البناء:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "المحتويات القابلة للتنزيل {0}", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -702,6 +702,9 @@
"Never": "Niemals", "Never": "Niemals",
"SwkbdMinCharacters": "Muss mindestens {0} Zeichen lang sein", "SwkbdMinCharacters": "Muss mindestens {0} Zeichen lang sein",
"SwkbdMinRangeCharacters": "Muss {0}-{1} Zeichen lang sein", "SwkbdMinRangeCharacters": "Muss {0}-{1} Zeichen lang sein",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Software-Tastatur", "SoftwareKeyboard": "Software-Tastatur",
"SoftwareKeyboardModeNumeric": "Darf nur 0-9 oder \".\" sein", "SoftwareKeyboardModeNumeric": "Darf nur 0-9 oder \".\" sein",
"SoftwareKeyboardModeAlphabet": "Keine CJK-Zeichen", "SoftwareKeyboardModeAlphabet": "Keine CJK-Zeichen",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Neue Dateien hinzufügen...", "UpdaterAddingFiles": "Neue Dateien hinzufügen...",
"UpdaterExtracting": "Update extrahieren...", "UpdaterExtracting": "Update extrahieren...",
"UpdaterDownloading": "Update herunterladen...", "UpdaterDownloading": "Update herunterladen...",
"Game": "Spiel",
"Docked": "Docked", "Docked": "Docked",
"Handheld": "Handheld", "Handheld": "Handheld",
"ConnectionError": "Verbindungsfehler.", "ConnectionError": "Verbindungsfehler.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Cheats verfügbar für {0} [{1}]", "CheatWindowHeading": "Cheats verfügbar für {0} [{1}]",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"BuildId": "BuildId:", "BuildId": "BuildId:",
"DlcWindowHeading": "DLC verfügbar für {0} [{1}]", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -702,6 +702,9 @@
"Never": "Ποτέ", "Never": "Ποτέ",
"SwkbdMinCharacters": "Πρέπει να έχει μήκος τουλάχιστον {0} χαρακτήρες", "SwkbdMinCharacters": "Πρέπει να έχει μήκος τουλάχιστον {0} χαρακτήρες",
"SwkbdMinRangeCharacters": "Πρέπει να έχει μήκος {0}-{1} χαρακτήρες", "SwkbdMinRangeCharacters": "Πρέπει να έχει μήκος {0}-{1} χαρακτήρες",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Εικονικό Πληκτρολόγιο", "SoftwareKeyboard": "Εικονικό Πληκτρολόγιο",
"SoftwareKeyboardModeNumeric": "Πρέπει να είναι 0-9 ή '.' μόνο", "SoftwareKeyboardModeNumeric": "Πρέπει να είναι 0-9 ή '.' μόνο",
"SoftwareKeyboardModeAlphabet": "Πρέπει να μην είναι μόνο χαρακτήρες CJK", "SoftwareKeyboardModeAlphabet": "Πρέπει να μην είναι μόνο χαρακτήρες CJK",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Προσθήκη Νέων Αρχείων...", "UpdaterAddingFiles": "Προσθήκη Νέων Αρχείων...",
"UpdaterExtracting": "Εξαγωγή Ενημέρωσης...", "UpdaterExtracting": "Εξαγωγή Ενημέρωσης...",
"UpdaterDownloading": "Λήψη Ενημέρωσης...", "UpdaterDownloading": "Λήψη Ενημέρωσης...",
"Game": "Παιχνίδι",
"Docked": "Προσκολλημένο", "Docked": "Προσκολλημένο",
"Handheld": "Χειροκίνητο", "Handheld": "Χειροκίνητο",
"ConnectionError": "Σφάλμα Σύνδεσης.", "ConnectionError": "Σφάλμα Σύνδεσης.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Διαθέσιμα Cheats για {0} [{1}]", "CheatWindowHeading": "Διαθέσιμα Cheats για {0} [{1}]",
"BuildId": "BuildId:", "BuildId": "BuildId:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -714,6 +714,9 @@
"Never": "Never", "Never": "Never",
"SwkbdMinCharacters": "Must be at least {0} characters long", "SwkbdMinCharacters": "Must be at least {0} characters long",
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long", "SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Software Keyboard", "SoftwareKeyboard": "Software Keyboard",
"SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only", "SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only",
"SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
@ -727,7 +730,6 @@
"UpdaterAddingFiles": "Adding New Files...", "UpdaterAddingFiles": "Adding New Files...",
"UpdaterExtracting": "Extracting Update...", "UpdaterExtracting": "Extracting Update...",
"UpdaterDownloading": "Downloading Update...", "UpdaterDownloading": "Downloading Update...",
"Game": "Game",
"Docked": "Docked", "Docked": "Docked",
"Handheld": "Handheld", "Handheld": "Handheld",
"ConnectionError": "Connection Error.", "ConnectionError": "Connection Error.",
@ -800,7 +802,7 @@
"CheatWindowHeading": "Cheats Available for {0} [{1}]", "CheatWindowHeading": "Cheats Available for {0} [{1}]",
"BuildId": "BuildId:", "BuildId": "BuildId:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -1,7 +1,7 @@
{ {
"Language": "Español (ES)", "Language": "Español (ES)",
"MenuBarFileOpenApplet": "Abrir applet", "MenuBarFileOpenApplet": "Abrir applet",
"MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet", "MenuBarFileOpenAppletOpenMiiApplet": "Applet Editor Mii",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abre el editor de Mii en modo autónomo", "MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abre el editor de Mii en modo autónomo",
"SettingsTabInputDirectMouseAccess": "Acceso directo al ratón", "SettingsTabInputDirectMouseAccess": "Acceso directo al ratón",
"SettingsTabSystemMemoryManagerMode": "Modo del administrador de memoria:", "SettingsTabSystemMemoryManagerMode": "Modo del administrador de memoria:",
@ -32,12 +32,12 @@
"MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware desde un archivo XCI o ZIP", "MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware desde un archivo XCI o ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware desde una carpeta", "MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware desde una carpeta",
"MenuBarToolsInstallKeys": "Install Keys", "MenuBarToolsInstallKeys": "Install Keys",
"MenuBarFileToolsInstallKeysFromFile": "Install keys from KEYS or ZIP", "MenuBarFileToolsInstallKeysFromFile": "Instalar keys de KEYS o ZIP",
"MenuBarFileToolsInstallKeysFromFolder": "Install keys from a directory", "MenuBarFileToolsInstallKeysFromFolder": "Instalar keys de un directorio",
"MenuBarToolsManageFileTypes": "Administrar tipos de archivo", "MenuBarToolsManageFileTypes": "Administrar tipos de archivo",
"MenuBarToolsInstallFileTypes": "Instalar tipos de archivo", "MenuBarToolsInstallFileTypes": "Instalar tipos de archivo",
"MenuBarToolsUninstallFileTypes": "Desinstalar tipos de archivo", "MenuBarToolsUninstallFileTypes": "Desinstalar tipos de archivo",
"MenuBarToolsXCITrimmer": "Trim XCI Files", "MenuBarToolsXCITrimmer": "Recortar archivos XCI",
"MenuBarView": "_View", "MenuBarView": "_View",
"MenuBarViewWindow": "Tamaño Ventana", "MenuBarViewWindow": "Tamaño Ventana",
"MenuBarViewWindow720": "720p", "MenuBarViewWindow720": "720p",
@ -89,11 +89,11 @@
"GameListContextMenuOpenModsDirectoryToolTip": "Abre el directorio que contiene los Mods de la Aplicación.", "GameListContextMenuOpenModsDirectoryToolTip": "Abre el directorio que contiene los Mods de la Aplicación.",
"GameListContextMenuOpenSdModsDirectory": "Abrir Directorio de Mods de Atmosphere\n\n\n\n\n\n", "GameListContextMenuOpenSdModsDirectory": "Abrir Directorio de Mods de Atmosphere\n\n\n\n\n\n",
"GameListContextMenuOpenSdModsDirectoryToolTip": "Abre el directorio alternativo de la tarjeta SD de Atmosphere que contiene los Mods de la Aplicación. Útil para los mods que están empaquetados para el hardware real.", "GameListContextMenuOpenSdModsDirectoryToolTip": "Abre el directorio alternativo de la tarjeta SD de Atmosphere que contiene los Mods de la Aplicación. Útil para los mods que están empaquetados para el hardware real.",
"GameListContextMenuTrimXCI": "Check and Trim XCI File", "GameListContextMenuTrimXCI": "Verificar y recortar archivo XCI",
"GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space", "GameListContextMenuTrimXCIToolTip": "Verificar y recortar archivo XCI para ahorrar espacio en disco",
"StatusBarGamesLoaded": "{0}/{1} juegos cargados", "StatusBarGamesLoaded": "{0}/{1} juegos cargados",
"StatusBarSystemVersion": "Versión del sistema: {0}", "StatusBarSystemVersion": "Versión del sistema: {0}",
"StatusBarXCIFileTrimming": "Trimming XCI File '{0}'", "StatusBarXCIFileTrimming": "Recortando el siguiente archivo XCI: '{0}'",
"LinuxVmMaxMapCountDialogTitle": "Límite inferior para mapeos de memoria detectado", "LinuxVmMaxMapCountDialogTitle": "Límite inferior para mapeos de memoria detectado",
"LinuxVmMaxMapCountDialogTextPrimary": "¿Quieres aumentar el valor de vm.max_map_count a {0}?", "LinuxVmMaxMapCountDialogTextPrimary": "¿Quieres aumentar el valor de vm.max_map_count a {0}?",
"LinuxVmMaxMapCountDialogTextSecondary": "Algunos juegos podrían intentar crear más mapeos de memoria de los permitidos. Ryujinx se bloqueará tan pronto como se supere este límite.", "LinuxVmMaxMapCountDialogTextSecondary": "Algunos juegos podrían intentar crear más mapeos de memoria de los permitidos. Ryujinx se bloqueará tan pronto como se supere este límite.",
@ -480,7 +480,7 @@
"DialogUninstallFileTypesSuccessMessage": "¡Tipos de archivos desinstalados con éxito!", "DialogUninstallFileTypesSuccessMessage": "¡Tipos de archivos desinstalados con éxito!",
"DialogUninstallFileTypesErrorMessage": "No se pudo desinstalar los tipos de archivo.", "DialogUninstallFileTypesErrorMessage": "No se pudo desinstalar los tipos de archivo.",
"DialogOpenSettingsWindowLabel": "Abrir ventana de opciones", "DialogOpenSettingsWindowLabel": "Abrir ventana de opciones",
"DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window", "DialogOpenXCITrimmerWindowLabel": "Ventana recortador XCI",
"DialogControllerAppletTitle": "Applet de mandos", "DialogControllerAppletTitle": "Applet de mandos",
"DialogMessageDialogErrorExceptionMessage": "Error al mostrar cuadro de diálogo: {0}", "DialogMessageDialogErrorExceptionMessage": "Error al mostrar cuadro de diálogo: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Error al mostrar teclado de software: {0}", "DialogSoftwareKeyboardErrorExceptionMessage": "Error al mostrar teclado de software: {0}",
@ -509,13 +509,13 @@
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n¿Continuar?", "DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n¿Continuar?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Instalando firmware...", "DialogFirmwareInstallerFirmwareInstallWaitMessage": "Instalando firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versión de sistema {0} instalada con éxito.", "DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versión de sistema {0} instalada con éxito.",
"DialogKeysInstallerKeysNotFoundErrorMessage": "An invalid Keys file was found in {0}", "DialogKeysInstallerKeysNotFoundErrorMessage": "Se halló un archivo Keys inválido en {0}",
"DialogKeysInstallerKeysInstallTitle": "Install Keys", "DialogKeysInstallerKeysInstallTitle": "Instalar Keys",
"DialogKeysInstallerKeysInstallMessage": "New Keys file will be installed.", "DialogKeysInstallerKeysInstallMessage": "Un nuevo archivo Keys será instalado.",
"DialogKeysInstallerKeysInstallSubMessage": "\n\nThis may replace some of the current installed Keys.", "DialogKeysInstallerKeysInstallSubMessage": "\n\nEsto puede reemplazar algunas de las Keys actualmente instaladas.",
"DialogKeysInstallerKeysInstallConfirmMessage": "\n\nDo you want to continue?", "DialogKeysInstallerKeysInstallConfirmMessage": "\n\nDeseas continuar?",
"DialogKeysInstallerKeysInstallWaitMessage": "Installing Keys...", "DialogKeysInstallerKeysInstallWaitMessage": "Instalando Keys...",
"DialogKeysInstallerKeysInstallSuccessMessage": "New Keys file successfully installed.", "DialogKeysInstallerKeysInstallSuccessMessage": "Nuevo archivo Keys instalado con éxito.",
"DialogUserProfileDeletionWarningMessage": "Si eliminas el perfil seleccionado no quedará ningún otro perfil", "DialogUserProfileDeletionWarningMessage": "Si eliminas el perfil seleccionado no quedará ningún otro perfil",
"DialogUserProfileDeletionConfirmMessage": "¿Quieres eliminar el perfil seleccionado?", "DialogUserProfileDeletionConfirmMessage": "¿Quieres eliminar el perfil seleccionado?",
"DialogUserProfileUnsavedChangesTitle": "Advertencia - Cambios sin guardar", "DialogUserProfileUnsavedChangesTitle": "Advertencia - Cambios sin guardar",
@ -688,20 +688,23 @@
"OpenSetupGuideMessage": "Abrir la guía de instalación", "OpenSetupGuideMessage": "Abrir la guía de instalación",
"NoUpdate": "No actualizado", "NoUpdate": "No actualizado",
"TitleUpdateVersionLabel": "Versión {0} - {1}", "TitleUpdateVersionLabel": "Versión {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}", "TitleBundledUpdateVersionLabel": "Incorporado: Versión {0}",
"TitleBundledDlcLabel": "Bundled:", "TitleBundledDlcLabel": "Incorporado:",
"TitleXCIStatusPartialLabel": "Partial", "TitleXCIStatusPartialLabel": "Parcial",
"TitleXCIStatusTrimmableLabel": "Untrimmed", "TitleXCIStatusTrimmableLabel": "Sin recortar",
"TitleXCIStatusUntrimmableLabel": "Trimmed", "TitleXCIStatusUntrimmableLabel": "Recortado",
"TitleXCIStatusFailedLabel": "(Failed)", "TitleXCIStatusFailedLabel": "(Fallido)",
"TitleXCICanSaveLabel": "Save {0:n0} Mb", "TitleXCICanSaveLabel": "Ahorra {0:n0} Mb",
"TitleXCISavingLabel": "Saved {0:n0} Mb", "TitleXCISavingLabel": "{0:n0} Mb ahorrado(s)",
"RyujinxInfo": "Ryujinx - Info", "RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Confirmación", "RyujinxConfirm": "Ryujinx - Confirmación",
"FileDialogAllTypes": "Todos los tipos", "FileDialogAllTypes": "Todos los tipos",
"Never": "Nunca", "Never": "Nunca",
"SwkbdMinCharacters": "Debe tener al menos {0} caracteres", "SwkbdMinCharacters": "Debe tener al menos {0} caracteres",
"SwkbdMinRangeCharacters": "Debe tener {0}-{1} caracteres", "SwkbdMinRangeCharacters": "Debe tener {0}-{1} caracteres",
"CabinetTitle": "Diálogo Gabinete",
"CabinetDialog": "Ingresa el nuevo nombre de tu Amiibo",
"CabinetScanDialog": "Escanea tu Amiibo ahora.",
"SoftwareKeyboard": "Teclado de software", "SoftwareKeyboard": "Teclado de software",
"SoftwareKeyboardModeNumeric": "Debe ser sólo 0-9 o '.'", "SoftwareKeyboardModeNumeric": "Debe ser sólo 0-9 o '.'",
"SoftwareKeyboardModeAlphabet": "Solo deben ser caracteres no CJK", "SoftwareKeyboardModeAlphabet": "Solo deben ser caracteres no CJK",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Añadiendo nuevos archivos...", "UpdaterAddingFiles": "Añadiendo nuevos archivos...",
"UpdaterExtracting": "Extrayendo actualización...", "UpdaterExtracting": "Extrayendo actualización...",
"UpdaterDownloading": "Descargando actualización...", "UpdaterDownloading": "Descargando actualización...",
"Game": "Juego",
"Docked": "Dock/TV", "Docked": "Dock/TV",
"Handheld": "Portátil", "Handheld": "Portátil",
"ConnectionError": "Error de conexión.", "ConnectionError": "Error de conexión.",
@ -748,44 +750,44 @@
"SelectDlcDialogTitle": "Selecciona archivo(s) de DLC", "SelectDlcDialogTitle": "Selecciona archivo(s) de DLC",
"SelectUpdateDialogTitle": "Selecciona archivo(s) de actualización", "SelectUpdateDialogTitle": "Selecciona archivo(s) de actualización",
"SelectModDialogTitle": "Seleccionar un directorio de Mods", "SelectModDialogTitle": "Seleccionar un directorio de Mods",
"TrimXCIFileDialogTitle": "Check and Trim XCI File", "TrimXCIFileDialogTitle": "Verificar y recortar archivo XCI",
"TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.", "TrimXCIFileDialogPrimaryText": "Esta función verificará el espacio vacío y después recortará el archivo XCI para ahorrar espacio en disco",
"TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB", "TrimXCIFileDialogSecondaryText": "Tamaño de archivo actual: {0:n} MB\nTamaño de datos de juego: {1:n} MB\nAhorro de espacio en disco: {2:n} MB",
"TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details", "TrimXCIFileNoTrimNecessary": "El archivo XCI no necesita ser recortado. Verifica los logs para más detalles.",
"TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details", "TrimXCIFileNoUntrimPossible": "El recorte del archivo XCI no puede ser deshecho. Verifica los registros para más detalles.",
"TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details", "TrimXCIFileReadOnlyFileCannotFix": "El archivo XCI es de solo Lectura y no se le puede escribir. Lee el registro para más información.",
"TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.", "TrimXCIFileFileSizeChanged": "El archivo XCI ha cambiado de tamaño desde que fue escaneado. Verifica que no se esté escribiendo al archivo y vuelve a intentarlo.",
"TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim", "TrimXCIFileFreeSpaceCheckFailed": "El archivo XCI tiene datos en el área de espacio libre, no es seguro recortar.",
"TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details", "TrimXCIFileInvalidXCIFile": "El archivo XCI contiene datos inválidos. Lee el registro para más información.",
"TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details", "TrimXCIFileFileIOWriteError": "El archivo XCI no se puede abrir para escribirlo. Lee el registro para más información.",
"TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed", "TrimXCIFileFailedPrimaryText": "El recorte del archivo XCI falló",
"TrimXCIFileCancelled": "The operation was cancelled", "TrimXCIFileCancelled": "La operación fue cancelada",
"TrimXCIFileFileUndertermined": "No operation was performed", "TrimXCIFileFileUndertermined": "No se realizó ninguna operación",
"UserProfileWindowTitle": "Administrar perfiles de usuario", "UserProfileWindowTitle": "Administrar perfiles de usuario",
"CheatWindowTitle": "Administrar cheats", "CheatWindowTitle": "Administrar cheats",
"DlcWindowTitle": "Administrar contenido descargable", "DlcWindowTitle": "Administrar contenido descargable",
"ModWindowTitle": "Administrar Mods para {0} ({1})", "ModWindowTitle": "Administrar Mods para {0} ({1})",
"UpdateWindowTitle": "Administrar actualizaciones", "UpdateWindowTitle": "Administrar actualizaciones",
"XCITrimmerWindowTitle": "XCI File Trimmer", "XCITrimmerWindowTitle": "Recortador de archivos XCI",
"XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected", "XCITrimmerTitleStatusCount": "{0} de {1} Título(s) seleccionado(s)",
"XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)", "XCITrimmerTitleStatusCountWithFilter": "{0} de {1} Título(s) seleccionado(s) ({2} mostrado(s))",
"XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...", "XCITrimmerTitleStatusTrimming": "Recortando {0} Título(s)...",
"XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...", "XCITrimmerTitleStatusUntrimming": "Deshaciendo recorte de {0} Título(s)...",
"XCITrimmerTitleStatusFailed": "Failed", "XCITrimmerTitleStatusFailed": "Fallido",
"XCITrimmerPotentialSavings": "Potential Savings", "XCITrimmerPotentialSavings": "Ahorro potencial",
"XCITrimmerActualSavings": "Actual Savings", "XCITrimmerActualSavings": "Ahorro real",
"XCITrimmerSavingsMb": "{0:n0} Mb", "XCITrimmerSavingsMb": "{0:n0} Mb",
"XCITrimmerSelectDisplayed": "Select Shown", "XCITrimmerSelectDisplayed": "Seleccionar mostrado(s)",
"XCITrimmerDeselectDisplayed": "Deselect Shown", "XCITrimmerDeselectDisplayed": "Deseleccionar mostrado(s)",
"XCITrimmerSortName": "Title", "XCITrimmerSortName": "Título",
"XCITrimmerSortSaved": "Space Savings", "XCITrimmerSortSaved": "Ahorro de espacio",
"XCITrimmerTrim": "Trim", "XCITrimmerTrim": "Recortar",
"XCITrimmerUntrim": "Untrim", "XCITrimmerUntrim": "Deshacer recorte",
"UpdateWindowUpdateAddedMessage": "{0} nueva(s) actualización(es) agregada(s)", "UpdateWindowUpdateAddedMessage": "{0} nueva(s) actualización(es) agregada(s)",
"UpdateWindowBundledContentNotice": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.", "UpdateWindowBundledContentNotice": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.",
"CheatWindowHeading": "Cheats disponibles para {0} [{1}]", "CheatWindowHeading": "Cheats disponibles para {0} [{1}]",
"BuildId": "Id de compilación:", "BuildId": "Id de compilación:",
"DlcWindowHeading": "Contenido descargable disponible para {0} [{1}]", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)", "DlcWindowDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)",
"AutoloadDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)", "AutoloadDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)",
"AutoloadDlcRemovedMessage": "Se eliminaron {0} contenido(s) descargable(s) faltantes", "AutoloadDlcRemovedMessage": "Se eliminaron {0} contenido(s) descargable(s) faltantes",
@ -793,7 +795,7 @@
"AutoloadUpdateRemovedMessage": "Se eliminaron {0} actualización(es) faltantes", "AutoloadUpdateRemovedMessage": "Se eliminaron {0} actualización(es) faltantes",
"ModWindowHeading": "{0} Mod(s)", "ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Editar selección", "UserProfilesEditProfile": "Editar selección",
"Continue": "Continue", "Continue": "Continuar",
"Cancel": "Cancelar", "Cancel": "Cancelar",
"Save": "Guardar", "Save": "Guardar",
"Discard": "Descartar", "Discard": "Descartar",

View File

@ -702,6 +702,9 @@
"Never": "Jamais", "Never": "Jamais",
"SwkbdMinCharacters": "Doit comporter au moins {0} caractères", "SwkbdMinCharacters": "Doit comporter au moins {0} caractères",
"SwkbdMinRangeCharacters": "Doit comporter entre {0} et {1} caractères", "SwkbdMinRangeCharacters": "Doit comporter entre {0} et {1} caractères",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Clavier logiciel", "SoftwareKeyboard": "Clavier logiciel",
"SoftwareKeyboardModeNumeric": "Doit être 0-9 ou '.' uniquement", "SoftwareKeyboardModeNumeric": "Doit être 0-9 ou '.' uniquement",
"SoftwareKeyboardModeAlphabet": "Doit être uniquement des caractères non CJK", "SoftwareKeyboardModeAlphabet": "Doit être uniquement des caractères non CJK",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Ajout des nouveaux fichiers...", "UpdaterAddingFiles": "Ajout des nouveaux fichiers...",
"UpdaterExtracting": "Extraction de la mise à jour…", "UpdaterExtracting": "Extraction de la mise à jour…",
"UpdaterDownloading": "Téléchargement de la mise à jour...", "UpdaterDownloading": "Téléchargement de la mise à jour...",
"Game": "Jeu",
"Docked": "Mode station d'accueil", "Docked": "Mode station d'accueil",
"Handheld": "Mode Portable", "Handheld": "Mode Portable",
"ConnectionError": "Erreur de connexion.", "ConnectionError": "Erreur de connexion.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Cheats disponibles pour {0} [{1}]", "CheatWindowHeading": "Cheats disponibles pour {0} [{1}]",
"BuildId": "BuildId :", "BuildId": "BuildId :",
"DlcWindowBundledContentNotice": "Les DLC inclus avec le jeu ne peuvent pas être supprimés mais peuvent être désactivés.", "DlcWindowBundledContentNotice": "Les DLC inclus avec le jeu ne peuvent pas être supprimés mais peuvent être désactivés.",
"DlcWindowHeading": "{0} Contenu(s) téléchargeable(s)", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)", "DlcWindowDlcAddedMessage": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)",
"AutoloadDlcAddedMessage": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)", "AutoloadDlcAddedMessage": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)",
"AutoloadDlcRemovedMessage": "{0} contenu(s) téléchargeable(s) manquant(s) supprimé(s)", "AutoloadDlcRemovedMessage": "{0} contenu(s) téléchargeable(s) manquant(s) supprimé(s)",

View File

@ -702,6 +702,9 @@
"Never": "אף פעם", "Never": "אף פעם",
"SwkbdMinCharacters": "לפחות {0} תווים", "SwkbdMinCharacters": "לפחות {0} תווים",
"SwkbdMinRangeCharacters": "באורך {0}-{1} תווים", "SwkbdMinRangeCharacters": "באורך {0}-{1} תווים",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "מקלדת וירטואלית", "SoftwareKeyboard": "מקלדת וירטואלית",
"SoftwareKeyboardModeNumeric": "חייב להיות בין 0-9 או '.' בלבד", "SoftwareKeyboardModeNumeric": "חייב להיות בין 0-9 או '.' בלבד",
"SoftwareKeyboardModeAlphabet": "מחויב להיות ללא אותיות CJK", "SoftwareKeyboardModeAlphabet": "מחויב להיות ללא אותיות CJK",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "מוסיף קבצים חדשים...", "UpdaterAddingFiles": "מוסיף קבצים חדשים...",
"UpdaterExtracting": "מחלץ עדכון...", "UpdaterExtracting": "מחלץ עדכון...",
"UpdaterDownloading": "מוריד עדכון...", "UpdaterDownloading": "מוריד עדכון...",
"Game": "משחק",
"Docked": "בתחנת עגינה", "Docked": "בתחנת עגינה",
"Handheld": "נייד", "Handheld": "נייד",
"ConnectionError": "שגיאת חיבור", "ConnectionError": "שגיאת חיבור",

View File

@ -702,6 +702,9 @@
"Never": "Mai", "Never": "Mai",
"SwkbdMinCharacters": "Non può avere meno di {0} caratteri", "SwkbdMinCharacters": "Non può avere meno di {0} caratteri",
"SwkbdMinRangeCharacters": "Può avere da {0} a {1} caratteri", "SwkbdMinRangeCharacters": "Può avere da {0} a {1} caratteri",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Tastiera software", "SoftwareKeyboard": "Tastiera software",
"SoftwareKeyboardModeNumeric": "Deve essere solo 0-9 o '.'", "SoftwareKeyboardModeNumeric": "Deve essere solo 0-9 o '.'",
"SoftwareKeyboardModeAlphabet": "Deve essere solo caratteri non CJK", "SoftwareKeyboardModeAlphabet": "Deve essere solo caratteri non CJK",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Aggiunta dei nuovi file...", "UpdaterAddingFiles": "Aggiunta dei nuovi file...",
"UpdaterExtracting": "Estrazione dell'aggiornamento...", "UpdaterExtracting": "Estrazione dell'aggiornamento...",
"UpdaterDownloading": "Download dell'aggiornamento...", "UpdaterDownloading": "Download dell'aggiornamento...",
"Game": "Gioco",
"Docked": "TV", "Docked": "TV",
"Handheld": "Portatile", "Handheld": "Portatile",
"ConnectionError": "Errore di connessione.", "ConnectionError": "Errore di connessione.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Trucchi disponibili per {0} [{1}]", "CheatWindowHeading": "Trucchi disponibili per {0} [{1}]",
"BuildId": "ID Build", "BuildId": "ID Build",
"DlcWindowBundledContentNotice": "i DLC \"impacchettati\" non possono essere rimossi, ma solo disabilitati.", "DlcWindowBundledContentNotice": "i DLC \"impacchettati\" non possono essere rimossi, ma solo disabilitati.",
"DlcWindowHeading": "DLC disponibili per {0} [{1}]", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} nuovo/i contenuto/i scaricabile/i aggiunto/i", "DlcWindowDlcAddedMessage": "{0} nuovo/i contenuto/i scaricabile/i aggiunto/i",
"AutoloadDlcAddedMessage": "{0} contenuto/i scaricabile/i aggiunto/i", "AutoloadDlcAddedMessage": "{0} contenuto/i scaricabile/i aggiunto/i",
"AutoloadDlcRemovedMessage": "{0} contenuto/i scaricabile/i mancante/i rimosso/i", "AutoloadDlcRemovedMessage": "{0} contenuto/i scaricabile/i mancante/i rimosso/i",

View File

@ -702,6 +702,9 @@
"Never": "決して", "Never": "決して",
"SwkbdMinCharacters": "最低 {0} 文字必要です", "SwkbdMinCharacters": "最低 {0} 文字必要です",
"SwkbdMinRangeCharacters": "{0}-{1} 文字にしてください", "SwkbdMinRangeCharacters": "{0}-{1} 文字にしてください",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "ソフトウェアキーボード", "SoftwareKeyboard": "ソフトウェアキーボード",
"SoftwareKeyboardModeNumeric": "0-9 または '.' のみでなければなりません", "SoftwareKeyboardModeNumeric": "0-9 または '.' のみでなければなりません",
"SoftwareKeyboardModeAlphabet": "CJK文字以外のみ", "SoftwareKeyboardModeAlphabet": "CJK文字以外のみ",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "新規ファイルを追加中...", "UpdaterAddingFiles": "新規ファイルを追加中...",
"UpdaterExtracting": "アップデートを展開中...", "UpdaterExtracting": "アップデートを展開中...",
"UpdaterDownloading": "アップデートをダウンロード中...", "UpdaterDownloading": "アップデートをダウンロード中...",
"Game": "ゲーム",
"Docked": "ドッキング", "Docked": "ドッキング",
"Handheld": "携帯", "Handheld": "携帯",
"ConnectionError": "接続エラー.", "ConnectionError": "接続エラー.",
@ -785,7 +787,7 @@
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "利用可能なチート {0} [{1}]", "CheatWindowHeading": "利用可能なチート {0} [{1}]",
"BuildId": "ビルドID:", "BuildId": "ビルドID:",
"DlcWindowHeading": "利用可能な DLC {0} [{1}]", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -1,7 +1,7 @@
{ {
"Language": "한국어", "Language": "한국어",
"MenuBarFileOpenApplet": "애플릿 열기", "MenuBarFileOpenApplet": "애플릿 열기",
"MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet", "MenuBarFileOpenAppletOpenMiiApplet": "Mii 편집 애플릿",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "독립 실행형 모드로 Mii 편집기 애플릿 열기", "MenuBarFileOpenAppletOpenMiiAppletToolTip": "독립 실행형 모드로 Mii 편집기 애플릿 열기",
"SettingsTabInputDirectMouseAccess": "마우스 직접 접근", "SettingsTabInputDirectMouseAccess": "마우스 직접 접근",
"SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드 :", "SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드 :",
@ -484,7 +484,7 @@
"DialogControllerAppletTitle": "컨트롤러 애플릿", "DialogControllerAppletTitle": "컨트롤러 애플릿",
"DialogMessageDialogErrorExceptionMessage": "메시지 대화 상자 표시 오류 : {0}", "DialogMessageDialogErrorExceptionMessage": "메시지 대화 상자 표시 오류 : {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "소프트웨어 키보드 표시 오류 : {0}", "DialogSoftwareKeyboardErrorExceptionMessage": "소프트웨어 키보드 표시 오류 : {0}",
"DialogErrorAppletErrorExceptionMessage": "ErrorApplet 대화 상자 표시 오류 : {0}", "DialogErrorAppletErrorExceptionMessage": "애플릿 오류류 대화 상자 표시 오류 : {0}",
"DialogUserErrorDialogMessage": "{0}: {1}", "DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\n이 오류를 해결하는 방법에 대한 자세한 내용은 설정 가이드를 참조하세요.", "DialogUserErrorDialogInfoMessage": "\n이 오류를 해결하는 방법에 대한 자세한 내용은 설정 가이드를 참조하세요.",
"DialogUserErrorDialogTitle": "Ryujinx 오류 ({0})", "DialogUserErrorDialogTitle": "Ryujinx 오류 ({0})",
@ -702,6 +702,9 @@
"Never": "절대 안 함", "Never": "절대 안 함",
"SwkbdMinCharacters": "{0}자 이상이어야 함", "SwkbdMinCharacters": "{0}자 이상이어야 함",
"SwkbdMinRangeCharacters": "{0}-{1}자 길이여야 함", "SwkbdMinRangeCharacters": "{0}-{1}자 길이여야 함",
"CabinetTitle": "캐비닛 대화 상자",
"CabinetDialog": "Amiibo의 새 이름 입력하기",
"CabinetScanDialog": "지금 Amiibo를 스캔하세요.",
"SoftwareKeyboard": "소프트웨어 키보드", "SoftwareKeyboard": "소프트웨어 키보드",
"SoftwareKeyboardModeNumeric": "0-9 또는 '.'만 가능", "SoftwareKeyboardModeNumeric": "0-9 또는 '.'만 가능",
"SoftwareKeyboardModeAlphabet": "CJK 문자가 아닌 문자만 가능", "SoftwareKeyboardModeAlphabet": "CJK 문자가 아닌 문자만 가능",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "새 파일 추가...", "UpdaterAddingFiles": "새 파일 추가...",
"UpdaterExtracting": "업데이트 추출...", "UpdaterExtracting": "업데이트 추출...",
"UpdaterDownloading": "업데이트 내려받기 중...", "UpdaterDownloading": "업데이트 내려받기 중...",
"Game": "게임",
"Docked": "도킹", "Docked": "도킹",
"Handheld": "휴대", "Handheld": "휴대",
"ConnectionError": "연결 오류가 발생했습니다.", "ConnectionError": "연결 오류가 발생했습니다.",
@ -779,14 +781,14 @@
"XCITrimmerDeselectDisplayed": "표시됨 선택 취소", "XCITrimmerDeselectDisplayed": "표시됨 선택 취소",
"XCITrimmerSortName": "타이틀", "XCITrimmerSortName": "타이틀",
"XCITrimmerSortSaved": "공간 절약s", "XCITrimmerSortSaved": "공간 절약s",
"XCITrimmerTrim": "Trim", "XCITrimmerTrim": "트림",
"XCITrimmerUntrim": "Untrim", "XCITrimmerUntrim": "언트림",
"UpdateWindowUpdateAddedMessage": "{0}개의 새 업데이트가 추가됨", "UpdateWindowUpdateAddedMessage": "{0}개의 새 업데이트가 추가됨",
"UpdateWindowBundledContentNotice": "번들 업데이트는 제거할 수 없으며, 비활성화만 가능합니다.", "UpdateWindowBundledContentNotice": "번들 업데이트는 제거할 수 없으며, 비활성화만 가능합니다.",
"CheatWindowHeading": "{0} [{1}]에 사용 가능한 치트", "CheatWindowHeading": "{0} [{1}]에 사용 가능한 치트",
"BuildId": "빌드ID:", "BuildId": "빌드ID:",
"DlcWindowBundledContentNotice": "번들 DLC는 제거할 수 없으며 비활성화만 가능합니다.", "DlcWindowBundledContentNotice": "번들 DLC는 제거할 수 없으며 비활성화만 가능합니다.",
"DlcWindowHeading": "{1} ({2})에 내려받기 가능한 콘텐츠 {0}개 사용 가능", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨", "DlcWindowDlcAddedMessage": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨",
"AutoloadDlcAddedMessage": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨", "AutoloadDlcAddedMessage": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨",
"AutoloadDlcRemovedMessage": "{0}개의 내려받기 가능한 콘텐츠가 제거됨", "AutoloadDlcRemovedMessage": "{0}개의 내려받기 가능한 콘텐츠가 제거됨",

View File

@ -702,6 +702,9 @@
"Never": "Nigdy", "Never": "Nigdy",
"SwkbdMinCharacters": "Musi mieć co najmniej {0} znaków", "SwkbdMinCharacters": "Musi mieć co najmniej {0} znaków",
"SwkbdMinRangeCharacters": "Musi mieć długość od {0}-{1} znaków", "SwkbdMinRangeCharacters": "Musi mieć długość od {0}-{1} znaków",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Klawiatura Oprogramowania", "SoftwareKeyboard": "Klawiatura Oprogramowania",
"SoftwareKeyboardModeNumeric": "Może składać się jedynie z 0-9 lub '.'", "SoftwareKeyboardModeNumeric": "Może składać się jedynie z 0-9 lub '.'",
"SoftwareKeyboardModeAlphabet": "Nie może zawierać znaków CJK", "SoftwareKeyboardModeAlphabet": "Nie może zawierać znaków CJK",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Dodawanie Nowych Plików...", "UpdaterAddingFiles": "Dodawanie Nowych Plików...",
"UpdaterExtracting": "Wypakowywanie Aktualizacji...", "UpdaterExtracting": "Wypakowywanie Aktualizacji...",
"UpdaterDownloading": "Pobieranie Aktualizacji...", "UpdaterDownloading": "Pobieranie Aktualizacji...",
"Game": "Gra",
"Docked": "Zadokowany", "Docked": "Zadokowany",
"Handheld": "Przenośny", "Handheld": "Przenośny",
"ConnectionError": "Błąd Połączenia.", "ConnectionError": "Błąd Połączenia.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Kody Dostępne dla {0} [{1}]", "CheatWindowHeading": "Kody Dostępne dla {0} [{1}]",
"BuildId": "Identyfikator wersji:", "BuildId": "Identyfikator wersji:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "{0} Zawartości do Pobrania dostępna dla {1} ({2})", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -701,6 +701,9 @@
"Never": "Nunca", "Never": "Nunca",
"SwkbdMinCharacters": "Deve ter pelo menos {0} caracteres", "SwkbdMinCharacters": "Deve ter pelo menos {0} caracteres",
"SwkbdMinRangeCharacters": "Deve ter entre {0}-{1} caracteres", "SwkbdMinRangeCharacters": "Deve ter entre {0}-{1} caracteres",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Teclado por Software", "SoftwareKeyboard": "Teclado por Software",
"SoftwareKeyboardModeNumeric": "Deve ser somente 0-9 ou '.'", "SoftwareKeyboardModeNumeric": "Deve ser somente 0-9 ou '.'",
"SoftwareKeyboardModeAlphabet": "Apenas devem ser caracteres não CJK.", "SoftwareKeyboardModeAlphabet": "Apenas devem ser caracteres não CJK.",
@ -714,7 +717,6 @@
"UpdaterAddingFiles": "Adicionando novos arquivos...", "UpdaterAddingFiles": "Adicionando novos arquivos...",
"UpdaterExtracting": "Extraíndo atualização...", "UpdaterExtracting": "Extraíndo atualização...",
"UpdaterDownloading": "Baixando atualização...", "UpdaterDownloading": "Baixando atualização...",
"Game": "Jogo",
"Docked": "TV", "Docked": "TV",
"Handheld": "Portátil", "Handheld": "Portátil",
"ConnectionError": "Erro de conexão.", "ConnectionError": "Erro de conexão.",
@ -785,7 +787,7 @@
"CheatWindowHeading": "Cheats disponíveis para {0} [{1}]", "CheatWindowHeading": "Cheats disponíveis para {0} [{1}]",
"BuildId": "ID da Build:", "BuildId": "ID da Build:",
"DlcWindowBundledContentNotice": "DLCs incorporadas não podem ser removidas, apenas desativadas.", "DlcWindowBundledContentNotice": "DLCs incorporadas não podem ser removidas, apenas desativadas.",
"DlcWindowHeading": "{0} DLCs disponíveis para {1} ({2})", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} novo(s) conteúdo(s) para download adicionado(s)", "DlcWindowDlcAddedMessage": "{0} novo(s) conteúdo(s) para download adicionado(s)",
"AutoloadDlcAddedMessage": "{0} novo(s) conteúdo(s) para download adicionado(s)", "AutoloadDlcAddedMessage": "{0} novo(s) conteúdo(s) para download adicionado(s)",
"AutoloadDlcRemovedMessage": "{0} conteúdo(s) para download ausente(s) removido(s)", "AutoloadDlcRemovedMessage": "{0} conteúdo(s) para download ausente(s) removido(s)",

View File

@ -702,6 +702,9 @@
"Never": "Никогда", "Never": "Никогда",
"SwkbdMinCharacters": "Должно быть не менее {0} символов.", "SwkbdMinCharacters": "Должно быть не менее {0} символов.",
"SwkbdMinRangeCharacters": "Должно быть {0}-{1} символов", "SwkbdMinRangeCharacters": "Должно быть {0}-{1} символов",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Программная клавиатура", "SoftwareKeyboard": "Программная клавиатура",
"SoftwareKeyboardModeNumeric": "Должно быть в диапазоне 0-9 или '.'", "SoftwareKeyboardModeNumeric": "Должно быть в диапазоне 0-9 или '.'",
"SoftwareKeyboardModeAlphabet": "Не должно быть CJK-символов", "SoftwareKeyboardModeAlphabet": "Не должно быть CJK-символов",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Добавление новых файлов...", "UpdaterAddingFiles": "Добавление новых файлов...",
"UpdaterExtracting": "Извлечение обновления...", "UpdaterExtracting": "Извлечение обновления...",
"UpdaterDownloading": "Загрузка обновления...", "UpdaterDownloading": "Загрузка обновления...",
"Game": "Игра",
"Docked": "Стационарный режим", "Docked": "Стационарный режим",
"Handheld": "Портативный режим", "Handheld": "Портативный режим",
"ConnectionError": "Ошибка соединения", "ConnectionError": "Ошибка соединения",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Доступные читы для {0} [{1}]", "CheatWindowHeading": "Доступные читы для {0} [{1}]",
"BuildId": "ID версии:", "BuildId": "ID версии:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "{0} DLC", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -702,6 +702,9 @@
"Never": "ไม่ต้อง", "Never": "ไม่ต้อง",
"SwkbdMinCharacters": "ต้องมีความยาวของตัวอักษรอย่างน้อย {0} ตัว", "SwkbdMinCharacters": "ต้องมีความยาวของตัวอักษรอย่างน้อย {0} ตัว",
"SwkbdMinRangeCharacters": "ต้องมีความยาวของตัวอักษร {0}-{1} ตัว", "SwkbdMinRangeCharacters": "ต้องมีความยาวของตัวอักษร {0}-{1} ตัว",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "ซอฟต์แวร์คีย์บอร์ด", "SoftwareKeyboard": "ซอฟต์แวร์คีย์บอร์ด",
"SoftwareKeyboardModeNumeric": "ต้องเป็น 0-9 หรือ '.' เท่านั้น", "SoftwareKeyboardModeNumeric": "ต้องเป็น 0-9 หรือ '.' เท่านั้น",
"SoftwareKeyboardModeAlphabet": "ต้องเป็นตัวอักษรที่ไม่ใช่ประเภท CJK เท่านั้น", "SoftwareKeyboardModeAlphabet": "ต้องเป็นตัวอักษรที่ไม่ใช่ประเภท CJK เท่านั้น",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "กำลังเพิ่มไฟล์ใหม่...", "UpdaterAddingFiles": "กำลังเพิ่มไฟล์ใหม่...",
"UpdaterExtracting": "กำลังแยกการอัปเดต...", "UpdaterExtracting": "กำลังแยกการอัปเดต...",
"UpdaterDownloading": "กำลังดาวน์โหลดอัปเดต...", "UpdaterDownloading": "กำลังดาวน์โหลดอัปเดต...",
"Game": "เกมส์",
"Docked": "ด็อก", "Docked": "ด็อก",
"Handheld": "แฮนด์เฮลด์", "Handheld": "แฮนด์เฮลด์",
"ConnectionError": "การเชื่อมต่อล้มเหลว", "ConnectionError": "การเชื่อมต่อล้มเหลว",
@ -786,7 +788,7 @@
"CheatWindowHeading": "สูตรโกงมีให้สำหรับ {0} [{1}]", "CheatWindowHeading": "สูตรโกงมีให้สำหรับ {0} [{1}]",
"BuildId": "รหัสการสร้าง:", "BuildId": "รหัสการสร้าง:",
"DlcWindowBundledContentNotice": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น", "DlcWindowBundledContentNotice": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น",
"DlcWindowHeading": "{0} DLC ที่สามารถดาวน์โหลดได้", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} DLC ใหม่ที่เพิ่มเข้ามา", "DlcWindowDlcAddedMessage": "{0} DLC ใหม่ที่เพิ่มเข้ามา",
"AutoloadDlcAddedMessage": "{0} ใหม่ที่เพิ่มเข้ามา", "AutoloadDlcAddedMessage": "{0} ใหม่ที่เพิ่มเข้ามา",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -702,6 +702,9 @@
"Never": "Hiçbir Zaman", "Never": "Hiçbir Zaman",
"SwkbdMinCharacters": "En az {0} karakter uzunluğunda olmalı", "SwkbdMinCharacters": "En az {0} karakter uzunluğunda olmalı",
"SwkbdMinRangeCharacters": "{0}-{1} karakter uzunluğunda olmalı", "SwkbdMinRangeCharacters": "{0}-{1} karakter uzunluğunda olmalı",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Yazılım Klavyesi", "SoftwareKeyboard": "Yazılım Klavyesi",
"SoftwareKeyboardModeNumeric": "Sadece 0-9 veya '.' olabilir", "SoftwareKeyboardModeNumeric": "Sadece 0-9 veya '.' olabilir",
"SoftwareKeyboardModeAlphabet": "Sadece CJK-characters olmayan karakterler olabilir", "SoftwareKeyboardModeAlphabet": "Sadece CJK-characters olmayan karakterler olabilir",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Yeni Dosyalar Ekleniyor...", "UpdaterAddingFiles": "Yeni Dosyalar Ekleniyor...",
"UpdaterExtracting": "Güncelleme Ayrıştırılıyor...", "UpdaterExtracting": "Güncelleme Ayrıştırılıyor...",
"UpdaterDownloading": "Güncelleme İndiriliyor...", "UpdaterDownloading": "Güncelleme İndiriliyor...",
"Game": "Oyun",
"Docked": "Docked", "Docked": "Docked",
"Handheld": "El tipi", "Handheld": "El tipi",
"ConnectionError": "Bağlantı Hatası.", "ConnectionError": "Bağlantı Hatası.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "{0} için Hile mevcut [{1}]", "CheatWindowHeading": "{0} için Hile mevcut [{1}]",
"BuildId": "BuildId:", "BuildId": "BuildId:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -702,6 +702,9 @@
"Never": "Ніколи", "Never": "Ніколи",
"SwkbdMinCharacters": "Мінімальна кількість символів: {0}", "SwkbdMinCharacters": "Мінімальна кількість символів: {0}",
"SwkbdMinRangeCharacters": "Має бути {0}-{1} символів", "SwkbdMinRangeCharacters": "Має бути {0}-{1} символів",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Програмна клавіатура", "SoftwareKeyboard": "Програмна клавіатура",
"SoftwareKeyboardModeNumeric": "Повинно бути лише 0-9 або “.”", "SoftwareKeyboardModeNumeric": "Повинно бути лише 0-9 або “.”",
"SoftwareKeyboardModeAlphabet": "Повинно бути лише не CJK-символи", "SoftwareKeyboardModeAlphabet": "Повинно бути лише не CJK-символи",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Додавання нових файлів...", "UpdaterAddingFiles": "Додавання нових файлів...",
"UpdaterExtracting": "Видобування оновлення...", "UpdaterExtracting": "Видобування оновлення...",
"UpdaterDownloading": "Завантаження оновлення...", "UpdaterDownloading": "Завантаження оновлення...",
"Game": "Гра",
"Docked": "Док-станція", "Docked": "Док-станція",
"Handheld": "Портативний", "Handheld": "Портативний",
"ConnectionError": "Помилка з'єднання.", "ConnectionError": "Помилка з'єднання.",
@ -786,7 +788,7 @@
"CheatWindowHeading": "Коди доступні для {0} [{1}]", "CheatWindowHeading": "Коди доступні для {0} [{1}]",
"BuildId": "ID збірки:", "BuildId": "ID збірки:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"DlcWindowHeading": "Вміст для завантаження, доступний для {1} ({2}): {0}", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",

View File

@ -702,6 +702,9 @@
"Never": "从不", "Never": "从不",
"SwkbdMinCharacters": "不少于 {0} 个字符", "SwkbdMinCharacters": "不少于 {0} 个字符",
"SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字符", "SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字符",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "软键盘", "SoftwareKeyboard": "软键盘",
"SoftwareKeyboardModeNumeric": "只能输入 0-9 或 \".\"", "SoftwareKeyboardModeNumeric": "只能输入 0-9 或 \".\"",
"SoftwareKeyboardModeAlphabet": "仅支持非中文字符", "SoftwareKeyboardModeAlphabet": "仅支持非中文字符",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "安装更新中...", "UpdaterAddingFiles": "安装更新中...",
"UpdaterExtracting": "正在提取更新...", "UpdaterExtracting": "正在提取更新...",
"UpdaterDownloading": "下载更新中...", "UpdaterDownloading": "下载更新中...",
"Game": "游戏",
"Docked": "主机模式", "Docked": "主机模式",
"Handheld": "掌机模式", "Handheld": "掌机模式",
"ConnectionError": "连接错误。", "ConnectionError": "连接错误。",

View File

@ -702,6 +702,9 @@
"Never": "從不", "Never": "從不",
"SwkbdMinCharacters": "長度必須至少為 {0} 個字元", "SwkbdMinCharacters": "長度必須至少為 {0} 個字元",
"SwkbdMinRangeCharacters": "長度必須為 {0} 到 {1} 個字元", "SwkbdMinRangeCharacters": "長度必須為 {0} 到 {1} 個字元",
"CabinetTitle": "Cabinet Dialog",
"CabinetDialog": "Enter your Amiibo's new name",
"CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "軟體鍵盤", "SoftwareKeyboard": "軟體鍵盤",
"SoftwareKeyboardModeNumeric": "必須是 0 到 9 或「.」", "SoftwareKeyboardModeNumeric": "必須是 0 到 9 或「.」",
"SoftwareKeyboardModeAlphabet": "必須是「非中日韓字元」 (non CJK)", "SoftwareKeyboardModeAlphabet": "必須是「非中日韓字元」 (non CJK)",
@ -715,7 +718,6 @@
"UpdaterAddingFiles": "正在加入新檔案...", "UpdaterAddingFiles": "正在加入新檔案...",
"UpdaterExtracting": "正在提取更新...", "UpdaterExtracting": "正在提取更新...",
"UpdaterDownloading": "正在下載更新...", "UpdaterDownloading": "正在下載更新...",
"Game": "遊戲",
"Docked": "底座模式", "Docked": "底座模式",
"Handheld": "手提模式", "Handheld": "手提模式",
"ConnectionError": "連線錯誤。", "ConnectionError": "連線錯誤。",
@ -786,7 +788,7 @@
"CheatWindowHeading": "可用於 {0} [{1}] 的密技", "CheatWindowHeading": "可用於 {0} [{1}] 的密技",
"BuildId": "組建識別碼:", "BuildId": "組建識別碼:",
"DlcWindowBundledContentNotice": "附帶的 DLC 只能被停用而無法被刪除。", "DlcWindowBundledContentNotice": "附帶的 DLC 只能被停用而無法被刪除。",
"DlcWindowHeading": "{0} 個可下載內容", "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "已加入 {0} 個 DLC", "DlcWindowDlcAddedMessage": "已加入 {0} 個 DLC",
"AutoloadDlcAddedMessage": "已加入 {0} 個 DLC", "AutoloadDlcAddedMessage": "已加入 {0} 個 DLC",
"AutoloadDlcRemovedMessage": "已刪除 {0} 個遺失的 DLC", "AutoloadDlcRemovedMessage": "已刪除 {0} 個遺失的 DLC",

View File

@ -4,18 +4,6 @@
<ResourceDictionary x:Key="Default"> <ResourceDictionary x:Key="Default">
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
Color="{DynamicResource DataGridSelectionColor}" /> Color="{DynamicResource DataGridSelectionColor}" />
<SolidColorBrush x:Key="ThemeAccentColorBrush"
Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="ThemeAccentBrush4"
Color="{DynamicResource ThemeAccentColor4}" />
<Color x:Key="SystemAccentColor">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark1">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark2">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark3">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight1">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight2">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight3">#FF00C3E3</Color>
<Color x:Key="ThemeAccentColor4">#FFe8e8e8</Color>
<Color x:Key="DataGridSelectionColor">#FF00FABB</Color> <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
<Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color> <Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color>
<Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color> <Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color>
@ -26,6 +14,7 @@
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color> <Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color> <Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
<Color x:Key="SecondaryTextColor">#A0000000</Color> <Color x:Key="SecondaryTextColor">#A0000000</Color>
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
<Color x:Key="Switch">#FF2EEAC9</Color> <Color x:Key="Switch">#FF2EEAC9</Color>
<Color x:Key="Unbounded">#FFFF4554</Color> <Color x:Key="Unbounded">#FFFF4554</Color>
<Color x:Key="Custom">#6483F5</Color> <Color x:Key="Custom">#6483F5</Color>
@ -33,18 +22,6 @@
<ResourceDictionary x:Key="Light"> <ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
Color="{DynamicResource DataGridSelectionColor}" /> Color="{DynamicResource DataGridSelectionColor}" />
<SolidColorBrush x:Key="ThemeAccentColorBrush"
Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="ThemeAccentBrush4"
Color="{DynamicResource ThemeAccentColor4}" />
<Color x:Key="SystemAccentColor">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark1">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark2">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark3">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight1">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight2">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorLight3">#FF00C3E3</Color>
<Color x:Key="ThemeAccentColor4">#FFe8e8e8</Color>
<Color x:Key="DataGridSelectionColor">#FF00FABB</Color> <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
<Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color> <Color x:Key="ThemeContentBackgroundColor">#FFF0F0F0</Color>
<Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color> <Color x:Key="ThemeControlBorderColor">#FFd6d6d6</Color>
@ -59,18 +36,7 @@
<ResourceDictionary x:Key="Dark"> <ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush" <SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
Color="{DynamicResource DataGridSelectionColor}" /> Color="{DynamicResource DataGridSelectionColor}" />
<SolidColorBrush x:Key="ThemeAccentColorBrush"
Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="ThemeAccentBrush4"
Color="{DynamicResource ThemeAccentColor4}" />
<Color x:Key="ControlFillColorSecondary">#008AA8</Color> <Color x:Key="ControlFillColorSecondary">#008AA8</Color>
<Color x:Key="SystemAccentColor">#FF00C3E3</Color>
<Color x:Key="SystemAccentColorDark1">#FF99b000</Color>
<Color x:Key="SystemAccentColorDark2">#FF006d7d</Color>
<Color x:Key="SystemAccentColorDark3">#FF00525E</Color>
<Color x:Key="SystemAccentColorLight1">#FF00dbff</Color>
<Color x:Key="SystemAccentColorLight2">#FF19dfff</Color>
<Color x:Key="SystemAccentColorLight3">#FF33e3ff</Color>
<Color x:Key="DataGridSelectionColor">#FF00FABB</Color> <Color x:Key="DataGridSelectionColor">#FF00FABB</Color>
<Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color> <Color x:Key="ThemeContentBackgroundColor">#FF2D2D2D</Color>
<Color x:Key="ThemeControlBorderColor">#FF505050</Color> <Color x:Key="ThemeControlBorderColor">#FF505050</Color>

View File

@ -17,13 +17,13 @@ namespace Ryujinx.Ava.Common.Markup
public virtual string Name => "Item"; public virtual string Name => "Item";
public virtual Action<object, T?>? Setter => null; public virtual Action<object, T?>? Setter => null;
protected abstract T? GetValue(); protected abstract T? Value { get; }
protected virtual void ConfigureBindingExtension(CompiledBindingExtension _) { } protected virtual void ConfigureBindingExtension(CompiledBindingExtension _) { }
private ClrPropertyInfo PropertyInfo => private ClrPropertyInfo PropertyInfo =>
new(Name, new(Name,
_ => GetValue(), _ => Value,
Setter as Action<object, object?>, Setter as Action<object, object?>,
typeof(T)); typeof(T));

View File

@ -6,17 +6,17 @@ namespace Ryujinx.Ava.Common.Markup
{ {
internal class IconExtension(string iconString) : BasicMarkupExtension<Icon> internal class IconExtension(string iconString) : BasicMarkupExtension<Icon>
{ {
protected override Icon GetValue() => new() { Value = iconString }; protected override Icon Value => new() { Value = iconString };
} }
internal class SpinningIconExtension(string iconString) : BasicMarkupExtension<Icon> internal class SpinningIconExtension(string iconString) : BasicMarkupExtension<Icon>
{ {
protected override Icon GetValue() => new() { Value = iconString, Animation = IconAnimation.Spin }; protected override Icon Value => new() { Value = iconString, Animation = IconAnimation.Spin };
} }
internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension<string> internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension<string>
{ {
protected override string GetValue() => LocaleManager.Instance[key]; protected override string Value => LocaleManager.Instance[key];
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension) protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
=> bindingExtension.Source = LocaleManager.Instance; => bindingExtension.Source = LocaleManager.Instance;

View File

@ -7,6 +7,7 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types; using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
using Ryujinx.HLE.UI; using Ryujinx.HLE.UI;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
@ -155,6 +156,55 @@ namespace Ryujinx.Ava.UI.Applet
return error || okPressed; return error || okPressed;
} }
public bool DisplayCabinetDialog(out string userText)
{
ManualResetEvent dialogCloseEvent = new(false);
bool okPressed = false;
string inputText = "My Amiibo";
Dispatcher.UIThread.InvokeAsync(async () =>
{
try
{
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
SoftwareKeyboardUIArgs args = new SoftwareKeyboardUIArgs();
args.KeyboardMode = KeyboardMode.Default;
args.InitialText = "Ryujinx";
args.StringLengthMin = 1;
args.StringLengthMax = 25;
(UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.CabinetDialog], args);
if (result == UserResult.Ok)
{
inputText = userInput;
okPressed = true;
}
}
finally
{
dialogCloseEvent.Set();
}
});
dialogCloseEvent.WaitOne();
_parent.ViewModel.AppHost.NpadManager.UnblockInputUpdates();
userText = inputText;
return okPressed;
}
public void DisplayCabinetMessageDialog()
{
ManualResetEvent dialogCloseEvent = new(false);
Dispatcher.UIThread.InvokeAsync(async () =>
{
dialogCloseEvent.Set();
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.CabinetScanDialog],
string.Empty,
LocaleManager.Instance[LocaleKeys.InputDialogOk],
string.Empty,
LocaleManager.Instance[LocaleKeys.CabinetTitle]);
});
dialogCloseEvent.WaitOne();
}
public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value) public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value)
{ {
device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value); device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value);

View File

@ -91,7 +91,7 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
FontSize="16" FontSize="16"
Foreground="{DynamicResource SystemAccentColor}" Foreground="{DynamicResource FavoriteApplicationIconColor}"
IsVisible="{Binding Favorite}" IsVisible="{Binding Favorite}"
Symbol="StarFilled" /> Symbol="StarFilled" />
</Grid> </Grid>

View File

@ -146,7 +146,7 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
FontSize="16" FontSize="16"
Foreground="{DynamicResource SystemAccentColor}" Foreground="{DynamicResource FavoriteApplicationIconColor}"
IsVisible="{Binding Favorite}" IsVisible="{Binding Favorite}"
Symbol="StarFilled" /> Symbol="StarFilled" />
</Grid> </Grid>

View File

@ -10,6 +10,7 @@ using DynamicData;
using DynamicData.Binding; using DynamicData.Binding;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using LibHac.Common; using LibHac.Common;
using LibHac.Ns;
using Ryujinx.Ava.Common; using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input; using Ryujinx.Ava.Input;
@ -70,7 +71,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private string _gpuStatusText; private string _gpuStatusText;
private string _shaderCountText; private string _shaderCountText;
private bool _isAmiiboRequested; private bool _isAmiiboRequested;
private bool _showRightmostSeparator; private bool _showShaderCompilationHint;
private bool _isGameRunning; private bool _isGameRunning;
private bool _isFullScreen; private bool _isFullScreen;
private int _progressMaximum; private int _progressMaximum;
@ -275,12 +276,12 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool ShowFirmwareStatus => !ShowLoadProgress; public bool ShowFirmwareStatus => !ShowLoadProgress;
public bool ShowRightmostSeparator public bool ShowShaderCompilationHint
{ {
get => _showRightmostSeparator; get => _showShaderCompilationHint;
set set
{ {
_showRightmostSeparator = value; _showShaderCompilationHint = value;
OnPropertyChanged(); OnPropertyChanged();
} }
@ -1497,7 +1498,7 @@ namespace Ryujinx.Ava.UI.ViewModels
VolumeStatusText = args.VolumeStatus; VolumeStatusText = args.VolumeStatus;
FifoStatusText = args.FifoStatus; FifoStatusText = args.FifoStatus;
ShaderCountText = (ShowRightmostSeparator = args.ShaderCount > 0) ShaderCountText = (ShowShaderCompilationHint = args.ShaderCount > 0)
? $"{LocaleManager.Instance[LocaleKeys.CompilingShaders]}: {args.ShaderCount}" ? $"{LocaleManager.Instance[LocaleKeys.CompilingShaders]}: {args.ShaderCount}"
: string.Empty; : string.Empty;
@ -1897,7 +1898,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public async Task LoadApplication(ApplicationData application, bool startFullscreen = false) public async Task LoadApplication(ApplicationData application, bool startFullscreen = false, BlitStruct<ApplicationControlProperty>? customNacpData = null)
{ {
if (AppHost != null) if (AppHost != null)
{ {
@ -1935,7 +1936,7 @@ namespace Ryujinx.Ava.UI.ViewModels
this, this,
TopLevel); TopLevel);
if (!await AppHost.LoadGuestApplication()) if (!await AppHost.LoadGuestApplication(customNacpData))
{ {
AppHost.DisposeContext(); AppHost.DisposeContext();
AppHost = null; AppHost = null;

View File

@ -3,7 +3,9 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Threading; using Avalonia.Threading;
using Gommon; using Gommon;
using LibHac.Common;
using LibHac.Ncm; using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
@ -11,6 +13,7 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE;
using Ryujinx.UI.App.Common; using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common; using Ryujinx.UI.Common;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
@ -19,6 +22,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
namespace Ryujinx.Ava.UI.Views.Main namespace Ryujinx.Ava.UI.Views.Main
{ {
@ -123,18 +127,24 @@ namespace Ryujinx.Ava.UI.Views.Main
public async void OpenMiiApplet(object sender, RoutedEventArgs e) public async void OpenMiiApplet(object sender, RoutedEventArgs e)
{ {
string contentPath = ViewModel.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program); const string AppletName = "miiEdit";
const ulong AppletProgramId = 0x0100000000001009;
const string AppletVersion = "1.0.0";
string contentPath = ViewModel.ContentManager.GetInstalledContentPath(AppletProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
if (!string.IsNullOrEmpty(contentPath)) if (!string.IsNullOrEmpty(contentPath))
{ {
ApplicationData applicationData = new() ApplicationData applicationData = new()
{ {
Name = "miiEdit", Name = AppletName,
Id = 0x0100000000001009, Id = AppletProgramId,
Path = contentPath, Path = contentPath
}; };
var nacpData = StructHelpers.CreateCustomNacpData(AppletName, AppletVersion);
await ViewModel.LoadApplication(applicationData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen); await ViewModel.LoadApplication(applicationData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
} }
} }
@ -200,7 +210,6 @@ namespace Ryujinx.Ava.UI.Views.Main
await Dispatcher.UIThread.InvokeAsync(() => await Dispatcher.UIThread.InvokeAsync(() =>
{ {
ViewModel.WindowState = WindowState.Normal; ViewModel.WindowState = WindowState.Normal;
Window.Arrange(new Rect(Window.Position.X, Window.Position.Y, windowWidthScaled, windowHeightScaled)); Window.Arrange(new Rect(Window.Position.X, Window.Position.Y, windowWidthScaled, windowHeightScaled));
@ -210,7 +219,7 @@ namespace Ryujinx.Ava.UI.Views.Main
public async void CheckForUpdates(object sender, RoutedEventArgs e) public async void CheckForUpdates(object sender, RoutedEventArgs e)
{ {
if (Updater.CanUpdate(true)) if (Updater.CanUpdate(true))
await Window.BeginUpdateAsync(true); await Updater.BeginUpdateAsync(true);
} }
public async void OpenXCITrimmerWindow(object sender, RoutedEventArgs e) => await XCITrimmerWindow.Show(ViewModel); public async void OpenXCITrimmerWindow(object sender, RoutedEventArgs e) => await XCITrimmerWindow.Show(ViewModel);

View File

@ -23,7 +23,7 @@
Background="{DynamicResource ThemeContentBackgroundColor}" Background="{DynamicResource ThemeContentBackgroundColor}"
DockPanel.Dock="Bottom" DockPanel.Dock="Bottom"
IsVisible="{Binding ShowMenuAndStatusBar}" IsVisible="{Binding ShowMenuAndStatusBar}"
ColumnDefinitions="Auto,Auto,*,Auto"> ColumnDefinitions="Auto,Auto,*,Auto,Auto">
<StackPanel <StackPanel
Grid.Column="0" Grid.Column="0"
Margin="5" Margin="5"
@ -284,14 +284,27 @@
IsVisible="{Binding !ShowLoadProgress}" IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding FifoStatusText}" Text="{Binding FifoStatusText}"
TextAlignment="Start" /> TextAlignment="Start" />
</StackPanel>
<StackPanel
Grid.Column="3"
Margin="0, 0, 5, 0"
IsVisible="{Binding IsGameRunning}"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
Name="ShaderCount"
Margin="5,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IsVisible="{Binding ShowShaderCompilationHint}"
Text="{Binding ShaderCountText}" />
<Border <Border
Width="2" Width="2"
Height="12" Height="12"
Margin="0" Margin="0"
BorderBrush="Gray" BorderBrush="Gray"
Background="Gray"
BorderThickness="1" BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" /> IsVisible="{Binding ShowShaderCompilationHint}" />
<TextBlock <TextBlock
Margin="5,0,5,0" Margin="5,0,5,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@ -308,35 +321,29 @@
BorderThickness="1" BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" /> IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock <TextBlock
Margin="5,0,5,0" Margin="5,0,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}" IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding GpuNameText}" Text="{Binding GpuNameText}"
TextAlignment="Start" /> TextAlignment="Start" />
</StackPanel>
<StackPanel
Grid.Column="4"
Margin="0,0,5,0"
VerticalAlignment="Center"
IsVisible="{Binding ShowFirmwareStatus}"
Orientation="Horizontal">
<Border <Border
Width="2" Width="2"
Height="12" Height="12"
Margin="0" Margin="0"
BorderBrush="Gray" BorderBrush="Gray"
BorderThickness="1" BorderThickness="1"
IsVisible="{Binding ShowRightmostSeparator}" /> IsVisible="{Binding IsGameRunning}" />
<TextBlock
Name="ShaderCount"
Margin="5,0,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{Binding ShaderCountText}" />
</StackPanel>
<StackPanel
Grid.Column="3"
Margin="0,0,5,0"
VerticalAlignment="Center"
IsVisible="{Binding ShowFirmwareStatus}"
Orientation="Horizontal">
<TextBlock <TextBlock
Name="FirmwareStatus" Name="FirmwareStatus"
Margin="0" Margin="5, 0, 0, 0"
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{ext:Locale StatusBarSystemVersion}" /> Text="{ext:Locale StatusBarSystemVersion}" />

View File

@ -61,23 +61,17 @@ namespace Ryujinx.Ava.UI.Windows
private void RemoveDLC(object sender, RoutedEventArgs e) private void RemoveDLC(object sender, RoutedEventArgs e)
{ {
if (sender is Button button) if (sender is Button { DataContext: DownloadableContentModel dlc })
{ {
if (button.DataContext is DownloadableContentModel model) ViewModel.Remove(dlc);
{
ViewModel.Remove(model);
}
} }
} }
private void OpenLocation(object sender, RoutedEventArgs e) private void OpenLocation(object sender, RoutedEventArgs e)
{ {
if (sender is Button button) if (sender is Button { DataContext: DownloadableContentModel dlc })
{ {
if (button.DataContext is DownloadableContentModel model) OpenHelper.LocateFile(dlc.ContainerPath);
{
OpenHelper.LocateFile(model.ContainerPath);
}
} }
} }

View File

@ -7,6 +7,7 @@ using Avalonia.Threading;
using DynamicData; using DynamicData;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing; using FluentAvalonia.UI.Windowing;
using Gommon;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Common; using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
@ -387,10 +388,8 @@ namespace Ryujinx.Ava.UI.Windows
if (ConfigurationState.Instance.CheckUpdatesOnStart && !CommandLineState.HideAvailableUpdates && Updater.CanUpdate()) if (ConfigurationState.Instance.CheckUpdatesOnStart && !CommandLineState.HideAvailableUpdates && Updater.CanUpdate())
{ {
await this.BeginUpdateAsync() await Updater.BeginUpdateAsync()
.ContinueWith( .Catch(task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"));
task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"),
TaskContinuationOptions.OnlyOnFaulted);
} }
} }

View File

@ -1,4 +1,3 @@
using Avalonia.Controls;
using Avalonia.Threading; using Avalonia.Threading;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Gommon; using Gommon;
@ -51,7 +50,7 @@ namespace Ryujinx.Ava
private static readonly string[] _windowsDependencyDirs = []; private static readonly string[] _windowsDependencyDirs = [];
public static async Task BeginUpdateAsync(this Window mainWindow, bool showVersionUpToDate = false) public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
{ {
if (_running) if (_running)
{ {
@ -225,7 +224,7 @@ namespace Ryujinx.Ava
? $"Canary {currentVersion} -> Canary {newVersion}" ? $"Canary {currentVersion} -> Canary {newVersion}"
: $"{currentVersion} -> {newVersion}"; : $"{currentVersion} -> {newVersion}";
RequestUserToUpdate: RequestUserToUpdate:
// Show a message asking the user if they want to update // Show a message asking the user if they want to update
UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog( UserResult shouldUpdate = await ContentDialogHelper.CreateUpdaterChoiceDialog(
LocaleManager.Instance[LocaleKeys.RyujinxUpdater], LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
@ -235,7 +234,7 @@ namespace Ryujinx.Ava
switch (shouldUpdate) switch (shouldUpdate)
{ {
case UserResult.Yes: case UserResult.Yes:
await UpdateRyujinx(mainWindow, _buildUrl); await UpdateRyujinx(_buildUrl);
break; break;
// Secondary button maps to no, which in this case is the show changelog button. // Secondary button maps to no, which in this case is the show changelog button.
case UserResult.No: case UserResult.No:
@ -258,7 +257,7 @@ namespace Ryujinx.Ava
return result; return result;
} }
private static async Task UpdateRyujinx(Window parent, string downloadUrl) private static async Task UpdateRyujinx(string downloadUrl)
{ {
_updateSuccessful = false; _updateSuccessful = false;
@ -278,7 +277,7 @@ namespace Ryujinx.Ava
SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading], SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading],
IconSource = new SymbolIconSource { Symbol = Symbol.Download }, IconSource = new SymbolIconSource { Symbol = Symbol.Download },
ShowProgressBar = true, ShowProgressBar = true,
XamlRoot = parent, XamlRoot = App.MainWindow,
}; };
taskDialog.Opened += (s, e) => taskDialog.Opened += (s, e) =>