am: Fully reverse swkbd configuration structure
This commit is contained in:
parent
bb7600e215
commit
4e38cadcad
3 changed files with 236 additions and 35 deletions
|
@ -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;
|
||||
|
@ -22,7 +23,8 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
|
||||
private SoftwareKeyboardConfig _keyboardConfig;
|
||||
|
||||
private string _textValue = DEFAULT_TEXT;
|
||||
private string _textValue = DEFAULT_TEXT;
|
||||
private Encoding _encoding = Encoding.Unicode;
|
||||
|
||||
public event EventHandler AppletStateChanged;
|
||||
|
||||
|
@ -41,6 +43,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
var transferMemory = _normalSession.Pop();
|
||||
|
||||
_keyboardConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
|
||||
_encoding = _keyboardConfig.UseUtf8 ? Encoding.UTF8 : Encoding.Unicode;
|
||||
|
||||
_state = SoftwareKeyboardState.Ready;
|
||||
|
||||
|
@ -58,7 +61,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
{
|
||||
// If the keyboard type is numbers only, we swap to a default
|
||||
// text that only contains numbers.
|
||||
if (_keyboardConfig.Type == SoftwareKeyboardType.NumbersOnly)
|
||||
if (_keyboardConfig.Mode == KeyboardMode.NumbersOnly)
|
||||
{
|
||||
_textValue = DEFAULT_NUMB;
|
||||
}
|
||||
|
@ -70,6 +73,15 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
_keyboardConfig.StringLengthMax = 100;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// This should always be done before the text truncation step.
|
||||
while (_textValue.Length < _keyboardConfig.StringLengthMin)
|
||||
{
|
||||
_textValue = String.Join(" ", _textValue, _textValue);
|
||||
}
|
||||
|
||||
// If our default text is longer than the allowed length,
|
||||
// we truncate it.
|
||||
if (_textValue.Length > _keyboardConfig.StringLengthMax)
|
||||
|
@ -77,6 +89,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
_textValue = _textValue.Substring(0, (int)_keyboardConfig.StringLengthMax);
|
||||
}
|
||||
|
||||
// Does the application want to validate the text itself?
|
||||
if (!_keyboardConfig.CheckText)
|
||||
{
|
||||
// If the application doesn't need to validate the response,
|
||||
|
@ -136,12 +149,12 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
|
||||
private byte[] BuildResponse(string text, bool interactive)
|
||||
{
|
||||
int bufferSize = !interactive ? STANDARD_BUFFER_SIZE : INTERACTIVE_BUFFER_SIZE;
|
||||
int bufferSize = interactive ? INTERACTIVE_BUFFER_SIZE : STANDARD_BUFFER_SIZE;
|
||||
|
||||
using (MemoryStream stream = new MemoryStream(new byte[bufferSize]))
|
||||
using (BinaryWriter writer = new BinaryWriter(stream))
|
||||
{
|
||||
byte[] output = Encoding.Unicode.GetBytes(text);
|
||||
byte[] output = _encoding.GetBytes(text);
|
||||
|
||||
if (!interactive)
|
||||
{
|
||||
|
|
|
@ -2,32 +2,240 @@
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||
{
|
||||
// TODO(jduncanator): Define all fields
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal enum KeyboardMode : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Normal keyboard.
|
||||
/// </summary>
|
||||
Default,
|
||||
|
||||
/// <summary>
|
||||
/// Number pad. The buttons at the bottom left/right are only available when they're set in the config by leftButtonText / rightButtonText.
|
||||
/// </summary>
|
||||
NumbersOnly,
|
||||
|
||||
/// <summary>
|
||||
/// QWERTY (and variants) keyboard only.
|
||||
/// </summary>
|
||||
LettersOnly
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal enum InvalidCharFlags : uint
|
||||
{
|
||||
None = 0 << 1,
|
||||
|
||||
Space = 1 << 1,
|
||||
|
||||
AtSymbol = 1 << 2,
|
||||
|
||||
Percent = 1 << 3,
|
||||
|
||||
ForwardSlash = 1 << 4,
|
||||
|
||||
BackSlash = 1 << 5,
|
||||
|
||||
Numbers = 1 << 6,
|
||||
|
||||
DownloadCode = 1 << 7,
|
||||
|
||||
Username = 1 << 8
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal enum PasswordMode : uint
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Disabled,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Enabled
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal enum InputFormMode : uint
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SingleLine,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
MultiLine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal enum InitialCursorPosition : uint
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
Start,
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
End
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
struct SoftwareKeyboardConfig
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
const int SubmitTextLength = 8;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
const int HeaderTextLength = 64;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
const int SubtitleTextLength = 128;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
const int GuideTextLength = 256;
|
||||
|
||||
/// <summary>
|
||||
/// Type of keyboard.
|
||||
/// </summary>
|
||||
[FieldOffset(0x0)]
|
||||
public SoftwareKeyboardType Type;
|
||||
public KeyboardMode Mode;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SubmitTextLength + 1)]
|
||||
public string SubmitText;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public char LeftOptionalSymbolKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public char RightOptionalSymbolKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool PredictionEnabled;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InvalidCharFlags InvalidCharFlag;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InitialCursorPosition InitialCursorPosition;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = HeaderTextLength + 1)]
|
||||
public string HeaderText;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = SubtitleTextLength + 1)]
|
||||
public string SubtitleText;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = GuideTextLength + 1)]
|
||||
public string GuideText;
|
||||
|
||||
/// <summary>
|
||||
/// When non-zero, specifies the max string length. When the input is too long, swkbd will stop accepting more input until text is deleted via the B button (Backspace).
|
||||
/// </summary>
|
||||
[FieldOffset(0x3AC)]
|
||||
public uint StringLengthMax;
|
||||
public int StringLengthMax;
|
||||
|
||||
/// <summary>
|
||||
/// When non-zero, specifies the max string length. When the input is too long, swkbd will display an icon and disable the ok-button.
|
||||
/// When non-zero, specifies the minimum string length.
|
||||
/// </summary>
|
||||
[FieldOffset(0x3B0)]
|
||||
public uint StringLengthMaxExtended;
|
||||
public int StringLengthMin;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public PasswordMode PasswordMode;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public InputFormMode InputFormMode;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool UseNewLine;
|
||||
|
||||
/// <summary>
|
||||
/// When set, the software keyboard will return a string UTF-8 encoded, rather than UTF-16.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool UseUtf8;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool UseBlurBackground;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int InitialStringOffset;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int InitialStringLength;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int CustomDictionaryOffset;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int CustomDictionaryCount;
|
||||
|
||||
/// <summary>
|
||||
/// When set, the application will validate the entered text whilst the swkbd is still on screen.
|
||||
/// </summary>
|
||||
[FieldOffset(0x3D0), MarshalAs(UnmanagedType.I1)]
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool CheckText;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||
{
|
||||
internal enum SoftwareKeyboardType : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Normal keyboard.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Number pad. The buttons at the bottom left/right are only available when they're set in the config by leftButtonText / rightButtonText.
|
||||
/// </summary>
|
||||
NumbersOnly = 1,
|
||||
|
||||
/// <summary>
|
||||
/// QWERTY (and variants) keyboard only.
|
||||
/// </summary>
|
||||
LettersOnly = 2
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue