set: Quick implementation of GetKeyCodeMap/GetKeyCodeMap2 (#1210)
* set: Quick implementation of GetKeyCodeMap/GetKeyCodeMap2 This fixed USB keyboard access in official titles. * hid: Stub SendKeyboardLockKeyEvent * Update Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.HLE/HOS/Services/Hid/IHidServer.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * set: KeyboardLayout bringup * set: Small bugfix * Fix GetKeyCodeMapImpl * Revert SystemRegion > RegionCode in Configuration * Fix SendKeyboardLockKeyEvent Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
parent
8be7335176
commit
7f500e7cae
7 changed files with 5001 additions and 8 deletions
|
@ -81,6 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
context.Device.Hid.Touchscreen.Active = true;
|
context.Device.Hid.Touchscreen.Active = true;
|
||||||
|
|
||||||
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
|
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
|
@ -93,6 +94,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
context.Device.Hid.Mouse.Active = true;
|
context.Device.Hid.Mouse.Active = true;
|
||||||
|
|
||||||
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
|
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
|
@ -105,11 +107,25 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
context.Device.Hid.Keyboard.Active = true;
|
context.Device.Hid.Keyboard.Active = true;
|
||||||
|
|
||||||
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
|
Logger.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(32)]
|
||||||
|
// SendKeyboardLockKeyEvent(uint flags, pid)
|
||||||
|
public ResultCode SendKeyboardLockKeyEvent(ServiceCtx context)
|
||||||
|
{
|
||||||
|
uint flags = context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
|
// NOTE: This signal the keyboard driver about lock events.
|
||||||
|
|
||||||
|
Logger.PrintStub(LogClass.ServiceHid, new { flags });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[Command(40)]
|
[Command(40)]
|
||||||
// AcquireXpadIdEventHandle(ulong XpadId) -> nn::sf::NativeHandle
|
// AcquireXpadIdEventHandle(ulong XpadId) -> nn::sf::NativeHandle
|
||||||
public ResultCode AcquireXpadIdEventHandle(ServiceCtx context)
|
public ResultCode AcquireXpadIdEventHandle(ServiceCtx context)
|
||||||
|
|
|
@ -60,11 +60,11 @@ namespace Ryujinx.HLE.HOS.Services.Settings
|
||||||
{
|
{
|
||||||
// NOTE: Service mount 0x8000000000000050 savedata and read the region code here.
|
// NOTE: Service mount 0x8000000000000050 savedata and read the region code here.
|
||||||
|
|
||||||
SystemRegion regionCode = (SystemRegion)context.Device.System.State.DesiredRegionCode;
|
RegionCode regionCode = (RegionCode)context.Device.System.State.DesiredRegionCode;
|
||||||
|
|
||||||
if (regionCode < SystemRegion.Min || regionCode > SystemRegion.Max)
|
if (regionCode < RegionCode.Min || regionCode > RegionCode.Max)
|
||||||
{
|
{
|
||||||
regionCode = SystemRegion.USA;
|
regionCode = RegionCode.USA;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ResponseData.Write((uint)regionCode);
|
context.ResponseData.Write((uint)regionCode);
|
||||||
|
@ -92,6 +92,13 @@ namespace Ryujinx.HLE.HOS.Services.Settings
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(7)] // 4.0.0+
|
||||||
|
// GetKeyCodeMap() -> buffer<nn::kpr::KeyCodeMap, 0x16>
|
||||||
|
public ResultCode GetKeyCodeMap(ServiceCtx context)
|
||||||
|
{
|
||||||
|
return GetKeyCodeMapImpl(context, 1);
|
||||||
|
}
|
||||||
|
|
||||||
[Command(8)] // 5.0.0+
|
[Command(8)] // 5.0.0+
|
||||||
// GetQuestFlag() -> bool
|
// GetQuestFlag() -> bool
|
||||||
public ResultCode GetQuestFlag(ServiceCtx context)
|
public ResultCode GetQuestFlag(ServiceCtx context)
|
||||||
|
@ -103,6 +110,96 @@ namespace Ryujinx.HLE.HOS.Services.Settings
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(9)] // 6.0.0+
|
||||||
|
// GetKeyCodeMap2() -> buffer<nn::kpr::KeyCodeMap, 0x16>
|
||||||
|
public ResultCode GetKeyCodeMap2(ServiceCtx context)
|
||||||
|
{
|
||||||
|
return GetKeyCodeMapImpl(context, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultCode GetKeyCodeMapImpl(ServiceCtx context, int version)
|
||||||
|
{
|
||||||
|
if (context.Request.ReceiveBuff[0].Size != 0x1000)
|
||||||
|
{
|
||||||
|
Logger.PrintWarning(LogClass.ServiceSet, "Bad size");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] keyCodeMap;
|
||||||
|
|
||||||
|
switch ((KeyboardLayout)context.Device.System.State.DesiredKeyboardLayout)
|
||||||
|
{
|
||||||
|
case KeyboardLayout.EnglishUs:
|
||||||
|
|
||||||
|
long langCode = context.Device.System.State.DesiredLanguageCode;
|
||||||
|
|
||||||
|
if (langCode == 0x736e61482d687a) // Zh-Hans
|
||||||
|
{
|
||||||
|
keyCodeMap = KeyCodeMaps.ChineseSimplified;
|
||||||
|
}
|
||||||
|
else if (langCode == 0x746e61482d687a) // Zh-Hant
|
||||||
|
{
|
||||||
|
keyCodeMap = KeyCodeMaps.ChineseTraditional;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyCodeMap = KeyCodeMaps.EnglishUk;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.EnglishUsInternational:
|
||||||
|
keyCodeMap = KeyCodeMaps.EnglishUsInternational;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.EnglishUk:
|
||||||
|
keyCodeMap = KeyCodeMaps.EnglishUk;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.French:
|
||||||
|
keyCodeMap = KeyCodeMaps.French;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.FrenchCa:
|
||||||
|
keyCodeMap = KeyCodeMaps.FrenchCa;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.Spanish:
|
||||||
|
keyCodeMap = KeyCodeMaps.Spanish;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.SpanishLatin:
|
||||||
|
keyCodeMap = KeyCodeMaps.SpanishLatin;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.German:
|
||||||
|
keyCodeMap = KeyCodeMaps.German;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.Italian:
|
||||||
|
keyCodeMap = KeyCodeMaps.Italian;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.Portuguese:
|
||||||
|
keyCodeMap = KeyCodeMaps.Portuguese;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.Russian:
|
||||||
|
keyCodeMap = KeyCodeMaps.Russian;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.Korean:
|
||||||
|
keyCodeMap = KeyCodeMaps.Korean;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.ChineseSimplified:
|
||||||
|
keyCodeMap = KeyCodeMaps.ChineseSimplified;
|
||||||
|
break;
|
||||||
|
case KeyboardLayout.ChineseTraditional:
|
||||||
|
keyCodeMap = KeyCodeMaps.ChineseTraditional;
|
||||||
|
break;
|
||||||
|
default: // KeyboardLayout.Default
|
||||||
|
keyCodeMap = KeyCodeMaps.Default;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Memory.Write((ulong)context.Request.ReceiveBuff[0].Position, keyCodeMap);
|
||||||
|
|
||||||
|
if (version == 1 && context.Device.System.State.DesiredKeyboardLayout == (long)KeyboardLayout.Default)
|
||||||
|
{
|
||||||
|
context.Memory.Write((ulong)context.Request.ReceiveBuff[0].Position, (byte)0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
public ResultCode GetAvailableLanguagesCodesImpl(ServiceCtx context, long position, long size, int maxSize)
|
public ResultCode GetAvailableLanguagesCodesImpl(ServiceCtx context, long position, long size, int maxSize)
|
||||||
{
|
{
|
||||||
int count = (int)(size / 8);
|
int count = (int)(size / 8);
|
||||||
|
|
4849
Ryujinx.HLE/HOS/Services/Settings/KeyCodeMaps.cs
Normal file
4849
Ryujinx.HLE/HOS/Services/Settings/KeyCodeMaps.cs
Normal file
File diff suppressed because it is too large
Load diff
25
Ryujinx.HLE/HOS/SystemState/KeyboardLayout.cs
Normal file
25
Ryujinx.HLE/HOS/SystemState/KeyboardLayout.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.SystemState
|
||||||
|
{
|
||||||
|
// nn::settings::KeyboardLayout
|
||||||
|
public enum KeyboardLayout
|
||||||
|
{
|
||||||
|
Default = 0,
|
||||||
|
EnglishUs,
|
||||||
|
EnglishUsInternational,
|
||||||
|
EnglishUk,
|
||||||
|
French,
|
||||||
|
FrenchCa,
|
||||||
|
Spanish,
|
||||||
|
SpanishLatin,
|
||||||
|
German,
|
||||||
|
Italian,
|
||||||
|
Portuguese,
|
||||||
|
Russian,
|
||||||
|
Korean,
|
||||||
|
ChineseSimplified,
|
||||||
|
ChineseTraditional,
|
||||||
|
|
||||||
|
Min = Default,
|
||||||
|
Max = ChineseTraditional
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
namespace Ryujinx.HLE.HOS.SystemState
|
namespace Ryujinx.HLE.HOS.SystemState
|
||||||
{
|
{
|
||||||
public enum SystemRegion
|
// nn::settings::RegionCode
|
||||||
|
public enum RegionCode
|
||||||
{
|
{
|
||||||
Japan,
|
Japan,
|
||||||
USA,
|
USA,
|
|
@ -35,6 +35,8 @@ namespace Ryujinx.HLE.HOS.SystemState
|
||||||
"AudioBuiltInSpeakerOutput"
|
"AudioBuiltInSpeakerOutput"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal long DesiredKeyboardLayout { get; private set; }
|
||||||
|
|
||||||
internal long DesiredLanguageCode { get; private set; }
|
internal long DesiredLanguageCode { get; private set; }
|
||||||
|
|
||||||
internal uint DesiredRegionCode { get; private set; }
|
internal uint DesiredRegionCode { get; private set; }
|
||||||
|
@ -59,6 +61,9 @@ namespace Ryujinx.HLE.HOS.SystemState
|
||||||
|
|
||||||
Account.AddUser(DefaultUserId, "Player");
|
Account.AddUser(DefaultUserId, "Player");
|
||||||
Account.OpenUser(DefaultUserId);
|
Account.OpenUser(DefaultUserId);
|
||||||
|
|
||||||
|
// TODO: Let user specify.
|
||||||
|
DesiredKeyboardLayout = (long)KeyboardLayout.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLanguage(SystemLanguage language)
|
public void SetLanguage(SystemLanguage language)
|
||||||
|
@ -81,7 +86,7 @@ namespace Ryujinx.HLE.HOS.SystemState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRegion(SystemRegion region)
|
public void SetRegion(RegionCode region)
|
||||||
{
|
{
|
||||||
DesiredRegionCode = (uint)region;
|
DesiredRegionCode = (uint)region;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace Ryujinx.HLE
|
||||||
{
|
{
|
||||||
System.State.SetLanguage((SystemLanguage)ConfigurationState.Instance.System.Language.Value);
|
System.State.SetLanguage((SystemLanguage)ConfigurationState.Instance.System.Language.Value);
|
||||||
|
|
||||||
System.State.SetRegion((SystemRegion)ConfigurationState.Instance.System.Region.Value);
|
System.State.SetRegion((RegionCode)ConfigurationState.Instance.System.Region.Value);
|
||||||
|
|
||||||
EnableDeviceVsync = ConfigurationState.Instance.Graphics.EnableVsync;
|
EnableDeviceVsync = ConfigurationState.Instance.Graphics.EnableVsync;
|
||||||
|
|
||||||
|
|
Reference in a new issue