Mesen-SX/Windows/WindowsKeyManager.cpp

460 lines
13 KiB
C++
Raw Normal View History

2019-02-13 14:10:36 -05:00
#include "stdafx.h"
#include "WindowsKeyManager.h"
static vector<KeyDefinition> _keyDefinitions = {
//{ "VK_LBUTTON", 0x01, "Left mouse button", "" },
//{ "VK_RBUTTON", 0x02, "Right mouse button", "" },
2020-12-19 23:33:11 +03:00
{"VK_CANCEL", 0x03, "Control-break processing", ""},
2019-02-13 14:10:36 -05:00
//{ "VK_MBUTTON", 0x04, "Middle mouse button (three-button mouse)", "" },
//{ "VK_XBUTTON1", 0x05, "X1 mouse button", "" },
//{ "VK_XBUTTON2", 0x06, "X2 mouse button", "" },
2020-12-19 23:33:11 +03:00
{"-", 0x07, "Undefined", ""},
{"VK_BACK", 0x08, "Backspace", ""},
{"VK_TAB", 0x09, "Tab", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0x0A - 0B, "Reserved", "" },
2020-12-19 23:33:11 +03:00
{"VK_CLEAR", 0x0C, "Numpad 5", ""},
{"VK_RETURN", 0x0D, "Enter", "Numpad Enter"},
2019-02-13 14:10:36 -05:00
//{ "-", 0x0E - 0F, "Undefined", "" },
2020-12-19 23:33:11 +03:00
{"VK_SHIFT", 0x10, "Shift", ""},
{"VK_CONTROL", 0x11, "Ctrl", ""},
{"VK_MENU", 0x12, "Alt", ""},
{"VK_PAUSE", 0x13, "Pause", ""},
{"VK_CAPITAL", 0x14, "Caps Lock", ""},
{"VK_KANA", 0x15, "IME Kana mode", ""},
{"VK_HANGUEL", 0x15, "IME Hanguel mode", ""},
{"VK_HANGUL", 0x15, "IME Hangul mode", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0x16, "Undefined", "" },
2020-12-19 23:33:11 +03:00
{"VK_JUNJA", 0x17, "IME Junja mode", ""},
{"VK_FINAL", 0x18, "IME final mode", ""},
{"VK_HANJA", 0x19, "IME Hanja mode", ""},
{"VK_KANJI", 0x19, "IME Kanji mode", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0x1A, "Undefined", "" },
2020-12-19 23:33:11 +03:00
{"VK_ESCAPE", 0x1B, "Esc", ""},
{"VK_CONVERT", 0x1C, "IME convert", ""},
{"VK_NONCONVERT", 0x1D, "IME nonconvert", ""},
{"VK_ACCEPT", 0x1E, "IME accept", ""},
{"VK_MODECHANGE", 0x1F, "IME mode change request", ""},
{"VK_SPACE", 0x20, "Spacebar", ""},
{"VK_PRIOR", 0x21, "Numpad 9", "Page Up"},
{"VK_NEXT", 0x22, "Numpad 3", "Page Down"},
{"VK_END", 0x23, "Numpad 1", "End"},
{"VK_HOME", 0x24, "Numpad 7", "Home"},
{"VK_LEFT", 0x25, "Numpad 4", "Left Arrow"},
{"VK_UP", 0x26, "Numpad 8", "Up Arrow"},
{"VK_RIGHT", 0x27, "Numpad 6", "Right Arrow"},
{"VK_DOWN", 0x28, "Numpad 2", "Down Arrow"},
{"VK_SELECT", 0x29, "Select", ""},
{"VK_PRINT", 0x2A, "Print", ""},
{"VK_EXECUTE", 0x2B, "Execute", ""},
{"VK_SNAPSHOT", 0x2C, "Print Screen", ""},
{"VK_INSERT", 0x2D, "Numpad 0", "Insert"},
{"VK_DELETE", 0x2E, "Numpad .", "Delete"},
{"VK_HELP", 0x2F, "Help", ""},
{"0", 0x30, "0", ""},
{"1", 0x31, "1", ""},
{"2", 0x32, "2", ""},
{"3", 0x33, "3", ""},
{"4", 0x34, "4", ""},
{"5", 0x35, "5", ""},
{"6", 0x36, "6", ""},
{"7", 0x37, "7", ""},
{"8", 0x38, "8", ""},
{"9", 0x39, "9", ""},
2019-02-13 14:10:36 -05:00
//{ "undefined", 0x3A - 40, "undefined", "" },
2020-12-19 23:33:11 +03:00
{"A", 0x41, "A", ""},
{"B", 0x42, "B", ""},
{"C", 0x43, "C", ""},
{"D", 0x44, "D", ""},
{"E", 0x45, "E", ""},
{"F", 0x46, "F", ""},
{"G", 0x47, "G", ""},
{"H", 0x48, "H", ""},
{"I", 0x49, "I", ""},
{"J", 0x4A, "J", ""},
{"K", 0x4B, "K", ""},
{"L", 0x4C, "L", ""},
{"M", 0x4D, "M", ""},
{"N", 0x4E, "N", ""},
{"O", 0x4F, "O", ""},
{"P", 0x50, "P", ""},
{"Q", 0x51, "Q", ""},
{"R", 0x52, "R", ""},
{"S", 0x53, "S", ""},
{"T", 0x54, "T", ""},
{"U", 0x55, "U", ""},
{"V", 0x56, "V", ""},
{"W", 0x57, "W", ""},
{"X", 0x58, "X", ""},
{"Y", 0x59, "Y", ""},
{"Z", 0x5A, "Z", ""},
{"VK_LWIN", 0x5B, "Left Windows", ""},
{"VK_RWIN", 0x5C, "Right Windows", ""},
{"VK_APPS", 0x5D, "Applications Key", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0x5E, "Reserved", "" },
2020-12-19 23:33:11 +03:00
{"VK_SLEEP", 0x5F, "Computer Sleep", ""},
{"VK_NUMPAD0", 0x60, "Keypad 0", ""},
{"VK_NUMPAD1", 0x61, "Keypad 1", ""},
{"VK_NUMPAD2", 0x62, "Keypad 2", ""},
{"VK_NUMPAD3", 0x63, "Keypad 3", ""},
{"VK_NUMPAD4", 0x64, "Keypad 4", ""},
{"VK_NUMPAD5", 0x65, "Keypad 5", ""},
{"VK_NUMPAD6", 0x66, "Keypad 6", ""},
{"VK_NUMPAD7", 0x67, "Keypad 7", ""},
{"VK_NUMPAD8", 0x68, "Keypad 8", ""},
{"VK_NUMPAD9", 0x69, "Keypad 9", ""},
{"VK_MULTIPLY", 0x6A, "Numpad *", ""},
{"VK_ADD", 0x6B, "Numpad +", ""},
{"VK_SEPARATOR", 0x6C, "Separator", ""},
{"VK_SUBTRACT", 0x6D, "Numpad -", ""},
{"VK_DECIMAL", 0x6E, "Decimal", ""},
{"VK_DIVIDE", 0x6F, "Numpad /", ""},
{"VK_F1", 0x70, "F1", ""},
{"VK_F2", 0x71, "F2", ""},
{"VK_F3", 0x72, "F3", ""},
{"VK_F4", 0x73, "F4", ""},
{"VK_F5", 0x74, "F5", ""},
{"VK_F6", 0x75, "F6", ""},
{"VK_F7", 0x76, "F7", ""},
{"VK_F8", 0x77, "F8", ""},
{"VK_F9", 0x78, "F9", ""},
{"VK_F10", 0x79, "F10", ""},
{"VK_F11", 0x7A, "F11", ""},
{"VK_F12", 0x7B, "F12", ""},
{"VK_F13", 0x7C, "F13", ""},
{"VK_F14", 0x7D, "F14", ""},
{"VK_F15", 0x7E, "F15", ""},
{"VK_F16", 0x7F, "F16", ""},
{"VK_F17", 0x80, "F17", ""},
{"VK_F18", 0x81, "F18", ""},
{"VK_F19", 0x82, "F19", ""},
{"VK_F20", 0x83, "F20", ""},
{"VK_F21", 0x84, "F21", ""},
{"VK_F22", 0x85, "F22", ""},
{"VK_F23", 0x86, "F23", ""},
{"VK_F24", 0x87, "F24", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0x88 - 8F, "Unassigned", "" },
2020-12-19 23:33:11 +03:00
{"VK_NUMLOCK", 0x90, "Pause", "Num Lock"},
{"VK_SCROLL", 0x91, "Scroll Lock", ""},
2019-02-13 14:10:36 -05:00
//{"-", 0x92-96,"OEM specific"},
//{ "-", 0x97 - 9F, "Unassigned", "" },
2020-12-19 23:33:11 +03:00
{"VK_LSHIFT", 0xA0, "Left Shift", ""},
{"VK_RSHIFT", 0xA1, "Right Shift", ""},
{"VK_LCONTROL", 0xA2, "Left Control", ""},
{"VK_RCONTROL", 0xA3, "Right Control", ""},
{"VK_LMENU", 0xA4, "Left Menu", ""},
{"VK_RMENU", 0xA5, "Right Menu", ""},
{"VK_BROWSER_BACK", 0xA6, "Browser Back", ""},
{"VK_BROWSER_FORWARD", 0xA7, "Browser Forward", ""},
{"VK_BROWSER_REFRESH", 0xA8, "Browser Refresh", ""},
{"VK_BROWSER_STOP", 0xA9, "Browser Stop", ""},
{"VK_BROWSER_SEARCH", 0xAA, "Browser Search", ""},
{"VK_BROWSER_FAVORITES", 0xAB, "Browser Favorites", ""},
{"VK_BROWSER_HOME", 0xAC, "Browser Start and Home", ""},
{"VK_VOLUME_MUTE", 0xAD, "Volume Mute", ""},
{"VK_VOLUME_DOWN", 0xAE, "Volume Down", ""},
{"VK_VOLUME_UP", 0xAF, "Volume Up", ""},
{"VK_MEDIA_NEXT_TRACK", 0xB0, "Next Track", ""},
{"VK_MEDIA_PREV_TRACK", 0xB1, "Previous Track", ""},
{"VK_MEDIA_STOP", 0xB2, "Stop Media", ""},
{"VK_MEDIA_PLAY_PAUSE", 0xB3, "Play/Pause Media", ""},
{"VK_LAUNCH_MAIL", 0xB4, "Start Mail", ""},
{"VK_LAUNCH_MEDIA_SELECT", 0xB5, "Select Media", ""},
{"VK_LAUNCH_APP1", 0xB6, "Start Application 1", ""},
{"VK_LAUNCH_APP2", 0xB7, "Start Application 2", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0xB8 - B9, "Reserved", "" },
2020-12-19 23:33:11 +03:00
{"VK_OEM_1", 0xBA, ";", ""},
{"VK_OEM_PLUS", 0xBB, "=", ""},
{"VK_OEM_COMMA", 0xBC, ",", ""},
{"VK_OEM_MINUS", 0xBD, "-", ""},
{"VK_OEM_PERIOD", 0xBE, ".", ""},
{"VK_OEM_2", 0xBF, "/", "Numpad /"},
{"VK_OEM_3", 0xC0, "`", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0xC1 - D7, "Reserved", "" },
//{ "-", 0xD8 - DA, "Unassigned", "" },
2020-12-19 23:33:11 +03:00
{"VK_OEM_4", 0xDB, "[", ""},
{"VK_OEM_5", 0xDC, "\\", ""},
{"VK_OEM_6", 0xDD, "]", ""},
{"VK_OEM_7", 0xDE, "'", ""},
{"VK_OEM_8", 0xDF, "Used for miscellaneous characters; it can vary by keyboard.", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0xE0, "Reserved", "" },
//{ "-", 0xE1, "OEM specific", "" },
2020-12-19 23:33:11 +03:00
{"VK_OEM_102", 0xE2, "Pipe", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0xE3 - E4, "OEM specific", "" },
2020-12-19 23:33:11 +03:00
{"VK_PROCESSKEY", 0xE5, "IME PROCESS", ""},
2019-02-13 14:10:36 -05:00
//{ "-", 0xE6, "OEM specific", "" },
2020-12-19 23:33:11 +03:00
{
"VK_PACKET", 0xE7,
"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP",
""
},
2019-02-13 14:10:36 -05:00
//{ "-", 0xE8, "Unassigned", "" },
// {"-",0xE6,"OEM specific"},
2020-12-19 23:33:11 +03:00
{
"VK_PACKET", 0xE7,
"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP",
""
},
2019-02-13 14:10:36 -05:00
// {"-",0xE8,"Unassigned"},
//{ "-", 0xE9 - F5, "OEM specific", "" },
2020-12-19 23:33:11 +03:00
{"VK_ATTN", 0xF6, "Attn", ""},
{"VK_CRSEL", 0xF7, "CrSel", ""},
{"VK_EXSEL", 0xF8, "ExSel", ""},
{"VK_EREOF", 0xF9, "Erase EOF", "Menu"},
{"VK_PLAY", 0xFA, "Play", ""},
{"VK_ZOOM", 0xFB, "Zoom", ""},
{"VK_NONAME", 0xFC, "Reserved", ""},
{"VK_PA1", 0xFD, "PA1", ""},
{"VK_OEM_CLEAR", 0xFE, "Clear", ""}
2019-02-13 14:10:36 -05:00
};
WindowsKeyManager::WindowsKeyManager(shared_ptr<Console> console, HWND hWnd)
{
_console = console;
_hWnd = hWnd;
ResetKeyState();
//Init XInput buttons
2020-12-19 23:33:11 +03:00
vector<string> buttonNames = {
"Up", "Down", "Left", "Right", "Start", "Back", "L3", "R3", "L1", "R1", "?", "?", "A", "B", "X", "Y", "L2", "R2",
"RT Up", "RT Down", "RT Left", "RT Right", "LT Up", "LT Down", "LT Left", "LT Right"
};
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < (int)buttonNames.size(); j++)
{
_keyDefinitions.push_back({
"", (uint32_t)(0xFFFF + i * 0x100 + j + 1), "Pad" + std::to_string(i + 1) + " " + buttonNames[j]
});
2019-02-13 14:10:36 -05:00
}
}
//Init DirectInput buttons
2020-12-19 23:33:11 +03:00
vector<string> diButtonNames = {
"Y+", "Y-", "X-", "X+", "Y2+", "Y2-", "X2-", "X2+", "Z+", "Z-", "Z2+", "Z2-", "DPad Up", "DPad Down",
"DPad Right", "DPad Left"
};
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < (int)diButtonNames.size(); j++)
{
_keyDefinitions.push_back({
"", (uint32_t)(0x11000 + i * 0x100 + j), "Joy" + std::to_string(i + 1) + " " + diButtonNames[j]
});
2019-02-13 14:10:36 -05:00
}
2020-12-19 23:33:11 +03:00
for (int j = 0; j < 128; j++)
{
_keyDefinitions.push_back({
"", (uint32_t)(0x11000 + i * 0x100 + j + 0x10),
"Joy" + std::to_string(i + 1) + " But" + std::to_string(j + 1)
});
2019-02-13 14:10:36 -05:00
}
}
2020-12-19 23:33:11 +03:00
for (KeyDefinition& keyDef : _keyDefinitions)
{
2019-02-13 14:10:36 -05:00
_keyNames[keyDef.keyCode] = keyDef.description;
2020-12-19 23:33:11 +03:00
_keyExtendedNames[keyDef.keyCode | 0x100] = keyDef.extDescription.empty()
? "Ext " + keyDef.description
: keyDef.extDescription;
_keyCodes[keyDef.description] = keyDef.keyCode;
2020-12-19 23:33:11 +03:00
if (!keyDef.extDescription.empty())
{
_keyCodes[keyDef.extDescription] = 0x100 | (keyDef.keyCode);
2019-02-13 14:10:36 -05:00
}
}
2020-12-19 23:33:11 +03:00
2019-02-13 14:10:36 -05:00
StartUpdateDeviceThread();
}
WindowsKeyManager::~WindowsKeyManager()
{
_stopUpdateDeviceThread = true;
_stopSignal.Signal();
_updateDeviceThread.join();
}
void WindowsKeyManager::StartUpdateDeviceThread()
{
2020-12-19 23:33:11 +03:00
_updateDeviceThread = std::thread([=]()
{
2019-02-13 14:10:36 -05:00
_xInput.reset(new XInputManager(_console));
_directInput.reset(new DirectInputManager(_console, _hWnd));
2020-12-19 23:33:11 +03:00
while (!_stopUpdateDeviceThread)
{
//Check for newly plugged in XInput controllers every 5 secs
//Do not check for DirectInput controllers because this takes more time and sometimes causes issues/freezes
2020-12-19 23:33:11 +03:00
if (_xInput->NeedToUpdate())
{
2019-02-13 14:10:36 -05:00
_xInput->UpdateDeviceList();
}
_stopSignal.Wait(5000);
}
});
}
void WindowsKeyManager::RefreshState()
{
2020-12-19 23:33:11 +03:00
if (!_xInput || !_directInput)
{
2019-02-13 14:10:36 -05:00
return;
}
_xInput->RefreshState();
_directInput->RefreshState();
}
bool WindowsKeyManager::IsKeyPressed(uint32_t key)
{
2020-12-19 23:33:11 +03:00
if (_disableAllKeys)
{
2019-02-13 14:10:36 -05:00
return false;
}
2020-12-19 23:33:11 +03:00
if (key >= 0x10000)
{
if (!_xInput || !_directInput)
{
2019-02-13 14:10:36 -05:00
return false;
}
2020-12-19 23:33:11 +03:00
if (key >= 0x11000)
{
2019-02-13 14:10:36 -05:00
//Directinput key
uint8_t gamepadPort = (key - 0x11000) / 0x100;
uint8_t gamepadButton = (key - 0x11000) % 0x100;
return _directInput->IsPressed(gamepadPort, gamepadButton);
2020-12-19 23:33:11 +03:00
}
else
{
2019-02-13 14:10:36 -05:00
//XInput key
uint8_t gamepadPort = (key - 0xFFFF) / 0x100;
uint8_t gamepadButton = (key - 0xFFFF) % 0x100;
return _xInput->IsPressed(gamepadPort, gamepadButton);
}
2020-12-19 23:33:11 +03:00
}
else if (key < 0x200)
{
2019-02-13 14:10:36 -05:00
return _keyState[key] != 0;
}
return false;
}
bool WindowsKeyManager::IsMouseButtonPressed(MouseButton button)
{
2020-12-19 23:33:11 +03:00
switch (button)
{
case MouseButton::LeftButton: return _mouseState[0];
case MouseButton::RightButton: return _mouseState[1];
case MouseButton::MiddleButton: return _mouseState[2];
2019-02-13 14:10:36 -05:00
}
return false;
}
vector<uint32_t> WindowsKeyManager::GetPressedKeys()
{
vector<uint32_t> result;
2020-12-19 23:33:11 +03:00
if (!_xInput || !_directInput)
{
2019-02-13 14:10:36 -05:00
return result;
}
_xInput->RefreshState();
2020-12-19 23:33:11 +03:00
for (int i = 0; i < XUSER_MAX_COUNT; i++)
{
for (int j = 1; j <= 26; j++)
{
if (_xInput->IsPressed(i, j))
{
2019-02-13 14:10:36 -05:00
result.push_back(0xFFFF + i * 0x100 + j);
}
}
}
_directInput->RefreshState();
2020-12-19 23:33:11 +03:00
for (int i = _directInput->GetJoystickCount() - 1; i >= 0; i--)
{
for (int j = 0; j < 16 + 128; j++)
{
if (_directInput->IsPressed(i, j))
{
2019-02-13 14:10:36 -05:00
result.push_back(0x11000 + i * 0x100 + j);
}
}
}
2020-12-19 23:33:11 +03:00
for (int i = 0; i < 0x200; i++)
{
if (_keyState[i])
{
2019-02-13 14:10:36 -05:00
result.push_back(i);
}
}
return result;
}
string WindowsKeyManager::GetKeyName(uint32_t keyCode)
2019-02-13 14:10:36 -05:00
{
bool extendedKey = (keyCode <= 0xFFFF && (keyCode & 0x100));
2019-02-13 14:10:36 -05:00
auto keyDef = (extendedKey ? _keyExtendedNames : _keyNames).find(keyCode);
2020-12-19 23:33:11 +03:00
if (keyDef != (extendedKey ? _keyExtendedNames : _keyNames).end())
{
2019-02-13 14:10:36 -05:00
return keyDef->second;
}
return "";
}
uint32_t WindowsKeyManager::GetKeyCode(string keyName)
{
auto keyDef = _keyCodes.find(keyName);
2020-12-19 23:33:11 +03:00
if (keyDef != _keyCodes.end())
{
2019-02-13 14:10:36 -05:00
return keyDef->second;
}
return 0;
}
void WindowsKeyManager::UpdateDevices()
{
2020-12-19 23:33:11 +03:00
if (!_xInput || !_directInput)
{
2019-02-13 14:10:36 -05:00
return;
}
_xInput->UpdateDeviceList();
_directInput->UpdateDeviceList();
}
void WindowsKeyManager::SetKeyState(uint16_t scanCode, bool state)
{
2020-12-19 23:33:11 +03:00
if (scanCode > 0x1FF)
{
2019-02-13 14:10:36 -05:00
_mouseState[scanCode & 0x03] = state;
2020-12-19 23:33:11 +03:00
}
else
{
uint32_t keyCode = MapVirtualKeyEx(scanCode & 0xFF, MAPVK_VSC_TO_VK, GetKeyboardLayout(0));
2020-12-19 23:33:11 +03:00
if (keyCode >= 0x10 && keyCode <= 0x12)
{
2019-02-13 14:10:36 -05:00
//Ignore "ext" flag for alt, ctrl & shift
scanCode = MapVirtualKeyEx(keyCode, MAPVK_VK_TO_VSC, GetKeyboardLayout(0));
2019-02-13 14:10:36 -05:00
}
_keyState[keyCode | (scanCode & 0x100)] = state;
2019-02-13 14:10:36 -05:00
}
}
void WindowsKeyManager::SetDisabled(bool disabled)
{
_disableAllKeys = disabled;
}
void WindowsKeyManager::ResetKeyState()
{
memset(_mouseState, 0, sizeof(_mouseState));
memset(_keyState, 0, sizeof(_keyState));
2020-12-19 23:33:11 +03:00
}