mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-12-18 12:55:54 +01:00
Add the Cabinet Applet (#340)
This adds the missing Cabinet Applet, which allows for formatting Amiibos and changing their names.
This commit is contained in:
parent
17483aad24
commit
08b7257be5
@ -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;
|
||||
@ -31,6 +32,8 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||
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!");
|
||||
|
195
src/Ryujinx.HLE/HOS/Applets/Cabinet/CabinetApplet.cs
Normal file
195
src/Ryujinx.HLE/HOS/Applets/Cabinet/CabinetApplet.cs
Normal file
@ -0,0 +1,195 @@
|
||||
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;
|
||||
}
|
||||
|
||||
public static T ReadStruct<T>(byte[] data) where T : unmanaged
|
||||
{
|
||||
if (data.Length < Unsafe.SizeOf<T>())
|
||||
{
|
||||
throw new ArgumentException("Not enough data to read the struct");
|
||||
}
|
||||
|
||||
fixed (byte* dataPtr = data)
|
||||
{
|
||||
return Unsafe.Read<T>(dataPtr);
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -24,6 +24,18 @@ namespace Ryujinx.HLE.UI
|
||||
/// <returns>True when OK is pressed, False otherwise.</returns>
|
||||
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>
|
||||
/// Tell the UI that we need to transition to another program.
|
||||
/// </summary>
|
||||
|
@ -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;
|
||||
|
@ -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 فقط",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -702,6 +702,9 @@
|
||||
"Never": "Nunca",
|
||||
"SwkbdMinCharacters": "Debe tener al menos {0} caracteres",
|
||||
"SwkbdMinRangeCharacters": "Debe tener {0}-{1} caracteres",
|
||||
"CabinetTitle": "Cabinet Dialog",
|
||||
"CabinetDialog": "Enter your Amiibo's new name",
|
||||
"CabinetScanDialog": "Please scan your Amiibo now.",
|
||||
"SoftwareKeyboard": "Teclado de software",
|
||||
"SoftwareKeyboardModeNumeric": "Debe ser sólo 0-9 o '.'",
|
||||
"SoftwareKeyboardModeAlphabet": "Solo deben ser caracteres no CJK",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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文字以外のみ",
|
||||
|
@ -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 문자가 아닌 문자만 가능",
|
||||
|
@ -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",
|
||||
|
@ -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.",
|
||||
|
@ -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-символов",
|
||||
|
@ -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 เท่านั้น",
|
||||
|
@ -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",
|
||||
|
@ -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-символи",
|
||||
|
@ -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": "仅支持非中文字符",
|
||||
|
@ -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)",
|
||||
|
@ -7,6 +7,7 @@ using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.HLE;
|
||||
using Ryujinx.HLE.HOS.Applets;
|
||||
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
||||
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
|
||||
using Ryujinx.HLE.UI;
|
||||
using Ryujinx.UI.Common.Configuration;
|
||||
@ -155,6 +156,55 @@ namespace Ryujinx.Ava.UI.Applet
|
||||
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)
|
||||
{
|
||||
device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value);
|
||||
|
Loading…
Reference in New Issue
Block a user