Skip to content
Permalink
Browse files

IOS/USB_KBD: Make key code lookup tables immutable and internally linked

These aren't modified by the class, nor do they directly need anything
related to the class state, so they can solely live within the cpp file,
hidden from external view, and also be made const, so the compiler can
place it within the read-only segment.
  • Loading branch information...
lioncash committed May 31, 2019
1 parent 00ecfb3 commit 64564e337b23b4d3099b18496bb1391fb9df5e95
Showing with 153 additions and 155 deletions.
  1. +153 −153 Source/Core/Core/IOS/USB/USB_KBD.cpp
  2. +0 −2 Source/Core/Core/IOS/USB/USB_KBD.h
@@ -4,6 +4,7 @@

#include "Core/IOS/USB/USB_KBD.h"

#include <array>
#include <cstring>
#include <queue>

@@ -22,156 +23,11 @@

namespace IOS::HLE::Device
{
USB_KBD::SMessageData::SMessageData(u32 type, u8 modifiers, u8* pressed_keys)
namespace
{
MsgType = Common::swap32(type);
Unk1 = 0; // swapped
Modifiers = modifiers;
Unk2 = 0;

if (pressed_keys) // Doesn't need to be in a specific order
memcpy(PressedKeys, pressed_keys, sizeof(PressedKeys));
else
memset(PressedKeys, 0, sizeof(PressedKeys));
}

// TODO: support in netplay/movies.

USB_KBD::USB_KBD(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{
}

IPCCommandResult USB_KBD::Open(const OpenRequest& request)
{
INFO_LOG(IOS, "USB_KBD: Open");
IniFile ini;
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
ini.GetOrCreateSection("USB Keyboard")->Get("Layout", &m_KeyboardLayout, KBD_LAYOUT_QWERTY);

m_MessageQueue = std::queue<SMessageData>();
for (bool& pressed : m_OldKeyBuffer)
{
pressed = false;
}

m_OldModifiers = 0x00;

// m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, nullptr));
return Device::Open(request);
}

IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)
{
// Stubbed.
return GetDefaultReply(IPC_SUCCESS);
}

IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request)
{
if (SConfig::GetInstance().m_WiiKeyboard && !Core::WantsDeterminism() &&
ControlReference::InputGateOn() && !m_MessageQueue.empty())
{
Memory::CopyToEmu(request.buffer_out, &m_MessageQueue.front(), sizeof(SMessageData));
m_MessageQueue.pop();
}
return GetDefaultReply(IPC_SUCCESS);
}

bool USB_KBD::IsKeyPressed(int _Key)
{
#ifdef _WIN32
if (GetAsyncKeyState(_Key) & 0x8000)
return true;
else
return false;
#else
// TODO: do it for non-Windows platforms
return false;
#endif
}

void USB_KBD::Update()
{
if (!SConfig::GetInstance().m_WiiKeyboard || Core::WantsDeterminism() || !m_is_active)
return;

u8 Modifiers = 0x00;
u8 PressedKeys[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool GotEvent = false;
int num_pressed_keys = 0;
for (int i = 0; i < 256; i++)
{
bool KeyPressedNow = IsKeyPressed(i);
bool KeyPressedBefore = m_OldKeyBuffer[i];
u8 KeyCode = 0;

if (KeyPressedNow ^ KeyPressedBefore)
{
if (KeyPressedNow)
{
switch (m_KeyboardLayout)
{
case KBD_LAYOUT_QWERTY:
KeyCode = m_KeyCodesQWERTY[i];
break;

case KBD_LAYOUT_AZERTY:
KeyCode = m_KeyCodesAZERTY[i];
break;
}

if (KeyCode == 0x00)
continue;

PressedKeys[num_pressed_keys] = KeyCode;

num_pressed_keys++;
if (num_pressed_keys == 6)
break;
}

GotEvent = true;
}

m_OldKeyBuffer[i] = KeyPressedNow;
}

#ifdef _WIN32
if (GetAsyncKeyState(VK_LCONTROL) & 0x8000)
Modifiers |= 0x01;
if (GetAsyncKeyState(VK_LSHIFT) & 0x8000)
Modifiers |= 0x02;
if (GetAsyncKeyState(VK_MENU) & 0x8000)
Modifiers |= 0x04;
if (GetAsyncKeyState(VK_LWIN) & 0x8000)
Modifiers |= 0x08;
if (GetAsyncKeyState(VK_RCONTROL) & 0x8000)
Modifiers |= 0x10;
if (GetAsyncKeyState(VK_RSHIFT) & 0x8000)
Modifiers |= 0x20;
if (GetAsyncKeyState(VK_MENU) &
0x8000) // TODO: VK_MENU is for ALT, not for ALT GR (ALT GR seems to work though...)
Modifiers |= 0x40;
if (GetAsyncKeyState(VK_RWIN) & 0x8000)
Modifiers |= 0x80;
#else
// TODO: modifiers for non-Windows platforms
#endif

if (Modifiers ^ m_OldModifiers)
{
GotEvent = true;
m_OldModifiers = Modifiers;
}

if (GotEvent)
m_MessageQueue.push(SMessageData(MSG_EVENT, Modifiers, PressedKeys));
}

// Crazy ugly
#ifdef _WIN32
u8 USB_KBD::m_KeyCodesQWERTY[256] = {

constexpr std::array<u8, 256> s_key_codes_qwerty{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2A, // Backspace
0x2B, // Tab
@@ -241,11 +97,9 @@ u8 USB_KBD::m_KeyCodesQWERTY[256] = {
0x34, // '''
0x00, //
0x00, // Nothing interesting past this point.

};

u8 USB_KBD::m_KeyCodesAZERTY[256] = {

constexpr std::array<u8, 256> s_key_codes_azerty{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2A, // Backspace
0x2B, // Tab
@@ -315,11 +169,157 @@ u8 USB_KBD::m_KeyCodesAZERTY[256] = {
0x00, // ' '
0x38, // '!'
0x00, // Nothing interesting past this point.

};
#else
u8 USB_KBD::m_KeyCodesQWERTY[256] = {0};
constexpr std::array<u8, 256> s_key_codes_qwerty{};

u8 USB_KBD::m_KeyCodesAZERTY[256] = {0};
constexpr std::array<u8, 256> s_key_codes_azerty{};
#endif
} // Anonymous namespace

USB_KBD::SMessageData::SMessageData(u32 type, u8 modifiers, u8* pressed_keys)
{
MsgType = Common::swap32(type);
Unk1 = 0; // swapped
Modifiers = modifiers;
Unk2 = 0;

if (pressed_keys) // Doesn't need to be in a specific order
memcpy(PressedKeys, pressed_keys, sizeof(PressedKeys));
else
memset(PressedKeys, 0, sizeof(PressedKeys));
}

// TODO: support in netplay/movies.

USB_KBD::USB_KBD(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{
}

IPCCommandResult USB_KBD::Open(const OpenRequest& request)
{
INFO_LOG(IOS, "USB_KBD: Open");
IniFile ini;
ini.Load(File::GetUserPath(F_DOLPHINCONFIG_IDX));
ini.GetOrCreateSection("USB Keyboard")->Get("Layout", &m_KeyboardLayout, KBD_LAYOUT_QWERTY);

m_MessageQueue = std::queue<SMessageData>();
for (bool& pressed : m_OldKeyBuffer)
{
pressed = false;
}

m_OldModifiers = 0x00;

// m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, nullptr));
return Device::Open(request);
}

IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)
{
// Stubbed.
return GetDefaultReply(IPC_SUCCESS);
}

IPCCommandResult USB_KBD::IOCtl(const IOCtlRequest& request)
{
if (SConfig::GetInstance().m_WiiKeyboard && !Core::WantsDeterminism() &&
ControlReference::InputGateOn() && !m_MessageQueue.empty())
{
Memory::CopyToEmu(request.buffer_out, &m_MessageQueue.front(), sizeof(SMessageData));
m_MessageQueue.pop();
}
return GetDefaultReply(IPC_SUCCESS);
}

bool USB_KBD::IsKeyPressed(int _Key)
{
#ifdef _WIN32
if (GetAsyncKeyState(_Key) & 0x8000)
return true;
else
return false;
#else
// TODO: do it for non-Windows platforms
return false;
#endif
}

void USB_KBD::Update()
{
if (!SConfig::GetInstance().m_WiiKeyboard || Core::WantsDeterminism() || !m_is_active)
return;

u8 Modifiers = 0x00;
u8 PressedKeys[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool GotEvent = false;
int num_pressed_keys = 0;
for (int i = 0; i < 256; i++)
{
bool KeyPressedNow = IsKeyPressed(i);
bool KeyPressedBefore = m_OldKeyBuffer[i];
u8 KeyCode = 0;

if (KeyPressedNow ^ KeyPressedBefore)
{
if (KeyPressedNow)
{
switch (m_KeyboardLayout)
{
case KBD_LAYOUT_QWERTY:
KeyCode = s_key_codes_qwerty[i];
break;

case KBD_LAYOUT_AZERTY:
KeyCode = s_key_codes_azerty[i];
break;
}

if (KeyCode == 0x00)
continue;

PressedKeys[num_pressed_keys] = KeyCode;

num_pressed_keys++;
if (num_pressed_keys == 6)
break;
}

GotEvent = true;
}

m_OldKeyBuffer[i] = KeyPressedNow;
}

#ifdef _WIN32
if (GetAsyncKeyState(VK_LCONTROL) & 0x8000)
Modifiers |= 0x01;
if (GetAsyncKeyState(VK_LSHIFT) & 0x8000)
Modifiers |= 0x02;
if (GetAsyncKeyState(VK_MENU) & 0x8000)
Modifiers |= 0x04;
if (GetAsyncKeyState(VK_LWIN) & 0x8000)
Modifiers |= 0x08;
if (GetAsyncKeyState(VK_RCONTROL) & 0x8000)
Modifiers |= 0x10;
if (GetAsyncKeyState(VK_RSHIFT) & 0x8000)
Modifiers |= 0x20;
if (GetAsyncKeyState(VK_MENU) &
0x8000) // TODO: VK_MENU is for ALT, not for ALT GR (ALT GR seems to work though...)
Modifiers |= 0x40;
if (GetAsyncKeyState(VK_RWIN) & 0x8000)
Modifiers |= 0x80;
#else
// TODO: modifiers for non-Windows platforms
#endif

if (Modifiers ^ m_OldModifiers)
{
GotEvent = true;
m_OldModifiers = Modifiers;
}

if (GotEvent)
m_MessageQueue.push(SMessageData(MSG_EVENT, Modifiers, PressedKeys));
}
} // namespace IOS::HLE::Device
@@ -57,7 +57,5 @@ class USB_KBD : public Device
KBD_LAYOUT_AZERTY = 1
};
int m_KeyboardLayout;
static u8 m_KeyCodesQWERTY[256];
static u8 m_KeyCodesAZERTY[256];
};
} // namespace IOS::HLE::Device

0 comments on commit 64564e3

Please sign in to comment.
You can’t perform that action at this time.