You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
911 lines
26 KiB
911 lines
26 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//===========================================================================//
|
|
|
|
|
|
#if defined( WIN32 )
|
|
#if !defined( _X360 )
|
|
#include <wtypes.h>
|
|
#include <winuser.h>
|
|
#include "xbox/xboxstubs.h"
|
|
#else
|
|
#include "xbox/xbox_win32stubs.h"
|
|
#endif
|
|
#endif // WIN32
|
|
|
|
#include "key_translation.h"
|
|
#include "tier1/convar.h"
|
|
#include "tier1/strtools.h"
|
|
#include "tier0/dbg.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#if defined(__clang__)
|
|
#pragma GCC diagnostic ignored "-Wchar-subscripts"
|
|
#endif
|
|
|
|
static ButtonCode_t s_pVirtualKeyToButtonCode[256];
|
|
|
|
static ButtonCode_t s_pSKeytoButtonCode[SK_MAX_KEYS];
|
|
|
|
#if !defined( POSIX )
|
|
static ButtonCode_t s_pXKeyTrans[XK_MAX_KEYS];
|
|
#endif
|
|
|
|
#define SCONTROLLERBUTTONS_BUTTONS( x ) \
|
|
"SC_A",\
|
|
"SC_B",\
|
|
"SC_X",\
|
|
"SC_Y",\
|
|
"SC_DPAD_UP",\
|
|
"SC_DPAD_RIGHT",\
|
|
"SC_DPAD_DOWN",\
|
|
"SC_DPAD_LEFT",\
|
|
"SC_LEFT_BUMPER",\
|
|
"SC_RIGHT_BUMPER",\
|
|
"SC_LEFT_TRIGGER",\
|
|
"SC_RIGHT_TRIGGER",\
|
|
"SC_LEFT_GRIP",\
|
|
"SC_RIGHT_GRIP",\
|
|
"SC_LEFT_PAD_TOUCH",\
|
|
"SC_RIGHT_PAD_TOUCH",\
|
|
"SC_LEFT_PAD_CLICK",\
|
|
"SC_RIGHT_PAD_CLICK",\
|
|
"SC_LPAD_UP",\
|
|
"SC_LPAD_RIGHT",\
|
|
"SC_LPAD_DOWN",\
|
|
"SC_LPAD_LEFT",\
|
|
"SC_RPAD_UP",\
|
|
"SC_RPAD_RIGHT",\
|
|
"SC_RPAD_DOWN",\
|
|
"SC_RPAD_LEFT",\
|
|
"SC_SELECT",\
|
|
"SC_START",\
|
|
"SC_STEAM",\
|
|
"SC_NULL"
|
|
|
|
#define SCONTROLLERBUTTONS_AXIS( x ) \
|
|
"SC_LPAD_AXIS_RIGHT",\
|
|
"SC_LPAD_AXIS_LEFT",\
|
|
"SC_LPAD_AXIS_DOWN",\
|
|
"SC_LPAD_AXIS_UP",\
|
|
"SC_AXIS_L_TRIGGER",\
|
|
"SC_AXIS_R_TRIGGER",\
|
|
"SC_RPAD_AXIS_RIGHT",\
|
|
"SC_RPAD_AXIS_LEFT",\
|
|
"SC_RPAD_AXIS_DOWN",\
|
|
"SC_RPAD_AXIS_UP",\
|
|
"SC_GYRO_AXIS_PITCH_POSITIVE",\
|
|
"SC_GYRO_AXIS_PITCH_NEGATIVE",\
|
|
"SC_GYRO_AXIS_ROLL_POSITIVE",\
|
|
"SC_GYRO_AXIS_ROLL_NEGATIVE",\
|
|
"SC_GYRO_AXIS_YAW_POSITIVE",\
|
|
"SC_GYRO_AXIS_YAW_NEGATIVE"
|
|
|
|
#define SCONTROLLERBUTTONS_VBUTTONS( x ) \
|
|
"SC_F1",\
|
|
"SC_F2",\
|
|
"SC_F3",\
|
|
"SC_F4",\
|
|
"SC_F5",\
|
|
"SC_F6",\
|
|
"SC_F7",\
|
|
"SC_F8",\
|
|
"SC_F9",\
|
|
"SC_F10",\
|
|
"SC_F11",\
|
|
"SC_F12"
|
|
|
|
static int s_pButtonCodeToVirtual[BUTTON_CODE_LAST];
|
|
|
|
static const char *s_pButtonCodeName[ ] =
|
|
{
|
|
"", // KEY_NONE
|
|
"0", // KEY_0,
|
|
"1", // KEY_1,
|
|
"2", // KEY_2,
|
|
"3", // KEY_3,
|
|
"4", // KEY_4,
|
|
"5", // KEY_5,
|
|
"6", // KEY_6,
|
|
"7", // KEY_7,
|
|
"8", // KEY_8,
|
|
"9", // KEY_9,
|
|
"a", // KEY_A,
|
|
"b", // KEY_B,
|
|
"c", // KEY_C,
|
|
"d", // KEY_D,
|
|
"e", // KEY_E,
|
|
"f", // KEY_F,
|
|
"g", // KEY_G,
|
|
"h", // KEY_H,
|
|
"i", // KEY_I,
|
|
"j", // KEY_J,
|
|
"k", // KEY_K,
|
|
"l", // KEY_L,
|
|
"m", // KEY_M,
|
|
"n", // KEY_N,
|
|
"o", // KEY_O,
|
|
"p", // KEY_P,
|
|
"q", // KEY_Q,
|
|
"r", // KEY_R,
|
|
"s", // KEY_S,
|
|
"t", // KEY_T,
|
|
"u", // KEY_U,
|
|
"v", // KEY_V,
|
|
"w", // KEY_W,
|
|
"x", // KEY_X,
|
|
"y", // KEY_Y,
|
|
"z", // KEY_Z,
|
|
"KP_INS", // KEY_PAD_0,
|
|
"KP_END", // KEY_PAD_1,
|
|
"KP_DOWNARROW", // KEY_PAD_2,
|
|
"KP_PGDN", // KEY_PAD_3,
|
|
"KP_LEFTARROW", // KEY_PAD_4,
|
|
"KP_5", // KEY_PAD_5,
|
|
"KP_RIGHTARROW",// KEY_PAD_6,
|
|
"KP_HOME", // KEY_PAD_7,
|
|
"KP_UPARROW", // KEY_PAD_8,
|
|
"KP_PGUP", // KEY_PAD_9,
|
|
"KP_SLASH", // KEY_PAD_DIVIDE,
|
|
"KP_MULTIPLY", // KEY_PAD_MULTIPLY,
|
|
"KP_MINUS", // KEY_PAD_MINUS,
|
|
"KP_PLUS", // KEY_PAD_PLUS,
|
|
"KP_ENTER", // KEY_PAD_ENTER,
|
|
"KP_DEL", // KEY_PAD_DECIMAL,
|
|
"[", // KEY_LBRACKET,
|
|
"]", // KEY_RBRACKET,
|
|
"SEMICOLON", // KEY_SEMICOLON,
|
|
"'", // KEY_APOSTROPHE,
|
|
"`", // KEY_BACKQUOTE,
|
|
",", // KEY_COMMA,
|
|
".", // KEY_PERIOD,
|
|
"/", // KEY_SLASH,
|
|
"\\", // KEY_BACKSLASH,
|
|
"-", // KEY_MINUS,
|
|
"=", // KEY_EQUAL,
|
|
"ENTER", // KEY_ENTER,
|
|
"SPACE", // KEY_SPACE,
|
|
"BACKSPACE", // KEY_BACKSPACE,
|
|
"TAB", // KEY_TAB,
|
|
"CAPSLOCK", // KEY_CAPSLOCK,
|
|
"NUMLOCK", // KEY_NUMLOCK,
|
|
"ESCAPE", // KEY_ESCAPE,
|
|
"SCROLLLOCK", // KEY_SCROLLLOCK,
|
|
"INS", // KEY_INSERT,
|
|
"DEL", // KEY_DELETE,
|
|
"HOME", // KEY_HOME,
|
|
"END", // KEY_END,
|
|
"PGUP", // KEY_PAGEUP,
|
|
"PGDN", // KEY_PAGEDOWN,
|
|
"PAUSE", // KEY_BREAK,
|
|
"SHIFT", // KEY_LSHIFT,
|
|
"RSHIFT", // KEY_RSHIFT,
|
|
"ALT", // KEY_LALT,
|
|
"RALT", // KEY_RALT,
|
|
"CTRL", // KEY_LCONTROL,
|
|
"RCTRL", // KEY_RCONTROL,
|
|
"LWIN", // KEY_LWIN,
|
|
"RWIN", // KEY_RWIN,
|
|
"APP", // KEY_APP,
|
|
"UPARROW", // KEY_UP,
|
|
"LEFTARROW", // KEY_LEFT,
|
|
"DOWNARROW", // KEY_DOWN,
|
|
"RIGHTARROW", // KEY_RIGHT,
|
|
"F1", // KEY_F1,
|
|
"F2", // KEY_F2,
|
|
"F3", // KEY_F3,
|
|
"F4", // KEY_F4,
|
|
"F5", // KEY_F5,
|
|
"F6", // KEY_F6,
|
|
"F7", // KEY_F7,
|
|
"F8", // KEY_F8,
|
|
"F9", // KEY_F9,
|
|
"F10", // KEY_F10,
|
|
"F11", // KEY_F11,
|
|
"F12", // KEY_F12,
|
|
|
|
// FIXME: CAPSLOCK/NUMLOCK/SCROLLLOCK all appear above. What are these for?!
|
|
// They only appear in CInputWin32::UpdateToggleButtonState in vgui2
|
|
"CAPSLOCKTOGGLE", // KEY_CAPSLOCKTOGGLE,
|
|
"NUMLOCKTOGGLE", // KEY_NUMLOCKTOGGLE,
|
|
"SCROLLLOCKTOGGLE", // KEY_SCROLLLOCKTOGGLE,
|
|
|
|
// Mouse
|
|
"MOUSE1", // MOUSE_LEFT,
|
|
"MOUSE2", // MOUSE_RIGHT,
|
|
"MOUSE3", // MOUSE_MIDDLE,
|
|
"MOUSE4", // MOUSE_4,
|
|
"MOUSE5", // MOUSE_5,
|
|
|
|
"MWHEELUP", // MOUSE_WHEEL_UP
|
|
"MWHEELDOWN", // MOUSE_WHEEL_DOWN
|
|
|
|
#if defined ( _X360 ) || defined ( _LINUX )
|
|
"A_BUTTON", // JOYSTICK_FIRST_BUTTON
|
|
"B_BUTTON",
|
|
"X_BUTTON",
|
|
"Y_BUTTON",
|
|
"L_SHOULDER",
|
|
"R_SHOULDER",
|
|
"BACK",
|
|
"START",
|
|
"STICK1",
|
|
"STICK2",
|
|
#else
|
|
"JOY1", // JOYSTICK_FIRST_BUTTON
|
|
"JOY2",
|
|
"JOY3",
|
|
"JOY4",
|
|
"JOY5",
|
|
"JOY6",
|
|
"JOY7",
|
|
"JOY8",
|
|
"JOY9",
|
|
"JOY10",
|
|
#endif
|
|
|
|
"JOY11",
|
|
"JOY12",
|
|
"JOY13",
|
|
"JOY14",
|
|
"JOY15",
|
|
"JOY16",
|
|
"JOY17",
|
|
"JOY18",
|
|
"JOY19",
|
|
"JOY20",
|
|
"JOY21",
|
|
"JOY22",
|
|
"JOY23",
|
|
"JOY24",
|
|
"JOY25",
|
|
"JOY26",
|
|
"JOY27",
|
|
"JOY28",
|
|
"JOY29",
|
|
"JOY30",
|
|
"JOY31",
|
|
"JOY32", // JOYSTICK_LAST_BUTTON
|
|
|
|
#if defined ( _X360 )
|
|
"UP", // JOYSTICK_FIRST_POV_BUTTON
|
|
"RIGHT",
|
|
"DOWN",
|
|
"LEFT", // JOYSTICK_LAST_POV_BUTTON
|
|
|
|
"S1_RIGHT", // JOYSTICK_FIRST_AXIS_BUTTON
|
|
"S1_LEFT",
|
|
"S1_DOWN",
|
|
"S1_UP",
|
|
"L_TRIGGER",
|
|
"R_TRIGGER",
|
|
"S2_RIGHT",
|
|
"S2_LEFT",
|
|
"S2_DOWN",
|
|
"S2_UP", // JOYSTICK_LAST_AXIS_BUTTON
|
|
"V AXIS POS",
|
|
"V AXIS NEG",
|
|
#else
|
|
"POV_UP", // JOYSTICK_FIRST_POV_BUTTON
|
|
"POV_RIGHT",
|
|
"POV_DOWN",
|
|
"POV_LEFT", // JOYSTICK_LAST_POV_BUTTON
|
|
|
|
"X AXIS POS", // JOYSTICK_FIRST_AXIS_BUTTON
|
|
"X AXIS NEG",
|
|
"Y AXIS POS",
|
|
"Y AXIS NEG",
|
|
"Z AXIS POS",
|
|
"Z AXIS NEG",
|
|
"R AXIS POS",
|
|
"R AXIS NEG",
|
|
"U AXIS POS",
|
|
"U AXIS NEG",
|
|
"V AXIS POS",
|
|
"V AXIS NEG", // JOYSTICK_LAST_AXIS_BUTTON
|
|
"FALCON_NULL", // NVNT temp Fix for unaligned joystick enumeration
|
|
"FALCON_1", // NOVINT_FIRST
|
|
"FALCON_2",
|
|
"FALCON_3",
|
|
"FALCON_4",
|
|
"FALCON2_1",
|
|
"FALCON2_2",
|
|
"FALCON2_3",
|
|
"FALCON2_4", // NOVINT_LAST
|
|
#endif
|
|
|
|
SCONTROLLERBUTTONS_BUTTONS( 0 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 1 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 2 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 3 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 4 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 5 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 6 ),
|
|
SCONTROLLERBUTTONS_BUTTONS( 7 ),
|
|
|
|
SCONTROLLERBUTTONS_AXIS( 0 ),
|
|
SCONTROLLERBUTTONS_AXIS( 1 ),
|
|
SCONTROLLERBUTTONS_AXIS( 2 ),
|
|
SCONTROLLERBUTTONS_AXIS( 3 ),
|
|
SCONTROLLERBUTTONS_AXIS( 4 ),
|
|
SCONTROLLERBUTTONS_AXIS( 5 ),
|
|
SCONTROLLERBUTTONS_AXIS( 6 ),
|
|
SCONTROLLERBUTTONS_AXIS( 7 ),
|
|
|
|
SCONTROLLERBUTTONS_VBUTTONS( 0 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 1 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 2 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 3 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 4 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 5 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 6 ),
|
|
SCONTROLLERBUTTONS_VBUTTONS( 7 ),
|
|
};
|
|
|
|
static const char *s_pAnalogCodeName[ ] =
|
|
{
|
|
"MOUSE_X", // MOUSE_X = 0,
|
|
"MOUSE_Y", // MOUSE_Y,
|
|
"MOUSE_XY", // MOUSE_XY, // Invoked when either x or y changes
|
|
"MOUSE_WHEEL", // MOUSE_WHEEL,
|
|
|
|
"X AXIS", // JOY_AXIS_X
|
|
"Y AXIS", // JOY_AXIS_Y
|
|
"Z AXIS", // JOY_AXIS_Z
|
|
"R AXIS", // JOY_AXIS_R
|
|
"U AXIS", // JOY_AXIS_U
|
|
"V AXIS", // JOY_AXIS_V
|
|
};
|
|
|
|
#if !defined ( _X360 )
|
|
static const char *s_pXControllerButtonCodeNames[ ] =
|
|
{
|
|
"A_BUTTON", // JOYSTICK_FIRST_BUTTON
|
|
"B_BUTTON",
|
|
"X_BUTTON",
|
|
"Y_BUTTON",
|
|
"L_SHOULDER",
|
|
"R_SHOULDER",
|
|
"BACK",
|
|
"START",
|
|
"STICK1",
|
|
"STICK2",
|
|
"JOY11",
|
|
"JOY12",
|
|
"JOY13",
|
|
"JOY14",
|
|
"JOY15",
|
|
"JOY16",
|
|
"JOY17",
|
|
"JOY18",
|
|
"JOY19",
|
|
"JOY20",
|
|
"JOY21",
|
|
"JOY22",
|
|
"JOY23",
|
|
"JOY24",
|
|
"JOY25",
|
|
"JOY26",
|
|
"JOY27",
|
|
"JOY28",
|
|
"JOY29",
|
|
"JOY30",
|
|
"JOY31",
|
|
"JOY32", // JOYSTICK_LAST_BUTTON
|
|
|
|
"UP", // JOYSTICK_FIRST_POV_BUTTON
|
|
"RIGHT",
|
|
"DOWN",
|
|
"LEFT", // JOYSTICK_LAST_POV_BUTTON
|
|
|
|
"S1_RIGHT", // JOYSTICK_FIRST_AXIS_BUTTON
|
|
"S1_LEFT",
|
|
"S1_DOWN",
|
|
"S1_UP",
|
|
"L_TRIGGER",
|
|
"R_TRIGGER",
|
|
"S2_RIGHT",
|
|
"S2_LEFT",
|
|
"S2_DOWN",
|
|
"S2_UP", // JOYSTICK_LAST_AXIS_BUTTON
|
|
"V AXIS POS",
|
|
"V AXIS NEG",
|
|
};
|
|
#endif
|
|
|
|
// this maps non-translated keyboard scan codes to engine key codes
|
|
// Google for 'Keyboard Scan Code Specification'
|
|
static ButtonCode_t s_pScanToButtonCode_QWERTY[128] =
|
|
{
|
|
// 0 1 2 3 4 5 6 7
|
|
// 8 9 A B C D E F
|
|
KEY_NONE, KEY_ESCAPE, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, // 0
|
|
KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, // 0
|
|
|
|
KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, // 1
|
|
KEY_O, KEY_P, KEY_LBRACKET, KEY_RBRACKET, KEY_ENTER, KEY_LCONTROL, KEY_A, KEY_S, // 1
|
|
|
|
KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, // 2
|
|
KEY_APOSTROPHE, KEY_BACKQUOTE, KEY_LSHIFT, KEY_BACKSLASH, KEY_Z, KEY_X, KEY_C, KEY_V, // 2
|
|
|
|
KEY_B, KEY_N, KEY_M, KEY_COMMA, KEY_PERIOD, KEY_SLASH, KEY_RSHIFT, KEY_PAD_MULTIPLY,// 3
|
|
KEY_LALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, // 3
|
|
|
|
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_HOME, // 4
|
|
KEY_UP, KEY_PAGEUP, KEY_PAD_MINUS, KEY_LEFT, KEY_PAD_5, KEY_RIGHT, KEY_PAD_PLUS, KEY_END, // 4
|
|
|
|
KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_F11, // 5
|
|
KEY_F12, KEY_BREAK, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, // 5
|
|
|
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, // 6
|
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, // 6
|
|
|
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, // 7
|
|
KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE // 7
|
|
};
|
|
|
|
static ButtonCode_t s_pScanToButtonCode[128];
|
|
|
|
|
|
void ButtonCode_InitKeyTranslationTable()
|
|
{
|
|
COMPILE_TIME_ASSERT( sizeof(s_pButtonCodeName) / sizeof( const char * ) == BUTTON_CODE_LAST );
|
|
COMPILE_TIME_ASSERT( sizeof(s_pAnalogCodeName) / sizeof( const char * ) == ANALOG_CODE_LAST );
|
|
|
|
// set virtual key translation table
|
|
memset( s_pVirtualKeyToButtonCode, KEY_NONE, sizeof(s_pVirtualKeyToButtonCode) );
|
|
|
|
s_pVirtualKeyToButtonCode['0'] =KEY_0;
|
|
s_pVirtualKeyToButtonCode['1'] =KEY_1;
|
|
s_pVirtualKeyToButtonCode['2'] =KEY_2;
|
|
s_pVirtualKeyToButtonCode['3'] =KEY_3;
|
|
s_pVirtualKeyToButtonCode['4'] =KEY_4;
|
|
s_pVirtualKeyToButtonCode['5'] =KEY_5;
|
|
s_pVirtualKeyToButtonCode['6'] =KEY_6;
|
|
s_pVirtualKeyToButtonCode['7'] =KEY_7;
|
|
s_pVirtualKeyToButtonCode['8'] =KEY_8;
|
|
s_pVirtualKeyToButtonCode['9'] =KEY_9;
|
|
s_pVirtualKeyToButtonCode['A'] =KEY_A;
|
|
s_pVirtualKeyToButtonCode['B'] =KEY_B;
|
|
s_pVirtualKeyToButtonCode['C'] =KEY_C;
|
|
s_pVirtualKeyToButtonCode['D'] =KEY_D;
|
|
s_pVirtualKeyToButtonCode['E'] =KEY_E;
|
|
s_pVirtualKeyToButtonCode['F'] =KEY_F;
|
|
s_pVirtualKeyToButtonCode['G'] =KEY_G;
|
|
s_pVirtualKeyToButtonCode['H'] =KEY_H;
|
|
s_pVirtualKeyToButtonCode['I'] =KEY_I;
|
|
s_pVirtualKeyToButtonCode['J'] =KEY_J;
|
|
s_pVirtualKeyToButtonCode['K'] =KEY_K;
|
|
s_pVirtualKeyToButtonCode['L'] =KEY_L;
|
|
s_pVirtualKeyToButtonCode['M'] =KEY_M;
|
|
s_pVirtualKeyToButtonCode['N'] =KEY_N;
|
|
s_pVirtualKeyToButtonCode['O'] =KEY_O;
|
|
s_pVirtualKeyToButtonCode['P'] =KEY_P;
|
|
s_pVirtualKeyToButtonCode['Q'] =KEY_Q;
|
|
s_pVirtualKeyToButtonCode['R'] =KEY_R;
|
|
s_pVirtualKeyToButtonCode['S'] =KEY_S;
|
|
s_pVirtualKeyToButtonCode['T'] =KEY_T;
|
|
s_pVirtualKeyToButtonCode['U'] =KEY_U;
|
|
s_pVirtualKeyToButtonCode['V'] =KEY_V;
|
|
s_pVirtualKeyToButtonCode['W'] =KEY_W;
|
|
s_pVirtualKeyToButtonCode['X'] =KEY_X;
|
|
s_pVirtualKeyToButtonCode['Y'] =KEY_Y;
|
|
s_pVirtualKeyToButtonCode['Z'] =KEY_Z;
|
|
#if !defined( POSIX )
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD0] =KEY_PAD_0;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD1] =KEY_PAD_1;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD2] =KEY_PAD_2;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD3] =KEY_PAD_3;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD4] =KEY_PAD_4;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD5] =KEY_PAD_5;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD6] =KEY_PAD_6;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD7] =KEY_PAD_7;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD8] =KEY_PAD_8;
|
|
s_pVirtualKeyToButtonCode[VK_NUMPAD9] =KEY_PAD_9;
|
|
s_pVirtualKeyToButtonCode[VK_DIVIDE] =KEY_PAD_DIVIDE;
|
|
s_pVirtualKeyToButtonCode[VK_MULTIPLY] =KEY_PAD_MULTIPLY;
|
|
s_pVirtualKeyToButtonCode[VK_SUBTRACT] =KEY_PAD_MINUS;
|
|
s_pVirtualKeyToButtonCode[VK_ADD] =KEY_PAD_PLUS;
|
|
s_pVirtualKeyToButtonCode[VK_RETURN] =KEY_PAD_ENTER;
|
|
s_pVirtualKeyToButtonCode[VK_DECIMAL] =KEY_PAD_DECIMAL;
|
|
#endif
|
|
s_pVirtualKeyToButtonCode[0xdb] =KEY_LBRACKET;
|
|
s_pVirtualKeyToButtonCode[0xdd] =KEY_RBRACKET;
|
|
s_pVirtualKeyToButtonCode[0xba] =KEY_SEMICOLON;
|
|
s_pVirtualKeyToButtonCode[0xde] =KEY_APOSTROPHE;
|
|
s_pVirtualKeyToButtonCode[0xc0] =KEY_BACKQUOTE;
|
|
s_pVirtualKeyToButtonCode[0xbc] =KEY_COMMA;
|
|
s_pVirtualKeyToButtonCode[0xbe] =KEY_PERIOD;
|
|
s_pVirtualKeyToButtonCode[0xbf] =KEY_SLASH;
|
|
s_pVirtualKeyToButtonCode[0xdc] =KEY_BACKSLASH;
|
|
s_pVirtualKeyToButtonCode[0xbd] =KEY_MINUS;
|
|
s_pVirtualKeyToButtonCode[0xbb] =KEY_EQUAL;
|
|
#if !defined( POSIX )
|
|
s_pVirtualKeyToButtonCode[VK_RETURN] =KEY_ENTER;
|
|
s_pVirtualKeyToButtonCode[VK_SPACE] =KEY_SPACE;
|
|
s_pVirtualKeyToButtonCode[VK_BACK] =KEY_BACKSPACE;
|
|
s_pVirtualKeyToButtonCode[VK_TAB] =KEY_TAB;
|
|
s_pVirtualKeyToButtonCode[VK_CAPITAL] =KEY_CAPSLOCK;
|
|
s_pVirtualKeyToButtonCode[VK_NUMLOCK] =KEY_NUMLOCK;
|
|
s_pVirtualKeyToButtonCode[VK_ESCAPE] =KEY_ESCAPE;
|
|
s_pVirtualKeyToButtonCode[VK_SCROLL] =KEY_SCROLLLOCK;
|
|
s_pVirtualKeyToButtonCode[VK_INSERT] =KEY_INSERT;
|
|
s_pVirtualKeyToButtonCode[VK_DELETE] =KEY_DELETE;
|
|
s_pVirtualKeyToButtonCode[VK_HOME] =KEY_HOME;
|
|
s_pVirtualKeyToButtonCode[VK_END] =KEY_END;
|
|
s_pVirtualKeyToButtonCode[VK_PRIOR] =KEY_PAGEUP;
|
|
s_pVirtualKeyToButtonCode[VK_NEXT] =KEY_PAGEDOWN;
|
|
s_pVirtualKeyToButtonCode[VK_PAUSE] =KEY_BREAK;
|
|
s_pVirtualKeyToButtonCode[VK_SHIFT] =KEY_RSHIFT;
|
|
s_pVirtualKeyToButtonCode[VK_SHIFT] =KEY_LSHIFT; // SHIFT -> left SHIFT
|
|
s_pVirtualKeyToButtonCode[VK_MENU] =KEY_RALT;
|
|
s_pVirtualKeyToButtonCode[VK_MENU] =KEY_LALT; // ALT -> left ALT
|
|
s_pVirtualKeyToButtonCode[VK_CONTROL] =KEY_RCONTROL;
|
|
s_pVirtualKeyToButtonCode[VK_CONTROL] =KEY_LCONTROL; // CTRL -> left CTRL
|
|
s_pVirtualKeyToButtonCode[VK_LWIN] =KEY_LWIN;
|
|
s_pVirtualKeyToButtonCode[VK_RWIN] =KEY_RWIN;
|
|
s_pVirtualKeyToButtonCode[VK_APPS] =KEY_APP;
|
|
s_pVirtualKeyToButtonCode[VK_UP] =KEY_UP;
|
|
s_pVirtualKeyToButtonCode[VK_LEFT] =KEY_LEFT;
|
|
s_pVirtualKeyToButtonCode[VK_DOWN] =KEY_DOWN;
|
|
s_pVirtualKeyToButtonCode[VK_RIGHT] =KEY_RIGHT;
|
|
s_pVirtualKeyToButtonCode[VK_F1] =KEY_F1;
|
|
s_pVirtualKeyToButtonCode[VK_F2] =KEY_F2;
|
|
s_pVirtualKeyToButtonCode[VK_F3] =KEY_F3;
|
|
s_pVirtualKeyToButtonCode[VK_F4] =KEY_F4;
|
|
s_pVirtualKeyToButtonCode[VK_F5] =KEY_F5;
|
|
s_pVirtualKeyToButtonCode[VK_F6] =KEY_F6;
|
|
s_pVirtualKeyToButtonCode[VK_F7] =KEY_F7;
|
|
s_pVirtualKeyToButtonCode[VK_F8] =KEY_F8;
|
|
s_pVirtualKeyToButtonCode[VK_F9] =KEY_F9;
|
|
s_pVirtualKeyToButtonCode[VK_F10] =KEY_F10;
|
|
s_pVirtualKeyToButtonCode[VK_F11] =KEY_F11;
|
|
s_pVirtualKeyToButtonCode[VK_F12] =KEY_F12;
|
|
#endif
|
|
|
|
// init the xkey translation table
|
|
#if !defined( POSIX )
|
|
s_pXKeyTrans[XK_NULL] = KEY_NONE;
|
|
s_pXKeyTrans[XK_BUTTON_UP] = KEY_XBUTTON_UP;
|
|
s_pXKeyTrans[XK_BUTTON_DOWN] = KEY_XBUTTON_DOWN;
|
|
s_pXKeyTrans[XK_BUTTON_LEFT] = KEY_XBUTTON_LEFT;
|
|
s_pXKeyTrans[XK_BUTTON_RIGHT] = KEY_XBUTTON_RIGHT;
|
|
s_pXKeyTrans[XK_BUTTON_START] = KEY_XBUTTON_START;
|
|
s_pXKeyTrans[XK_BUTTON_BACK] = KEY_XBUTTON_BACK;
|
|
s_pXKeyTrans[XK_BUTTON_STICK1] = KEY_XBUTTON_STICK1;
|
|
s_pXKeyTrans[XK_BUTTON_STICK2] = KEY_XBUTTON_STICK2;
|
|
s_pXKeyTrans[XK_BUTTON_A] = KEY_XBUTTON_A;
|
|
s_pXKeyTrans[XK_BUTTON_B] = KEY_XBUTTON_B;
|
|
s_pXKeyTrans[XK_BUTTON_X] = KEY_XBUTTON_X;
|
|
s_pXKeyTrans[XK_BUTTON_Y] = KEY_XBUTTON_Y;
|
|
s_pXKeyTrans[XK_BUTTON_LEFT_SHOULDER] = KEY_XBUTTON_LEFT_SHOULDER;
|
|
s_pXKeyTrans[XK_BUTTON_RIGHT_SHOULDER] = KEY_XBUTTON_RIGHT_SHOULDER;
|
|
s_pXKeyTrans[XK_BUTTON_LTRIGGER] = KEY_XBUTTON_LTRIGGER;
|
|
s_pXKeyTrans[XK_BUTTON_RTRIGGER] = KEY_XBUTTON_RTRIGGER;
|
|
s_pXKeyTrans[XK_STICK1_UP] = KEY_XSTICK1_UP;
|
|
s_pXKeyTrans[XK_STICK1_DOWN] = KEY_XSTICK1_DOWN;
|
|
s_pXKeyTrans[XK_STICK1_LEFT] = KEY_XSTICK1_LEFT;
|
|
s_pXKeyTrans[XK_STICK1_RIGHT] = KEY_XSTICK1_RIGHT;
|
|
s_pXKeyTrans[XK_STICK2_UP] = KEY_XSTICK2_UP;
|
|
s_pXKeyTrans[XK_STICK2_DOWN] = KEY_XSTICK2_DOWN;
|
|
s_pXKeyTrans[XK_STICK2_LEFT] = KEY_XSTICK2_LEFT;
|
|
s_pXKeyTrans[XK_STICK2_RIGHT] = KEY_XSTICK2_RIGHT;
|
|
#endif // PLATFORM_POSIX
|
|
|
|
// create reverse table engine to virtual
|
|
for ( int i = 0; i < ARRAYSIZE( s_pVirtualKeyToButtonCode ); i++ )
|
|
{
|
|
s_pButtonCodeToVirtual[ s_pVirtualKeyToButtonCode[i] ] = i;
|
|
}
|
|
|
|
s_pButtonCodeToVirtual[0] = 0;
|
|
|
|
s_pSKeytoButtonCode[SK_NULL] = KEY_NONE;
|
|
s_pSKeytoButtonCode[SK_BUTTON_A] = STEAMCONTROLLER_A;
|
|
s_pSKeytoButtonCode[SK_BUTTON_B] = STEAMCONTROLLER_B;
|
|
s_pSKeytoButtonCode[SK_BUTTON_X] = STEAMCONTROLLER_X;
|
|
s_pSKeytoButtonCode[SK_BUTTON_Y] = STEAMCONTROLLER_Y;
|
|
s_pSKeytoButtonCode[SK_BUTTON_UP] = STEAMCONTROLLER_DPAD_UP;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RIGHT] = STEAMCONTROLLER_DPAD_RIGHT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_DOWN] = STEAMCONTROLLER_DPAD_DOWN;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LEFT] = STEAMCONTROLLER_DPAD_LEFT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LEFT_BUMPER] = STEAMCONTROLLER_LEFT_BUMPER;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RIGHT_BUMPER] = STEAMCONTROLLER_RIGHT_BUMPER;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LEFT_TRIGGER] = STEAMCONTROLLER_LEFT_TRIGGER;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RIGHT_TRIGGER] = STEAMCONTROLLER_RIGHT_TRIGGER;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LEFT_GRIP] = STEAMCONTROLLER_LEFT_GRIP;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RIGHT_GRIP] = STEAMCONTROLLER_RIGHT_GRIP;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LPAD_TOUCH] = STEAMCONTROLLER_LEFT_PAD_FINGERDOWN;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RPAD_TOUCH] = STEAMCONTROLLER_RIGHT_PAD_FINGERDOWN;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LPAD_CLICK] = STEAMCONTROLLER_LEFT_PAD_CLICK;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RPAD_CLICK] = STEAMCONTROLLER_RIGHT_PAD_CLICK;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LPAD_UP] = STEAMCONTROLLER_LEFT_PAD_UP;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LPAD_RIGHT] = STEAMCONTROLLER_LEFT_PAD_RIGHT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LPAD_DOWN] = STEAMCONTROLLER_LEFT_PAD_DOWN;
|
|
s_pSKeytoButtonCode[SK_BUTTON_LPAD_LEFT] = STEAMCONTROLLER_LEFT_PAD_LEFT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RPAD_UP] = STEAMCONTROLLER_RIGHT_PAD_UP;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RPAD_RIGHT] = STEAMCONTROLLER_RIGHT_PAD_RIGHT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RPAD_DOWN] = STEAMCONTROLLER_RIGHT_PAD_DOWN;
|
|
s_pSKeytoButtonCode[SK_BUTTON_RPAD_LEFT] = STEAMCONTROLLER_RIGHT_PAD_LEFT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_SELECT] = STEAMCONTROLLER_SELECT;
|
|
s_pSKeytoButtonCode[SK_BUTTON_START] = STEAMCONTROLLER_START;
|
|
s_pSKeytoButtonCode[SK_BUTTON_STEAM] = STEAMCONTROLLER_STEAM;
|
|
s_pSKeytoButtonCode[SK_BUTTON_INACTIVE_START] = STEAMCONTROLLER_INACTIVE_START;
|
|
|
|
// These are fake ("virtual") steam controller buttons that don't physically exist, but we can manufacture to make internal routing
|
|
// to old school UI (which is expecting button code rather than actions) without clashing with other butt
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F1] = STEAMCONTROLLER_F1;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F2] = STEAMCONTROLLER_F2;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F3] = STEAMCONTROLLER_F3;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F4] = STEAMCONTROLLER_F4;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F5] = STEAMCONTROLLER_F5;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F6] = STEAMCONTROLLER_F6;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F7] = STEAMCONTROLLER_F7;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F8] = STEAMCONTROLLER_F8;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F9] = STEAMCONTROLLER_F9;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F10] = STEAMCONTROLLER_F10;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F11] = STEAMCONTROLLER_F11;
|
|
s_pSKeytoButtonCode[SK_VBUTTON_F12] = STEAMCONTROLLER_F12;
|
|
}
|
|
|
|
ButtonCode_t ButtonCode_VirtualKeyToButtonCode( int keyCode )
|
|
{
|
|
if ( keyCode < 0 || keyCode >= sizeof( s_pVirtualKeyToButtonCode ) / sizeof( s_pVirtualKeyToButtonCode[0] ) )
|
|
{
|
|
Assert( false );
|
|
return KEY_NONE;
|
|
}
|
|
return s_pVirtualKeyToButtonCode[keyCode];
|
|
}
|
|
|
|
int ButtonCode_ButtonCodeToVirtualKey( ButtonCode_t code )
|
|
{
|
|
return s_pButtonCodeToVirtual[code];
|
|
}
|
|
|
|
ButtonCode_t ButtonCode_XKeyToButtonCode( int nPort, int keyCode )
|
|
{
|
|
#if !defined( POSIX )
|
|
if ( keyCode < 0 || keyCode >= sizeof( s_pXKeyTrans ) / sizeof( s_pXKeyTrans[0] ) )
|
|
{
|
|
Assert( false );
|
|
return KEY_NONE;
|
|
}
|
|
|
|
ButtonCode_t code = s_pXKeyTrans[keyCode];
|
|
if ( IsJoystickButtonCode( code ) )
|
|
{
|
|
int nOffset = code - JOYSTICK_FIRST_BUTTON;
|
|
return JOYSTICK_BUTTON( nPort, nOffset );
|
|
}
|
|
|
|
if ( IsJoystickPOVCode( code ) )
|
|
{
|
|
int nOffset = code - JOYSTICK_FIRST_POV_BUTTON;
|
|
return JOYSTICK_POV_BUTTON( nPort, nOffset );
|
|
}
|
|
|
|
if ( IsJoystickAxisCode( code ) )
|
|
{
|
|
int nOffset = code - JOYSTICK_FIRST_AXIS_BUTTON;
|
|
return JOYSTICK_AXIS_BUTTON( nPort, nOffset );
|
|
}
|
|
|
|
return code;
|
|
#else // POSIX
|
|
return KEY_NONE;
|
|
#endif // POSIX
|
|
}
|
|
|
|
// Convert back + forth between ButtonCode/AnalogCode + strings
|
|
const char *ButtonCode_ButtonCodeToString( ButtonCode_t code, bool bXController )
|
|
{
|
|
#if !defined ( _X360 )
|
|
if ( bXController && code >= JOYSTICK_FIRST_BUTTON && code <= JOYSTICK_LAST_AXIS_BUTTON )
|
|
return s_pXControllerButtonCodeNames[ code - JOYSTICK_FIRST_BUTTON ];
|
|
#endif
|
|
|
|
return s_pButtonCodeName[ code ];
|
|
}
|
|
|
|
const char *AnalogCode_AnalogCodeToString( AnalogCode_t code )
|
|
{
|
|
return s_pAnalogCodeName[ code ];
|
|
}
|
|
|
|
ButtonCode_t ButtonCode_StringToButtonCode( const char *pString, bool bXController )
|
|
{
|
|
if ( !pString || !pString[0] )
|
|
return BUTTON_CODE_INVALID;
|
|
|
|
// Backward compat for screwed up previous joystick button names
|
|
if ( !Q_strnicmp( pString, "aux", 3 ) )
|
|
{
|
|
int nIndex = atoi( &pString[3] );
|
|
if ( nIndex < 29 )
|
|
return JOYSTICK_BUTTON( 0, nIndex );
|
|
if ( ( nIndex >= 29 ) && ( nIndex <= 32 ) )
|
|
return JOYSTICK_POV_BUTTON( 0, nIndex - 29 );
|
|
return BUTTON_CODE_INVALID;
|
|
}
|
|
|
|
for ( int i = 0; i < BUTTON_CODE_LAST; ++i )
|
|
{
|
|
if ( !Q_stricmp( s_pButtonCodeName[i], pString ) )
|
|
return (ButtonCode_t)i;
|
|
}
|
|
|
|
#if !defined ( _X360 )
|
|
if ( bXController )
|
|
{
|
|
for ( int i = 0; i < ARRAYSIZE(s_pXControllerButtonCodeNames); ++i )
|
|
{
|
|
if ( !Q_stricmp( s_pXControllerButtonCodeNames[i], pString ) )
|
|
return (ButtonCode_t)(JOYSTICK_FIRST_BUTTON + i);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return BUTTON_CODE_INVALID;
|
|
}
|
|
|
|
ButtonCode_t ButtonCode_SKeyToButtonCode( int nPort, int keyCode )
|
|
{
|
|
#if !defined( _GAMECONSOLE )
|
|
if ( keyCode < 0 || keyCode >= sizeof( s_pSKeytoButtonCode ) / sizeof( s_pSKeytoButtonCode[0] ) )
|
|
{
|
|
Assert( false );
|
|
return KEY_NONE;
|
|
}
|
|
|
|
ButtonCode_t code = s_pSKeytoButtonCode[keyCode];
|
|
// if ( IsSteamControllerCode( code ) )
|
|
// {
|
|
// // Need Per Controller Offset here.
|
|
// return code;
|
|
// }
|
|
|
|
if ( IsSteamControllerButtonCode( code ) )
|
|
{
|
|
int nOffset = code - STEAMCONTROLLER_FIRST_BUTTON;
|
|
return STEAMCONTROLLER_BUTTON( nPort, nOffset );
|
|
}
|
|
|
|
if ( IsSteamControllerAxisCode( code ) )
|
|
{
|
|
int nOffset = code - STEAMCONTROLLER_FIRST_AXIS_BUTTON;
|
|
return STEAMCONTROLLER_AXIS_BUTTON( nPort, nOffset );
|
|
}
|
|
|
|
return code;
|
|
#else // _GAMECONSOLE
|
|
return KEY_NONE;
|
|
#endif // _GAMECONSOLE
|
|
}
|
|
|
|
AnalogCode_t AnalogCode_StringToAnalogCode( const char *pString )
|
|
{
|
|
if ( !pString || !pString[0] )
|
|
return ANALOG_CODE_INVALID;
|
|
|
|
for ( int i = 0; i < ANALOG_CODE_LAST; ++i )
|
|
{
|
|
if ( !Q_stricmp( s_pAnalogCodeName[i], pString ) )
|
|
return (AnalogCode_t)i;
|
|
}
|
|
|
|
return ANALOG_CODE_INVALID;
|
|
}
|
|
|
|
ButtonCode_t ButtonCode_ScanCodeToButtonCode( int lParam )
|
|
{
|
|
int nScanCode = ( lParam >> 16 ) & 0xFF;
|
|
if ( nScanCode > 127 )
|
|
return KEY_NONE;
|
|
|
|
ButtonCode_t result = s_pScanToButtonCode[nScanCode];
|
|
|
|
bool bIsExtended = ( lParam & ( 1 << 24 ) ) != 0;
|
|
if ( !bIsExtended )
|
|
{
|
|
switch ( result )
|
|
{
|
|
case KEY_HOME:
|
|
return KEY_PAD_7;
|
|
case KEY_UP:
|
|
return KEY_PAD_8;
|
|
case KEY_PAGEUP:
|
|
return KEY_PAD_9;
|
|
case KEY_LEFT:
|
|
return KEY_PAD_4;
|
|
case KEY_RIGHT:
|
|
return KEY_PAD_6;
|
|
case KEY_END:
|
|
return KEY_PAD_1;
|
|
case KEY_DOWN:
|
|
return KEY_PAD_2;
|
|
case KEY_PAGEDOWN:
|
|
return KEY_PAD_3;
|
|
case KEY_INSERT:
|
|
return KEY_PAD_0;
|
|
case KEY_DELETE:
|
|
return KEY_PAD_DECIMAL;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( result )
|
|
{
|
|
case KEY_ENTER:
|
|
return KEY_PAD_ENTER;
|
|
case KEY_LALT:
|
|
return KEY_RALT;
|
|
case KEY_LCONTROL:
|
|
return KEY_RCONTROL;
|
|
case KEY_SLASH:
|
|
return KEY_PAD_DIVIDE;
|
|
case KEY_CAPSLOCK:
|
|
return KEY_PAD_PLUS;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Update scan codes for foreign keyboards
|
|
//-----------------------------------------------------------------------------
|
|
void ButtonCode_UpdateScanCodeLayout( )
|
|
{
|
|
// reset the keyboard
|
|
memcpy( s_pScanToButtonCode, s_pScanToButtonCode_QWERTY, sizeof(s_pScanToButtonCode) );
|
|
|
|
#if !defined( _X360 ) && !defined( POSIX )
|
|
// fix up keyboard layout for other languages
|
|
HKL currentKb = ::GetKeyboardLayout( 0 );
|
|
HKL englishKb = ::LoadKeyboardLayout("00000409", 0);
|
|
|
|
if (englishKb && englishKb != currentKb)
|
|
{
|
|
for ( int i = 0; i < ARRAYSIZE(s_pScanToButtonCode); i++ )
|
|
{
|
|
// take the english/QWERTY
|
|
ButtonCode_t code = s_pScanToButtonCode_QWERTY[ i ];
|
|
|
|
// only remap printable keys
|
|
if ( code != KEY_NONE && code != KEY_BACKQUOTE && ( IsAlphaNumeric( code ) || IsPunctuation( code ) ) )
|
|
{
|
|
// get it's virtual key based on the old layout
|
|
int vk = ::MapVirtualKeyEx( i, 1, englishKb );
|
|
|
|
// turn in into a scancode on the new layout
|
|
int newScanCode = ::MapVirtualKeyEx( vk, 0, currentKb );
|
|
|
|
// strip off any high bits
|
|
newScanCode &= 0x0000007F;
|
|
|
|
// set in the new layout
|
|
s_pScanToButtonCode[newScanCode] = code;
|
|
}
|
|
}
|
|
}
|
|
|
|
s_pScanToButtonCode[0] = KEY_NONE;
|
|
#endif
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Updates the current keyboard layout
|
|
//-----------------------------------------------------------------------------
|
|
CON_COMMAND( key_updatelayout, "Updates game keyboard layout to current windows keyboard setting." )
|
|
{
|
|
ButtonCode_UpdateScanCodeLayout();
|
|
}
|