|
|
@@ -1,4 +1,5 @@
|
|
|
-using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
|
|
+using Ryujinx.Common.Logging;
|
|
|
+using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
|
|
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
|
|
using System;
|
|
|
using System.IO;
|
|
|
@@ -9,9 +10,10 @@ namespace Ryujinx.HLE.HOS.Applets
|
|
|
{
|
|
|
internal class SoftwareKeyboardApplet : IApplet
|
|
|
{
|
|
|
- private const string DefaultNumb = "1";
|
|
|
private const string DefaultText = "Ryujinx";
|
|
|
|
|
|
+ private readonly Switch _device;
|
|
|
+
|
|
|
private const int StandardBufferSize = 0x7D8;
|
|
|
private const int InteractiveBufferSize = 0x7D4;
|
|
|
|
|
|
@@ -21,13 +23,18 @@ namespace Ryujinx.HLE.HOS.Applets
|
|
|
private AppletSession _interactiveSession;
|
|
|
|
|
|
private SoftwareKeyboardConfig _keyboardConfig;
|
|
|
+ private byte[] _transferMemory;
|
|
|
|
|
|
- private string _textValue = DefaultText;
|
|
|
+ private string _textValue = null;
|
|
|
+ private bool _okPressed = false;
|
|
|
private Encoding _encoding = Encoding.Unicode;
|
|
|
|
|
|
public event EventHandler AppletStateChanged;
|
|
|
|
|
|
- public SoftwareKeyboardApplet(Horizon system) { }
|
|
|
+ public SoftwareKeyboardApplet(Horizon system)
|
|
|
+ {
|
|
|
+ _device = system.Device;
|
|
|
+ }
|
|
|
|
|
|
public ResultCode Start(AppletSession normalSession,
|
|
|
AppletSession interactiveSession)
|
|
|
@@ -39,9 +46,20 @@ namespace Ryujinx.HLE.HOS.Applets
|
|
|
|
|
|
var launchParams = _normalSession.Pop();
|
|
|
var keyboardConfig = _normalSession.Pop();
|
|
|
- var transferMemory = _normalSession.Pop();
|
|
|
|
|
|
- _keyboardConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
|
|
|
+ if (keyboardConfig.Length < Marshal.SizeOf<SoftwareKeyboardConfig>())
|
|
|
+ {
|
|
|
+ Logger.PrintError(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _keyboardConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!_normalSession.TryPop(out _transferMemory))
|
|
|
+ {
|
|
|
+ Logger.PrintError(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
|
|
|
+ }
|
|
|
|
|
|
if (_keyboardConfig.UseUtf8)
|
|
|
{
|
|
|
@@ -62,11 +80,13 @@ namespace Ryujinx.HLE.HOS.Applets
|
|
|
|
|
|
private void Execute()
|
|
|
{
|
|
|
- // If the keyboard type is numbers only, we swap to a default
|
|
|
- // text that only contains numbers.
|
|
|
- if (_keyboardConfig.Mode == KeyboardMode.NumbersOnly)
|
|
|
+ string initialText = null;
|
|
|
+
|
|
|
+ // Initial Text is always encoded as a UTF-16 string in the work buffer (passed as transfer memory)
|
|
|
+ // InitialStringOffset points to the memory offset and InitialStringLength is the number of UTF-16 characters
|
|
|
+ if (_transferMemory != null && _keyboardConfig.InitialStringLength > 0)
|
|
|
{
|
|
|
- _textValue = DefaultNumb;
|
|
|
+ initialText = Encoding.Unicode.GetString(_transferMemory, _keyboardConfig.InitialStringOffset, 2 * _keyboardConfig.InitialStringLength);
|
|
|
}
|
|
|
|
|
|
// If the max string length is 0, we set it to a large default
|
|
|
@@ -76,6 +96,30 @@ namespace Ryujinx.HLE.HOS.Applets
|
|
|
_keyboardConfig.StringLengthMax = 100;
|
|
|
}
|
|
|
|
|
|
+ var args = new SoftwareKeyboardUiArgs
|
|
|
+ {
|
|
|
+ HeaderText = _keyboardConfig.HeaderText,
|
|
|
+ SubtitleText = _keyboardConfig.SubtitleText,
|
|
|
+ GuideText = _keyboardConfig.GuideText,
|
|
|
+ SubmitText = (!string.IsNullOrWhiteSpace(_keyboardConfig.SubmitText) ? _keyboardConfig.SubmitText : "OK"),
|
|
|
+ StringLengthMin = _keyboardConfig.StringLengthMin,
|
|
|
+ StringLengthMax = _keyboardConfig.StringLengthMax,
|
|
|
+ InitialText = initialText
|
|
|
+ };
|
|
|
+
|
|
|
+ // Call the configured GUI handler to get user's input
|
|
|
+ if (_device.UiHandler == null)
|
|
|
+ {
|
|
|
+ Logger.PrintWarning(LogClass.Application, $"GUI Handler is not set. Falling back to default");
|
|
|
+ _okPressed = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _okPressed = _device.UiHandler.DisplayInputDialog(args, out _textValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ _textValue ??= initialText ?? DefaultText;
|
|
|
+
|
|
|
// If the game requests a string with a minimum length less
|
|
|
// than our default text, repeat our default text until we meet
|
|
|
// the minimum length requirement.
|
|
|
@@ -162,7 +206,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|
|
if (!interactive)
|
|
|
{
|
|
|
// Result Code
|
|
|
- writer.Write((uint)0);
|
|
|
+ writer.Write(_okPressed ? 0U : 1U);
|
|
|
}
|
|
|
else
|
|
|
{
|