diff --git a/Directory.Packages.props b/Directory.Packages.props
index ffb5f2ead..7059af0e0 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -38,7 +38,7 @@
-
+
diff --git a/distribution/macos/Info.plist b/distribution/macos/Info.plist
index 53929f95e..2602f9905 100644
--- a/distribution/macos/Info.plist
+++ b/distribution/macos/Info.plist
@@ -40,11 +40,11 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.1
+ 1.2
CFBundleSignature
????
CFBundleVersion
- 1.1.0
+ 1.2.0
NSHighResolutionCapable
CSResourcesFileMapped
diff --git a/distribution/macos/updater.sh b/distribution/macos/updater.sh
index 12e4c3aa1..0465d7c91 100755
--- a/distribution/macos/updater.sh
+++ b/distribution/macos/updater.sh
@@ -17,7 +17,7 @@ error_handler() {
set the button_pressed to the button returned of the result
if the button_pressed is \"Open Download Page\" then
- open location \"https://ryujinx.org/download\"
+ open location \"https://ryujinx.app/download\"
end if
"""
@@ -54,4 +54,4 @@ if [ "$#" -le 3 ]; then
open -a "$INSTALL_DIRECTORY"
else
open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
-fi
\ No newline at end of file
+fi
diff --git a/src/ARMeilleure/Instructions/InstEmitSystem.cs b/src/ARMeilleure/Instructions/InstEmitSystem.cs
index fbf3b4a70..11c1d0328 100644
--- a/src/ARMeilleure/Instructions/InstEmitSystem.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSystem.cs
@@ -88,7 +88,7 @@ namespace ARMeilleure.Instructions
EmitSetTpidrEl0(context);
return;
case 0b11_011_1101_0000_101:
- EmitGetTpidr2El0(context);
+ EmitSetTpidr2El0(context);
return;
default:
@@ -291,5 +291,16 @@ namespace ARMeilleure.Instructions
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);
+ }
}
}
diff --git a/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs b/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs
index 608681551..076530744 100644
--- a/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/Controller/JoyconConfigControllerStick.cs
@@ -1,6 +1,8 @@
namespace Ryujinx.Common.Configuration.Hid.Controller
{
- public class JoyconConfigControllerStick where TButton : unmanaged where TStick : unmanaged
+ public class JoyconConfigControllerStick
+ where TButton : unmanaged
+ where TStick : unmanaged
{
public TStick Joystick { get; set; }
public bool InvertStickX { get; set; }
diff --git a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs
index da4d2e51b..5895c67bb 100644
--- a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs
@@ -1,5 +1,6 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Applets.Browser;
+using Ryujinx.HLE.HOS.Applets.Cabinet;
using Ryujinx.HLE.HOS.Applets.Dummy;
using Ryujinx.HLE.HOS.Applets.Error;
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
@@ -23,14 +24,14 @@ namespace Ryujinx.HLE.HOS.Applets
case AppletId.SoftwareKeyboard:
return new SoftwareKeyboardApplet(system);
case AppletId.LibAppletWeb:
- return new BrowserApplet(system);
case AppletId.LibAppletShop:
- return new BrowserApplet(system);
case AppletId.LibAppletOff:
- return new BrowserApplet(system);
+ return new BrowserApplet();
case AppletId.MiiEdit:
Logger.Warning?.Print(LogClass.Application, $"Please use the MiiEdit inside File/Open Applet");
return new DummyApplet(system);
+ case AppletId.Cabinet:
+ return new CabinetApplet(system);
}
Logger.Warning?.Print(LogClass.Application, $"Applet {applet} not implemented!");
diff --git a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs
index 6afbe4a72..c5f13dab3 100644
--- a/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/Browser/BrowserApplet.cs
@@ -18,13 +18,6 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
private List _arguments;
private ShimKind _shimKind;
- public BrowserApplet(Horizon system) { }
-
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
-
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{
_normalSession = normalSession;
diff --git a/src/Ryujinx.HLE/HOS/Applets/Cabinet/CabinetApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Cabinet/CabinetApplet.cs
new file mode 100644
index 000000000..294b8d1f6
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Applets/Cabinet/CabinetApplet.cs
@@ -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(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 nickName = new Array41();
+ 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();
+ 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
+ }
+}
diff --git a/src/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs
index 5ec9d4b08..3a7b29ab5 100644
--- a/src/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/Controller/ControllerApplet.cs
@@ -117,11 +117,6 @@ namespace Ryujinx.HLE.HOS.Applets
return ResultCode.Success;
}
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
-
private static byte[] BuildResponse(ControllerSupportResultInfo result)
{
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
diff --git a/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs
index 75df7a373..6b16aee7b 100644
--- a/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs
@@ -11,11 +11,14 @@ namespace Ryujinx.HLE.HOS.Applets.Dummy
{
private readonly Horizon _system;
private AppletSession _normalSession;
+
public event EventHandler AppletStateChanged;
+
public DummyApplet(Horizon system)
{
_system = system;
}
+
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{
_normalSession = normalSession;
@@ -24,10 +27,7 @@ namespace Ryujinx.HLE.HOS.Applets.Dummy
_system.ReturnFocus();
return ResultCode.Success;
}
- private static T ReadStruct(byte[] data) where T : struct
- {
- return MemoryMarshal.Read(data.AsSpan());
- }
+
private static byte[] BuildResponse()
{
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
@@ -35,9 +35,5 @@ namespace Ryujinx.HLE.HOS.Applets.Dummy
writer.Write((ulong)ResultCode.Success);
return stream.ToArray();
}
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
}
}
diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
index 87d88fc65..0e043cc45 100644
--- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
@@ -203,10 +203,5 @@ namespace Ryujinx.HLE.HOS.Applets.Error
_horizon.Device.UIHandler.DisplayErrorAppletDialog($"Error Number: {applicationErrorArg.ErrorNumber} (Details)", "\n" + detailsText, buttons.ToArray());
}
}
-
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
}
}
diff --git a/src/Ryujinx.HLE/HOS/Applets/IApplet.cs b/src/Ryujinx.HLE/HOS/Applets/IApplet.cs
index bc5353841..4500b2f63 100644
--- a/src/Ryujinx.HLE/HOS/Applets/IApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/IApplet.cs
@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Applets
ResultCode Start(AppletSession normalSession,
AppletSession interactiveSession);
- ResultCode GetResult();
+ ResultCode GetResult() => ResultCode.Success;
bool DrawTo(RenderingSurfaceInfo surfaceInfo, IVirtualMemoryManager destination, ulong position) => false;
diff --git a/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs b/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs
index ccc761ba1..05bddc76f 100644
--- a/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/PlayerSelect/PlayerSelectApplet.cs
@@ -37,11 +37,6 @@ namespace Ryujinx.HLE.HOS.Applets
return ResultCode.Success;
}
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
-
private byte[] BuildResponse()
{
UserProfile currentUser = _system.AccountManager.LastOpenedUser;
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
index e04fc64fe..9ec202357 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
@@ -144,11 +144,6 @@ namespace Ryujinx.HLE.HOS.Applets
}
}
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
-
private bool IsKeyboardActive()
{
return _backgroundState >= InlineKeyboardState.Appearing && _backgroundState < InlineKeyboardState.Disappearing;
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs
index 32d9e68da..51571401f 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs
@@ -2,7 +2,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{
///
/// 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.
///
/// The internal type.
class TRef
diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs
index d48a88978..8f9f0e3e4 100644
--- a/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Ldn/Lp2p/ISfService.cs
@@ -24,6 +24,15 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
return ResultCode.Success;
}
+ [CommandCmif(776)]
+ // DestroyGroup()
+ public ResultCode DestroyGroup(ServiceCtx context)
+ {
+ Logger.Stub?.PrintStub(LogClass.ServiceLdn);
+
+ return ResultCode.Success;
+ }
+
[CommandCmif(1536)]
// SendToOtherGroup(nn::lp2p::MacAddress, nn::lp2p::GroupId, s16, s16, u32, buffer)
public ResultCode SendToOtherGroup(ServiceCtx context)
diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/Proxy/P2pProxyServer.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/Proxy/P2pProxyServer.cs
index 598fb654f..fbce5c10c 100644
--- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/Proxy/P2pProxyServer.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/Proxy/P2pProxyServer.cs
@@ -1,3 +1,5 @@
+using Gommon;
+using Humanizer;
using NetCoreServer;
using Open.Nat;
using Ryujinx.Common.Logging;
@@ -153,7 +155,10 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy
if (_publicPort != 0)
{
- _ = Task.Delay(PortLeaseRenew * 1000, _disposedCancellation.Token).ContinueWith((task) => Task.Run(RefreshLease));
+ _ = Executor.ExecuteAfterDelayAsync(
+ PortLeaseRenew.Seconds(),
+ _disposedCancellation.Token,
+ RefreshLease);
}
_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)
diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs
index 7ce749d1a..0c685471c 100644
--- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs
@@ -93,6 +93,13 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
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)
{
VirtualAmiiboFile virtualAmiiboFile = LoadAmiiboFile(amiiboId);
diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs
index 2928ac7fe..361a9159e 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs
@@ -26,7 +26,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
{
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? customNacpData = null)
{
// Extract RomFs and ExeFs from NCA.
IStorage romFs = nca.GetRomFs(device, patchNca);
@@ -55,6 +55,10 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
{
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)customNacpData;
+ }
/* TODO: Rework this since it's wrong and doesn't work as it takes the DisplayVersion from a "potential" non-existent update.
diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs
index a0e7e0fa1..fe8360f04 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs
@@ -98,12 +98,12 @@ namespace Ryujinx.HLE.Loaders.Processes
return false;
}
- public bool LoadNca(string path)
+ public bool LoadNca(string path, BlitStruct? customNacpData = null)
{
FileStream file = new(path, FileMode.Open, FileAccess.Read);
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))
{
diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
index e187b2360..3a7042670 100644
--- a/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
+++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
@@ -84,12 +84,19 @@ namespace Ryujinx.HLE.Loaders.Processes
return false;
}
+ bool isFirmware = ProgramId is >= 0x0100000000000819 and <= 0x010000000000081C;
+ bool isFirmwareApplication = ProgramId <= 0x0100000000007FFF;
+
+ string name = !isFirmware
+ ? (isFirmwareApplication ? "Firmware Application " : "") + (!string.IsNullOrWhiteSpace(Name) ? Name : "")
+ : "Firmware";
+
// TODO: LibHac npdm currently doesn't support version field.
- string version = ProgramId > 0x0100000000007FFF
- ? DisplayVersion
+ string version = !isFirmware
+ ? (!string.IsNullOrWhiteSpace(DisplayVersion) ? DisplayVersion : "")
: 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;
}
diff --git a/src/Ryujinx.HLE/StructHelpers.cs b/src/Ryujinx.HLE/StructHelpers.cs
new file mode 100644
index 000000000..6e6af8cea
--- /dev/null
+++ b/src/Ryujinx.HLE/StructHelpers.cs
@@ -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 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(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;
+ }
+ }
+}
diff --git a/src/Ryujinx.HLE/Switch.cs b/src/Ryujinx.HLE/Switch.cs
index 466352152..d0afdf173 100644
--- a/src/Ryujinx.HLE/Switch.cs
+++ b/src/Ryujinx.HLE/Switch.cs
@@ -1,3 +1,5 @@
+using LibHac.Common;
+using LibHac.Ns;
using Ryujinx.Audio.Backends.CompatLayer;
using Ryujinx.Audio.Integration;
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 LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId);
- public bool LoadNca(string ncaFile) => Processes.LoadNca(ncaFile);
+ public bool LoadNca(string ncaFile, BlitStruct? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData);
public bool LoadNsp(string nspFile, ulong applicationId = 0) => Processes.LoadNsp(nspFile, applicationId);
public bool LoadProgram(string fileName) => Processes.LoadNxo(fileName);
diff --git a/src/Ryujinx.HLE/UI/IHostUIHandler.cs b/src/Ryujinx.HLE/UI/IHostUIHandler.cs
index 8debfcca0..88af83735 100644
--- a/src/Ryujinx.HLE/UI/IHostUIHandler.cs
+++ b/src/Ryujinx.HLE/UI/IHostUIHandler.cs
@@ -24,6 +24,18 @@ namespace Ryujinx.HLE.UI
/// True when OK is pressed, False otherwise.
bool DisplayMessageDialog(ControllerAppletUIArgs args);
+ ///
+ /// Displays an Input Dialog box to the user so they can enter the Amiibo's new name
+ ///
+ /// Text that the user entered. Set to `null` on internal errors
+ /// True when OK is pressed, False otherwise. Also returns True on internal errors
+ bool DisplayCabinetDialog(out string userText);
+
+ ///
+ /// Displays a Message Dialog box to the user to notify them to scan the Amiibo.
+ ///
+ void DisplayCabinetMessageDialog();
+
///
/// Tell the UI that we need to transition to another program.
///
diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs
index ff87a3845..12158176a 100644
--- a/src/Ryujinx.Headless.SDL2/Program.cs
+++ b/src/Ryujinx.Headless.SDL2/Program.cs
@@ -1,4 +1,5 @@
using CommandLine;
+using Gommon;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Common;
@@ -96,8 +97,13 @@ namespace Ryujinx.Headless.SDL2
}
Parser.Default.ParseArguments(args)
- .WithParsed(Load)
- .WithNotParsed(errors => errors.Output());
+ .WithParsed(Load)
+ .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)
@@ -579,8 +585,8 @@ namespace Ryujinx.Headless.SDL2
options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
false,
- "",
- "",
+ string.Empty,
+ string.Empty,
options.CustomVSyncInterval);
return new Switch(configuration);
diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs
index 2479ec127..fbe7cb49c 100644
--- a/src/Ryujinx.Headless.SDL2/WindowBase.cs
+++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs
@@ -1,4 +1,5 @@
using Humanizer;
+using LibHac.Tools.Fs;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
@@ -485,6 +486,19 @@ namespace Ryujinx.Headless.SDL2
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)
{
if (_ignoreControllerApplet) return false;
diff --git a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
index 174db51ad..cb6467f5e 100644
--- a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
+++ b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
@@ -1,5 +1,4 @@
using DynamicData;
-using DynamicData.Kernel;
using Gommon;
using LibHac;
using LibHac.Common;
@@ -37,14 +36,13 @@ using System.Threading.Tasks;
using ContentType = LibHac.Ncm.ContentType;
using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
using Path = System.IO.Path;
-using SpanHelpers = LibHac.Common.SpanHelpers;
using TimeSpan = System.TimeSpan;
namespace Ryujinx.UI.App.Common
{
public class ApplicationLibrary
{
- public static string DefaultLanPlayWebHost = "ryuldnweb.vudjun.com";
+ public const string DefaultLanPlayWebHost = "ryuldnweb.vudjun.com";
public Language DesiredLanguage { get; set; }
public event EventHandler ApplicationCountUpdated;
public event EventHandler LdnGameDataReceived;
@@ -191,12 +189,9 @@ namespace Ryujinx.UI.App.Common
}
}
- if (isExeFs)
- {
- return GetApplicationFromExeFs(pfs, filePath);
- }
-
- return null;
+ return isExeFs
+ ? GetApplicationFromExeFs(pfs, filePath)
+ : null;
}
/// The configured key set is missing a key.
@@ -512,10 +507,6 @@ namespace Ryujinx.UI.App.Common
case ".xci":
case ".nsp":
{
- IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
- ? IntegrityCheckLevel.ErrorOnInvalid
- : IntegrityCheckLevel.None;
-
using IFileSystem pfs = PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
@@ -604,7 +595,7 @@ namespace Ryujinx.UI.App.Common
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None)
.OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read)
.ThrowIfFailure();
- nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData),
+ nacpFile.Get.Read(out _, 0, LibHac.Common.SpanHelpers.AsByteSpan(ref controlData),
ReadOption.None).ThrowIfFailure();
var displayVersion = controlData.DisplayVersionString.ToString();
@@ -827,7 +818,7 @@ namespace Ryujinx.UI.App.Common
{
_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.AddOrUpdate(dlcs);
@@ -839,7 +830,7 @@ namespace Ryujinx.UI.App.Common
{
_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.AddOrUpdate(updates);
@@ -1088,14 +1079,15 @@ namespace Ryujinx.UI.App.Common
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);
- var shouldSelect = !currentlySelected.HasValue ||
- currentlySelected.Value.TitleUpdate.Version < update.Version;
+ var shouldSelect = currentlySelected.Check(curr => curr.TitleUpdate?.Version < update.Version);
_titleUpdates.AddOrUpdate((update, shouldSelect));
-
+
if (currentlySelected.HasValue && shouldSelect)
{
_titleUpdates.AddOrUpdate((currentlySelected.Value.TitleUpdate, false));
@@ -1464,7 +1456,7 @@ namespace Ryujinx.UI.App.Common
if (addedNewDlc)
{
var gameDlcs = it.Items.Where(dlc => dlc.Dlc.TitleIdBase == application.IdBase).ToList();
- DownloadableContentsHelper.SaveDownloadableContentsJson(_virtualFileSystem, application.IdBase,
+ DownloadableContentsHelper.SaveDownloadableContentsJson(application.IdBase,
gameDlcs);
}
}
@@ -1483,11 +1475,11 @@ namespace Ryujinx.UI.App.Common
TitleUpdatesHelper.LoadTitleUpdatesJson(_virtualFileSystem, application.IdBase);
it.AddOrUpdate(savedUpdates);
- var selectedUpdate = savedUpdates.FirstOrOptional(update => update.IsSelected);
+ var selectedUpdate = savedUpdates.FindFirst(update => update.IsSelected);
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;
foreach (var update in bundledUpdates.OrderByDescending(bundled => bundled.Version))
@@ -1495,12 +1487,11 @@ namespace Ryujinx.UI.App.Common
if (!savedUpdateLookup.Contains(update))
{
bool shouldSelect = false;
- if (!selectedUpdate.HasValue || selectedUpdate.Value.Item1.Version < update.Version)
+ if (selectedUpdate.Check(su => su.Update?.Version < update.Version))
{
shouldSelect = true;
- if (selectedUpdate.HasValue)
- _titleUpdates.AddOrUpdate((selectedUpdate.Value.Item1, false));
- selectedUpdate = DynamicData.Kernel.Optional<(TitleUpdateModel, bool IsSelected)>.Create((update, true));
+ _titleUpdates.AddOrUpdate((selectedUpdate.Value.Update, false));
+ selectedUpdate = (update, true);
}
modifiedVersion = modifiedVersion || shouldSelect;
@@ -1513,7 +1504,7 @@ namespace Ryujinx.UI.App.Common
if (updatesChanged)
{
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)
{
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
private void SaveTitleUpdatesForGame(ulong titleIdBase)
{
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
diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
index badb047df..04ddd442f 100644
--- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
@@ -1,16 +1,12 @@
-using ARMeilleure;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Configuration.Multiplayer;
-using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Configuration.UI;
using System;
-using System.Collections.Generic;
namespace Ryujinx.UI.Common.Configuration
{
@@ -21,10 +17,10 @@ namespace Ryujinx.UI.Common.Configuration
if (Instance != null)
{
throw new InvalidOperationException("Configuration is already initialized");
- }
+ }
Instance = new ConfigurationState();
- }
+ }
public ConfigurationFileFormat ToFileFormat()
{
diff --git a/src/Ryujinx.UI.Common/Helper/ConsoleHelper.cs b/src/Ryujinx.UI.Common/Helper/ConsoleHelper.cs
index 623952b37..99b209c6e 100644
--- a/src/Ryujinx.UI.Common/Helper/ConsoleHelper.cs
+++ b/src/Ryujinx.UI.Common/Helper/ConsoleHelper.cs
@@ -7,6 +7,24 @@ namespace Ryujinx.UI.Common.Helper
{
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 void SetConsoleWindowState(bool show)
@@ -35,16 +53,11 @@ namespace Ryujinx.UI.Common.Helper
return;
}
+ SetForegroundWindow(hWnd);
+
+ hWnd = GetForegroundWindow();
+
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);
}
}
diff --git a/src/Ryujinx.UI.Common/Helper/DownloadableContentsHelper.cs b/src/Ryujinx.UI.Common/Helper/DownloadableContentsHelper.cs
index 3695c5c5c..020529b55 100644
--- a/src/Ryujinx.UI.Common/Helper/DownloadableContentsHelper.cs
+++ b/src/Ryujinx.UI.Common/Helper/DownloadableContentsHelper.cs
@@ -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;
List downloadableContentContainerList = new();
diff --git a/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs b/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs
index 18fbabd6d..36de8b31a 100644
--- a/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs
+++ b/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs
@@ -28,7 +28,7 @@ namespace Ryujinx.UI.Common.Helper
{
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);
@@ -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
{
@@ -77,7 +77,7 @@ namespace Ryujinx.UI.Common.Helper
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)>();
diff --git a/src/Ryujinx/App.axaml b/src/Ryujinx/App.axaml
index 5a603509c..5c96f97f2 100644
--- a/src/Ryujinx/App.axaml
+++ b/src/Ryujinx/App.axaml
@@ -11,7 +11,7 @@
-
+
diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs
index 5789737d6..65c798ac2 100644
--- a/src/Ryujinx/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
@@ -3,6 +3,8 @@ using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input;
using Avalonia.Threading;
+using LibHac.Common;
+using LibHac.Ns;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.Audio.Backends.OpenAL;
@@ -670,7 +672,7 @@ namespace Ryujinx.Ava
_cursorState = CursorStates.ForceChangeCursor;
}
- public async Task LoadGuestApplication()
+ public async Task LoadGuestApplication(BlitStruct? customNacpData = null)
{
InitializeSwitchInstance();
MainWindow.UpdateGraphicsConfig();
@@ -740,7 +742,7 @@ namespace Ryujinx.Ava
{
Logger.Info?.Print(LogClass.Application, "Loading as Firmware Title (NCA).");
- if (!Device.LoadNca(ApplicationPath))
+ if (!Device.LoadNca(ApplicationPath, customNacpData))
{
Device.Dispose();
@@ -1137,7 +1139,7 @@ namespace Ryujinx.Ava
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
dockedMode,
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} %",
_displayCount));
}
diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json
index 34b4f7212..bdb6a92ec 100644
--- a/src/Ryujinx/Assets/Locales/ar_SA.json
+++ b/src/Ryujinx/Assets/Locales/ar_SA.json
@@ -702,6 +702,9 @@
"Never": "مطلقا",
"SwkbdMinCharacters": "يجب أن يبلغ طوله {0} حرفا على الأقل",
"SwkbdMinRangeCharacters": "يجب أن يتكون من {0}-{1} حرفا",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "لوحة المفاتيح البرمجية",
"SoftwareKeyboardModeNumeric": "يجب أن يكون 0-9 أو '.' فقط",
"SoftwareKeyboardModeAlphabet": "يجب أن تكون الأحرف غير CJK فقط",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "إضافة ملفات جديدة...",
"UpdaterExtracting": "استخراج التحديث...",
"UpdaterDownloading": "تحميل التحديث...",
- "Game": "لعبة",
"Docked": "تركيب بالمنصة",
"Handheld": "محمول",
"ConnectionError": "خطأ في الاتصال",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "الغش متوفر لـ {0} [{1}]",
"BuildId": "معرف البناء:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
- "DlcWindowHeading": "المحتويات القابلة للتنزيل {0}",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json
index 013120738..9f4b63a95 100644
--- a/src/Ryujinx/Assets/Locales/de_DE.json
+++ b/src/Ryujinx/Assets/Locales/de_DE.json
@@ -702,6 +702,9 @@
"Never": "Niemals",
"SwkbdMinCharacters": "Muss mindestens {0} 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",
"SoftwareKeyboardModeNumeric": "Darf nur 0-9 oder \".\" sein",
"SoftwareKeyboardModeAlphabet": "Keine CJK-Zeichen",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Neue Dateien hinzufügen...",
"UpdaterExtracting": "Update extrahieren...",
"UpdaterDownloading": "Update herunterladen...",
- "Game": "Spiel",
"Docked": "Docked",
"Handheld": "Handheld",
"ConnectionError": "Verbindungsfehler.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Cheats verfügbar für {0} [{1}]",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
"BuildId": "BuildId:",
- "DlcWindowHeading": "DLC verfügbar für {0} [{1}]",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json
index c5d6a60e6..7979b9228 100644
--- a/src/Ryujinx/Assets/Locales/el_GR.json
+++ b/src/Ryujinx/Assets/Locales/el_GR.json
@@ -702,6 +702,9 @@
"Never": "Ποτέ",
"SwkbdMinCharacters": "Πρέπει να έχει μήκος τουλάχιστον {0} χαρακτήρες",
"SwkbdMinRangeCharacters": "Πρέπει να έχει μήκος {0}-{1} χαρακτήρες",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Εικονικό Πληκτρολόγιο",
"SoftwareKeyboardModeNumeric": "Πρέπει να είναι 0-9 ή '.' μόνο",
"SoftwareKeyboardModeAlphabet": "Πρέπει να μην είναι μόνο χαρακτήρες CJK",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Προσθήκη Νέων Αρχείων...",
"UpdaterExtracting": "Εξαγωγή Ενημέρωσης...",
"UpdaterDownloading": "Λήψη Ενημέρωσης...",
- "Game": "Παιχνίδι",
"Docked": "Προσκολλημένο",
"Handheld": "Χειροκίνητο",
"ConnectionError": "Σφάλμα Σύνδεσης.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Διαθέσιμα Cheats για {0} [{1}]",
"BuildId": "BuildId:",
"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",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json
index b7ab8969b..0598665fd 100644
--- a/src/Ryujinx/Assets/Locales/en_US.json
+++ b/src/Ryujinx/Assets/Locales/en_US.json
@@ -714,6 +714,9 @@
"Never": "Never",
"SwkbdMinCharacters": "Must be at least {0} 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",
"SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only",
"SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
@@ -727,7 +730,6 @@
"UpdaterAddingFiles": "Adding New Files...",
"UpdaterExtracting": "Extracting Update...",
"UpdaterDownloading": "Downloading Update...",
- "Game": "Game",
"Docked": "Docked",
"Handheld": "Handheld",
"ConnectionError": "Connection Error.",
@@ -800,7 +802,7 @@
"CheatWindowHeading": "Cheats Available for {0} [{1}]",
"BuildId": "BuildId:",
"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",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json
index 730bd7961..3774605f6 100644
--- a/src/Ryujinx/Assets/Locales/es_ES.json
+++ b/src/Ryujinx/Assets/Locales/es_ES.json
@@ -1,7 +1,7 @@
{
"Language": "Español (ES)",
"MenuBarFileOpenApplet": "Abrir applet",
- "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Applet Editor Mii",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Abre el editor de Mii en modo autónomo",
"SettingsTabInputDirectMouseAccess": "Acceso directo al ratón",
"SettingsTabSystemMemoryManagerMode": "Modo del administrador de memoria:",
@@ -32,12 +32,12 @@
"MenuBarFileToolsInstallFirmwareFromFile": "Instalar firmware desde un archivo XCI o ZIP",
"MenuBarFileToolsInstallFirmwareFromDirectory": "Instalar firmware desde una carpeta",
"MenuBarToolsInstallKeys": "Install Keys",
- "MenuBarFileToolsInstallKeysFromFile": "Install keys from KEYS or ZIP",
- "MenuBarFileToolsInstallKeysFromFolder": "Install keys from a directory",
+ "MenuBarFileToolsInstallKeysFromFile": "Instalar keys de KEYS o ZIP",
+ "MenuBarFileToolsInstallKeysFromFolder": "Instalar keys de un directorio",
"MenuBarToolsManageFileTypes": "Administrar tipos de archivo",
"MenuBarToolsInstallFileTypes": "Instalar tipos de archivo",
"MenuBarToolsUninstallFileTypes": "Desinstalar tipos de archivo",
- "MenuBarToolsXCITrimmer": "Trim XCI Files",
+ "MenuBarToolsXCITrimmer": "Recortar archivos XCI",
"MenuBarView": "_View",
"MenuBarViewWindow": "Tamaño Ventana",
"MenuBarViewWindow720": "720p",
@@ -89,11 +89,11 @@
"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",
"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",
- "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
+ "GameListContextMenuTrimXCI": "Verificar y recortar archivo XCI",
+ "GameListContextMenuTrimXCIToolTip": "Verificar y recortar archivo XCI para ahorrar espacio en disco",
"StatusBarGamesLoaded": "{0}/{1} juegos cargados",
"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",
"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.",
@@ -480,7 +480,7 @@
"DialogUninstallFileTypesSuccessMessage": "¡Tipos de archivos desinstalados con éxito!",
"DialogUninstallFileTypesErrorMessage": "No se pudo desinstalar los tipos de archivo.",
"DialogOpenSettingsWindowLabel": "Abrir ventana de opciones",
- "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window",
+ "DialogOpenXCITrimmerWindowLabel": "Ventana recortador XCI",
"DialogControllerAppletTitle": "Applet de mandos",
"DialogMessageDialogErrorExceptionMessage": "Error al mostrar cuadro de diálogo: {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "Error al mostrar teclado de software: {0}",
@@ -509,13 +509,13 @@
"DialogFirmwareInstallerFirmwareInstallConfirmMessage": "\n\n¿Continuar?",
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Instalando firmware...",
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Versión de sistema {0} instalada con éxito.",
- "DialogKeysInstallerKeysNotFoundErrorMessage": "An invalid Keys file was found in {0}",
- "DialogKeysInstallerKeysInstallTitle": "Install Keys",
- "DialogKeysInstallerKeysInstallMessage": "New Keys file will be installed.",
- "DialogKeysInstallerKeysInstallSubMessage": "\n\nThis may replace some of the current installed Keys.",
- "DialogKeysInstallerKeysInstallConfirmMessage": "\n\nDo you want to continue?",
- "DialogKeysInstallerKeysInstallWaitMessage": "Installing Keys...",
- "DialogKeysInstallerKeysInstallSuccessMessage": "New Keys file successfully installed.",
+ "DialogKeysInstallerKeysNotFoundErrorMessage": "Se halló un archivo Keys inválido en {0}",
+ "DialogKeysInstallerKeysInstallTitle": "Instalar Keys",
+ "DialogKeysInstallerKeysInstallMessage": "Un nuevo archivo Keys será instalado.",
+ "DialogKeysInstallerKeysInstallSubMessage": "\n\nEsto puede reemplazar algunas de las Keys actualmente instaladas.",
+ "DialogKeysInstallerKeysInstallConfirmMessage": "\n\nDeseas continuar?",
+ "DialogKeysInstallerKeysInstallWaitMessage": "Instalando Keys...",
+ "DialogKeysInstallerKeysInstallSuccessMessage": "Nuevo archivo Keys instalado con éxito.",
"DialogUserProfileDeletionWarningMessage": "Si eliminas el perfil seleccionado no quedará ningún otro perfil",
"DialogUserProfileDeletionConfirmMessage": "¿Quieres eliminar el perfil seleccionado?",
"DialogUserProfileUnsavedChangesTitle": "Advertencia - Cambios sin guardar",
@@ -688,20 +688,23 @@
"OpenSetupGuideMessage": "Abrir la guía de instalación",
"NoUpdate": "No actualizado",
"TitleUpdateVersionLabel": "Versión {0} - {1}",
- "TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
- "TitleBundledDlcLabel": "Bundled:",
- "TitleXCIStatusPartialLabel": "Partial",
- "TitleXCIStatusTrimmableLabel": "Untrimmed",
- "TitleXCIStatusUntrimmableLabel": "Trimmed",
- "TitleXCIStatusFailedLabel": "(Failed)",
- "TitleXCICanSaveLabel": "Save {0:n0} Mb",
- "TitleXCISavingLabel": "Saved {0:n0} Mb",
+ "TitleBundledUpdateVersionLabel": "Incorporado: Versión {0}",
+ "TitleBundledDlcLabel": "Incorporado:",
+ "TitleXCIStatusPartialLabel": "Parcial",
+ "TitleXCIStatusTrimmableLabel": "Sin recortar",
+ "TitleXCIStatusUntrimmableLabel": "Recortado",
+ "TitleXCIStatusFailedLabel": "(Fallido)",
+ "TitleXCICanSaveLabel": "Ahorra {0:n0} Mb",
+ "TitleXCISavingLabel": "{0:n0} Mb ahorrado(s)",
"RyujinxInfo": "Ryujinx - Info",
"RyujinxConfirm": "Ryujinx - Confirmación",
"FileDialogAllTypes": "Todos los tipos",
"Never": "Nunca",
"SwkbdMinCharacters": "Debe tener al menos {0} 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",
"SoftwareKeyboardModeNumeric": "Debe ser sólo 0-9 o '.'",
"SoftwareKeyboardModeAlphabet": "Solo deben ser caracteres no CJK",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Añadiendo nuevos archivos...",
"UpdaterExtracting": "Extrayendo actualización...",
"UpdaterDownloading": "Descargando actualización...",
- "Game": "Juego",
"Docked": "Dock/TV",
"Handheld": "Portátil",
"ConnectionError": "Error de conexión.",
@@ -748,44 +750,44 @@
"SelectDlcDialogTitle": "Selecciona archivo(s) de DLC",
"SelectUpdateDialogTitle": "Selecciona archivo(s) de actualización",
"SelectModDialogTitle": "Seleccionar un directorio de Mods",
- "TrimXCIFileDialogTitle": "Check and Trim XCI File",
- "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
- "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
- "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
- "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
- "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
- "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
- "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
- "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
- "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
- "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
- "TrimXCIFileCancelled": "The operation was cancelled",
- "TrimXCIFileFileUndertermined": "No operation was performed",
+ "TrimXCIFileDialogTitle": "Verificar y recortar archivo XCI",
+ "TrimXCIFileDialogPrimaryText": "Esta función verificará el espacio vacío y después recortará el archivo XCI para ahorrar espacio en disco",
+ "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": "El archivo XCI no necesita ser recortado. Verifica los logs para más detalles.",
+ "TrimXCIFileNoUntrimPossible": "El recorte del archivo XCI no puede ser deshecho. Verifica los registros para más detalles.",
+ "TrimXCIFileReadOnlyFileCannotFix": "El archivo XCI es de solo Lectura y no se le puede escribir. Lee el registro para más información.",
+ "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": "El archivo XCI tiene datos en el área de espacio libre, no es seguro recortar.",
+ "TrimXCIFileInvalidXCIFile": "El archivo XCI contiene datos inválidos. Lee el registro para más información.",
+ "TrimXCIFileFileIOWriteError": "El archivo XCI no se puede abrir para escribirlo. Lee el registro para más información.",
+ "TrimXCIFileFailedPrimaryText": "El recorte del archivo XCI falló",
+ "TrimXCIFileCancelled": "La operación fue cancelada",
+ "TrimXCIFileFileUndertermined": "No se realizó ninguna operación",
"UserProfileWindowTitle": "Administrar perfiles de usuario",
"CheatWindowTitle": "Administrar cheats",
"DlcWindowTitle": "Administrar contenido descargable",
"ModWindowTitle": "Administrar Mods para {0} ({1})",
"UpdateWindowTitle": "Administrar actualizaciones",
- "XCITrimmerWindowTitle": "XCI File Trimmer",
- "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
- "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
- "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
- "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
- "XCITrimmerTitleStatusFailed": "Failed",
- "XCITrimmerPotentialSavings": "Potential Savings",
- "XCITrimmerActualSavings": "Actual Savings",
+ "XCITrimmerWindowTitle": "Recortador de archivos XCI",
+ "XCITrimmerTitleStatusCount": "{0} de {1} Título(s) seleccionado(s)",
+ "XCITrimmerTitleStatusCountWithFilter": "{0} de {1} Título(s) seleccionado(s) ({2} mostrado(s))",
+ "XCITrimmerTitleStatusTrimming": "Recortando {0} Título(s)...",
+ "XCITrimmerTitleStatusUntrimming": "Deshaciendo recorte de {0} Título(s)...",
+ "XCITrimmerTitleStatusFailed": "Fallido",
+ "XCITrimmerPotentialSavings": "Ahorro potencial",
+ "XCITrimmerActualSavings": "Ahorro real",
"XCITrimmerSavingsMb": "{0:n0} Mb",
- "XCITrimmerSelectDisplayed": "Select Shown",
- "XCITrimmerDeselectDisplayed": "Deselect Shown",
- "XCITrimmerSortName": "Title",
- "XCITrimmerSortSaved": "Space Savings",
- "XCITrimmerTrim": "Trim",
- "XCITrimmerUntrim": "Untrim",
+ "XCITrimmerSelectDisplayed": "Seleccionar mostrado(s)",
+ "XCITrimmerDeselectDisplayed": "Deseleccionar mostrado(s)",
+ "XCITrimmerSortName": "Título",
+ "XCITrimmerSortSaved": "Ahorro de espacio",
+ "XCITrimmerTrim": "Recortar",
+ "XCITrimmerUntrim": "Deshacer recorte",
"UpdateWindowUpdateAddedMessage": "{0} nueva(s) actualización(es) agregada(s)",
"UpdateWindowBundledContentNotice": "Las actualizaciones agrupadas no pueden ser eliminadas, solamente deshabilitadas.",
"CheatWindowHeading": "Cheats disponibles para {0} [{1}]",
"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)",
"AutoloadDlcAddedMessage": "Se agregaron {0} nuevo(s) contenido(s) descargable(s)",
"AutoloadDlcRemovedMessage": "Se eliminaron {0} contenido(s) descargable(s) faltantes",
@@ -793,7 +795,7 @@
"AutoloadUpdateRemovedMessage": "Se eliminaron {0} actualización(es) faltantes",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Editar selección",
- "Continue": "Continue",
+ "Continue": "Continuar",
"Cancel": "Cancelar",
"Save": "Guardar",
"Discard": "Descartar",
diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json
index 947c48eab..c5a4bbeec 100644
--- a/src/Ryujinx/Assets/Locales/fr_FR.json
+++ b/src/Ryujinx/Assets/Locales/fr_FR.json
@@ -702,6 +702,9 @@
"Never": "Jamais",
"SwkbdMinCharacters": "Doit comporter au moins {0} 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",
"SoftwareKeyboardModeNumeric": "Doit être 0-9 ou '.' uniquement",
"SoftwareKeyboardModeAlphabet": "Doit être uniquement des caractères non CJK",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Ajout des nouveaux fichiers...",
"UpdaterExtracting": "Extraction de la mise à jour…",
"UpdaterDownloading": "Téléchargement de la mise à jour...",
- "Game": "Jeu",
"Docked": "Mode station d'accueil",
"Handheld": "Mode Portable",
"ConnectionError": "Erreur de connexion.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Cheats disponibles pour {0} [{1}]",
"BuildId": "BuildId :",
"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)",
"AutoloadDlcAddedMessage": "{0} nouveau(x) contenu(s) téléchargeable(s) ajouté(s)",
"AutoloadDlcRemovedMessage": "{0} contenu(s) téléchargeable(s) manquant(s) supprimé(s)",
diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json
index 88b6a059a..318068bf3 100644
--- a/src/Ryujinx/Assets/Locales/he_IL.json
+++ b/src/Ryujinx/Assets/Locales/he_IL.json
@@ -702,6 +702,9 @@
"Never": "אף פעם",
"SwkbdMinCharacters": "לפחות {0} תווים",
"SwkbdMinRangeCharacters": "באורך {0}-{1} תווים",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "מקלדת וירטואלית",
"SoftwareKeyboardModeNumeric": "חייב להיות בין 0-9 או '.' בלבד",
"SoftwareKeyboardModeAlphabet": "מחויב להיות ללא אותיות CJK",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "מוסיף קבצים חדשים...",
"UpdaterExtracting": "מחלץ עדכון...",
"UpdaterDownloading": "מוריד עדכון...",
- "Game": "משחק",
"Docked": "בתחנת עגינה",
"Handheld": "נייד",
"ConnectionError": "שגיאת חיבור",
diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json
index e689a2cd9..18e4ee04f 100644
--- a/src/Ryujinx/Assets/Locales/it_IT.json
+++ b/src/Ryujinx/Assets/Locales/it_IT.json
@@ -702,6 +702,9 @@
"Never": "Mai",
"SwkbdMinCharacters": "Non può avere meno di {0} 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",
"SoftwareKeyboardModeNumeric": "Deve essere solo 0-9 o '.'",
"SoftwareKeyboardModeAlphabet": "Deve essere solo caratteri non CJK",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Aggiunta dei nuovi file...",
"UpdaterExtracting": "Estrazione dell'aggiornamento...",
"UpdaterDownloading": "Download dell'aggiornamento...",
- "Game": "Gioco",
"Docked": "TV",
"Handheld": "Portatile",
"ConnectionError": "Errore di connessione.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Trucchi disponibili per {0} [{1}]",
"BuildId": "ID Build",
"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",
"AutoloadDlcAddedMessage": "{0} contenuto/i scaricabile/i aggiunto/i",
"AutoloadDlcRemovedMessage": "{0} contenuto/i scaricabile/i mancante/i rimosso/i",
diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json
index d55d1449d..6ecc74009 100644
--- a/src/Ryujinx/Assets/Locales/ja_JP.json
+++ b/src/Ryujinx/Assets/Locales/ja_JP.json
@@ -702,6 +702,9 @@
"Never": "決して",
"SwkbdMinCharacters": "最低 {0} 文字必要です",
"SwkbdMinRangeCharacters": "{0}-{1} 文字にしてください",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "ソフトウェアキーボード",
"SoftwareKeyboardModeNumeric": "0-9 または '.' のみでなければなりません",
"SoftwareKeyboardModeAlphabet": "CJK文字以外のみ",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "新規ファイルを追加中...",
"UpdaterExtracting": "アップデートを展開中...",
"UpdaterDownloading": "アップデートをダウンロード中...",
- "Game": "ゲーム",
"Docked": "ドッキング",
"Handheld": "携帯",
"ConnectionError": "接続エラー.",
@@ -785,7 +787,7 @@
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
"CheatWindowHeading": "利用可能なチート {0} [{1}]",
"BuildId": "ビルドID:",
- "DlcWindowHeading": "利用可能な DLC {0} [{1}]",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json
index 8a3799e15..71aaa41e8 100644
--- a/src/Ryujinx/Assets/Locales/ko_KR.json
+++ b/src/Ryujinx/Assets/Locales/ko_KR.json
@@ -1,7 +1,7 @@
{
"Language": "한국어",
"MenuBarFileOpenApplet": "애플릿 열기",
- "MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
+ "MenuBarFileOpenAppletOpenMiiApplet": "Mii 편집 애플릿",
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "독립 실행형 모드로 Mii 편집기 애플릿 열기",
"SettingsTabInputDirectMouseAccess": "마우스 직접 접근",
"SettingsTabSystemMemoryManagerMode": "메모리 관리자 모드 :",
@@ -484,7 +484,7 @@
"DialogControllerAppletTitle": "컨트롤러 애플릿",
"DialogMessageDialogErrorExceptionMessage": "메시지 대화 상자 표시 오류 : {0}",
"DialogSoftwareKeyboardErrorExceptionMessage": "소프트웨어 키보드 표시 오류 : {0}",
- "DialogErrorAppletErrorExceptionMessage": "ErrorApplet 대화 상자 표시 오류 : {0}",
+ "DialogErrorAppletErrorExceptionMessage": "애플릿 오류류 대화 상자 표시 오류 : {0}",
"DialogUserErrorDialogMessage": "{0}: {1}",
"DialogUserErrorDialogInfoMessage": "\n이 오류를 해결하는 방법에 대한 자세한 내용은 설정 가이드를 참조하세요.",
"DialogUserErrorDialogTitle": "Ryujinx 오류 ({0})",
@@ -702,6 +702,9 @@
"Never": "절대 안 함",
"SwkbdMinCharacters": "{0}자 이상이어야 함",
"SwkbdMinRangeCharacters": "{0}-{1}자 길이여야 함",
+ "CabinetTitle": "캐비닛 대화 상자",
+ "CabinetDialog": "Amiibo의 새 이름 입력하기",
+ "CabinetScanDialog": "지금 Amiibo를 스캔하세요.",
"SoftwareKeyboard": "소프트웨어 키보드",
"SoftwareKeyboardModeNumeric": "0-9 또는 '.'만 가능",
"SoftwareKeyboardModeAlphabet": "CJK 문자가 아닌 문자만 가능",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "새 파일 추가...",
"UpdaterExtracting": "업데이트 추출...",
"UpdaterDownloading": "업데이트 내려받기 중...",
- "Game": "게임",
"Docked": "도킹",
"Handheld": "휴대",
"ConnectionError": "연결 오류가 발생했습니다.",
@@ -779,14 +781,14 @@
"XCITrimmerDeselectDisplayed": "표시됨 선택 취소",
"XCITrimmerSortName": "타이틀",
"XCITrimmerSortSaved": "공간 절약s",
- "XCITrimmerTrim": "Trim",
- "XCITrimmerUntrim": "Untrim",
+ "XCITrimmerTrim": "트림",
+ "XCITrimmerUntrim": "언트림",
"UpdateWindowUpdateAddedMessage": "{0}개의 새 업데이트가 추가됨",
"UpdateWindowBundledContentNotice": "번들 업데이트는 제거할 수 없으며, 비활성화만 가능합니다.",
"CheatWindowHeading": "{0} [{1}]에 사용 가능한 치트",
"BuildId": "빌드ID:",
"DlcWindowBundledContentNotice": "번들 DLC는 제거할 수 없으며 비활성화만 가능합니다.",
- "DlcWindowHeading": "{1} ({2})에 내려받기 가능한 콘텐츠 {0}개 사용 가능",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨",
"AutoloadDlcAddedMessage": "{0}개의 새로운 내려받기 가능한 콘텐츠가 추가됨",
"AutoloadDlcRemovedMessage": "{0}개의 내려받기 가능한 콘텐츠가 제거됨",
diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json
index c3202020f..6a2fa08b1 100644
--- a/src/Ryujinx/Assets/Locales/pl_PL.json
+++ b/src/Ryujinx/Assets/Locales/pl_PL.json
@@ -702,6 +702,9 @@
"Never": "Nigdy",
"SwkbdMinCharacters": "Musi mieć co najmniej {0} 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",
"SoftwareKeyboardModeNumeric": "Może składać się jedynie z 0-9 lub '.'",
"SoftwareKeyboardModeAlphabet": "Nie może zawierać znaków CJK",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Dodawanie Nowych Plików...",
"UpdaterExtracting": "Wypakowywanie Aktualizacji...",
"UpdaterDownloading": "Pobieranie Aktualizacji...",
- "Game": "Gra",
"Docked": "Zadokowany",
"Handheld": "Przenośny",
"ConnectionError": "Błąd Połączenia.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Kody Dostępne dla {0} [{1}]",
"BuildId": "Identyfikator wersji:",
"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",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json
index 71992434b..90b78b732 100644
--- a/src/Ryujinx/Assets/Locales/pt_BR.json
+++ b/src/Ryujinx/Assets/Locales/pt_BR.json
@@ -701,6 +701,9 @@
"Never": "Nunca",
"SwkbdMinCharacters": "Deve ter pelo menos {0} 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",
"SoftwareKeyboardModeNumeric": "Deve ser somente 0-9 ou '.'",
"SoftwareKeyboardModeAlphabet": "Apenas devem ser caracteres não CJK.",
@@ -714,7 +717,6 @@
"UpdaterAddingFiles": "Adicionando novos arquivos...",
"UpdaterExtracting": "Extraíndo atualização...",
"UpdaterDownloading": "Baixando atualização...",
- "Game": "Jogo",
"Docked": "TV",
"Handheld": "Portátil",
"ConnectionError": "Erro de conexão.",
@@ -785,7 +787,7 @@
"CheatWindowHeading": "Cheats disponíveis para {0} [{1}]",
"BuildId": "ID da Build:",
"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)",
"AutoloadDlcAddedMessage": "{0} novo(s) conteúdo(s) para download adicionado(s)",
"AutoloadDlcRemovedMessage": "{0} conteúdo(s) para download ausente(s) removido(s)",
diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json
index f0218ffcc..f058154e9 100644
--- a/src/Ryujinx/Assets/Locales/ru_RU.json
+++ b/src/Ryujinx/Assets/Locales/ru_RU.json
@@ -702,6 +702,9 @@
"Never": "Никогда",
"SwkbdMinCharacters": "Должно быть не менее {0} символов.",
"SwkbdMinRangeCharacters": "Должно быть {0}-{1} символов",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Программная клавиатура",
"SoftwareKeyboardModeNumeric": "Должно быть в диапазоне 0-9 или '.'",
"SoftwareKeyboardModeAlphabet": "Не должно быть CJK-символов",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Добавление новых файлов...",
"UpdaterExtracting": "Извлечение обновления...",
"UpdaterDownloading": "Загрузка обновления...",
- "Game": "Игра",
"Docked": "Стационарный режим",
"Handheld": "Портативный режим",
"ConnectionError": "Ошибка соединения",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Доступные читы для {0} [{1}]",
"BuildId": "ID версии:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
- "DlcWindowHeading": "{0} DLC",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json
index 02ddda899..33b2c4f30 100644
--- a/src/Ryujinx/Assets/Locales/th_TH.json
+++ b/src/Ryujinx/Assets/Locales/th_TH.json
@@ -702,6 +702,9 @@
"Never": "ไม่ต้อง",
"SwkbdMinCharacters": "ต้องมีความยาวของตัวอักษรอย่างน้อย {0} ตัว",
"SwkbdMinRangeCharacters": "ต้องมีความยาวของตัวอักษร {0}-{1} ตัว",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "ซอฟต์แวร์คีย์บอร์ด",
"SoftwareKeyboardModeNumeric": "ต้องเป็น 0-9 หรือ '.' เท่านั้น",
"SoftwareKeyboardModeAlphabet": "ต้องเป็นตัวอักษรที่ไม่ใช่ประเภท CJK เท่านั้น",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "กำลังเพิ่มไฟล์ใหม่...",
"UpdaterExtracting": "กำลังแยกการอัปเดต...",
"UpdaterDownloading": "กำลังดาวน์โหลดอัปเดต...",
- "Game": "เกมส์",
"Docked": "ด็อก",
"Handheld": "แฮนด์เฮลด์",
"ConnectionError": "การเชื่อมต่อล้มเหลว",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "สูตรโกงมีให้สำหรับ {0} [{1}]",
"BuildId": "รหัสการสร้าง:",
"DlcWindowBundledContentNotice": "แพ็ค DLC ไม่สามารถลบทิ้งได้ สามารถปิดใช้งานได้เท่านั้น",
- "DlcWindowHeading": "{0} DLC ที่สามารถดาวน์โหลดได้",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} DLC ใหม่ที่เพิ่มเข้ามา",
"AutoloadDlcAddedMessage": "{0} ใหม่ที่เพิ่มเข้ามา",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json
index a65064a38..72da205cb 100644
--- a/src/Ryujinx/Assets/Locales/tr_TR.json
+++ b/src/Ryujinx/Assets/Locales/tr_TR.json
@@ -702,6 +702,9 @@
"Never": "Hiçbir Zaman",
"SwkbdMinCharacters": "En az {0} 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",
"SoftwareKeyboardModeNumeric": "Sadece 0-9 veya '.' olabilir",
"SoftwareKeyboardModeAlphabet": "Sadece CJK-characters olmayan karakterler olabilir",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Yeni Dosyalar Ekleniyor...",
"UpdaterExtracting": "Güncelleme Ayrıştırılıyor...",
"UpdaterDownloading": "Güncelleme İndiriliyor...",
- "Game": "Oyun",
"Docked": "Docked",
"Handheld": "El tipi",
"ConnectionError": "Bağlantı Hatası.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "{0} için Hile mevcut [{1}]",
"BuildId": "BuildId:",
"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",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json
index ef26ace65..06f658640 100644
--- a/src/Ryujinx/Assets/Locales/uk_UA.json
+++ b/src/Ryujinx/Assets/Locales/uk_UA.json
@@ -702,6 +702,9 @@
"Never": "Ніколи",
"SwkbdMinCharacters": "Мінімальна кількість символів: {0}",
"SwkbdMinRangeCharacters": "Має бути {0}-{1} символів",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "Програмна клавіатура",
"SoftwareKeyboardModeNumeric": "Повинно бути лише 0-9 або “.”",
"SoftwareKeyboardModeAlphabet": "Повинно бути лише не CJK-символи",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "Додавання нових файлів...",
"UpdaterExtracting": "Видобування оновлення...",
"UpdaterDownloading": "Завантаження оновлення...",
- "Game": "Гра",
"Docked": "Док-станція",
"Handheld": "Портативний",
"ConnectionError": "Помилка з'єднання.",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "Коди доступні для {0} [{1}]",
"BuildId": "ID збірки:",
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
- "DlcWindowHeading": "Вміст для завантаження, доступний для {1} ({2}): {0}",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json
index dc3f27b5a..66ac309de 100644
--- a/src/Ryujinx/Assets/Locales/zh_CN.json
+++ b/src/Ryujinx/Assets/Locales/zh_CN.json
@@ -702,6 +702,9 @@
"Never": "从不",
"SwkbdMinCharacters": "不少于 {0} 个字符",
"SwkbdMinRangeCharacters": "必须为 {0}-{1} 个字符",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "软键盘",
"SoftwareKeyboardModeNumeric": "只能输入 0-9 或 \".\"",
"SoftwareKeyboardModeAlphabet": "仅支持非中文字符",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "安装更新中...",
"UpdaterExtracting": "正在提取更新...",
"UpdaterDownloading": "下载更新中...",
- "Game": "游戏",
"Docked": "主机模式",
"Handheld": "掌机模式",
"ConnectionError": "连接错误。",
diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json
index c33885784..64f137885 100644
--- a/src/Ryujinx/Assets/Locales/zh_TW.json
+++ b/src/Ryujinx/Assets/Locales/zh_TW.json
@@ -702,6 +702,9 @@
"Never": "從不",
"SwkbdMinCharacters": "長度必須至少為 {0} 個字元",
"SwkbdMinRangeCharacters": "長度必須為 {0} 到 {1} 個字元",
+ "CabinetTitle": "Cabinet Dialog",
+ "CabinetDialog": "Enter your Amiibo's new name",
+ "CabinetScanDialog": "Please scan your Amiibo now.",
"SoftwareKeyboard": "軟體鍵盤",
"SoftwareKeyboardModeNumeric": "必須是 0 到 9 或「.」",
"SoftwareKeyboardModeAlphabet": "必須是「非中日韓字元」 (non CJK)",
@@ -715,7 +718,6 @@
"UpdaterAddingFiles": "正在加入新檔案...",
"UpdaterExtracting": "正在提取更新...",
"UpdaterDownloading": "正在下載更新...",
- "Game": "遊戲",
"Docked": "底座模式",
"Handheld": "手提模式",
"ConnectionError": "連線錯誤。",
@@ -786,7 +788,7 @@
"CheatWindowHeading": "可用於 {0} [{1}] 的密技",
"BuildId": "組建識別碼:",
"DlcWindowBundledContentNotice": "附帶的 DLC 只能被停用而無法被刪除。",
- "DlcWindowHeading": "{0} 個可下載內容",
+ "DlcWindowHeading": "{0} DLC(s) available",
"DlcWindowDlcAddedMessage": "已加入 {0} 個 DLC",
"AutoloadDlcAddedMessage": "已加入 {0} 個 DLC",
"AutoloadDlcRemovedMessage": "已刪除 {0} 個遺失的 DLC",
diff --git a/src/Ryujinx/Assets/Styles/Themes.xaml b/src/Ryujinx/Assets/Styles/Themes.xaml
index 056eba228..46e298035 100644
--- a/src/Ryujinx/Assets/Styles/Themes.xaml
+++ b/src/Ryujinx/Assets/Styles/Themes.xaml
@@ -4,18 +4,6 @@
-
-
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FFe8e8e8
#FF00FABB
#FFF0F0F0
#FFd6d6d6
@@ -26,6 +14,7 @@
#b3ffffff
#80cccccc
#A0000000
+ #fffcd12a
#FF2EEAC9
#FFFF4554
#6483F5
@@ -33,18 +22,6 @@
-
-
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FF00C3E3
- #FFe8e8e8
#FF00FABB
#FFF0F0F0
#FFd6d6d6
@@ -59,18 +36,7 @@
-
-
#008AA8
- #FF00C3E3
- #FF99b000
- #FF006d7d
- #FF00525E
- #FF00dbff
- #FF19dfff
- #FF33e3ff
#FF00FABB
#FF2D2D2D
#FF505050
diff --git a/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs b/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs
index 67c016562..b1b7361a6 100644
--- a/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs
+++ b/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs
@@ -17,13 +17,13 @@ namespace Ryujinx.Ava.Common.Markup
public virtual string Name => "Item";
public virtual Action