mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2024-12-22 08:20:02 +00:00
Get keyboard input from X11 on Linux
This commit is contained in:
parent
48cec4a786
commit
bf7280b55b
|
@ -342,10 +342,10 @@ project "re3"
|
|||
libdirs { "vendor/openal-soft/libs/Win64" }
|
||||
|
||||
filter "platforms:linux*oal"
|
||||
links { "openal", "mpg123", "sndfile", "pthread" }
|
||||
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
|
||||
|
||||
filter "platforms:bsd*oal"
|
||||
links { "openal", "mpg123", "sndfile", "pthread" }
|
||||
links { "openal", "mpg123", "sndfile", "pthread", "X11" }
|
||||
|
||||
filter "platforms:macosx*oal"
|
||||
links { "openal", "mpg123", "sndfile", "pthread" }
|
||||
|
|
|
@ -50,17 +50,30 @@ long _dwOperatingSystemVersion;
|
|||
#include "Font.h"
|
||||
#include "MemoryMgr.h"
|
||||
|
||||
#define MAX_SUBSYSTEMS (16)
|
||||
// We found out that GLFW's keyboard input handling is still pretty delayed/not stable, so now we fetch input from X11 directly on Linux.
|
||||
#if !defined _WIN32 && !defined __APPLE__ && !defined __SWITCH__ // && !defined WAYLAND
|
||||
#define GET_KEYBOARD_INPUT_FROM_X11
|
||||
#endif
|
||||
|
||||
#ifdef GET_KEYBOARD_INPUT_FROM_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3native.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#include <GLFW/glfw3native.h>
|
||||
#endif
|
||||
|
||||
#define MAX_SUBSYSTEMS (16)
|
||||
|
||||
rw::EngineOpenParams openParams;
|
||||
|
||||
static RwBool ForegroundApp = TRUE;
|
||||
static RwBool WindowIconified = FALSE;
|
||||
static RwBool WindowFocused = TRUE;
|
||||
|
||||
static RwBool RwInitialised = FALSE;
|
||||
|
||||
|
@ -322,7 +335,9 @@ psInitialize(void)
|
|||
RsGlobal.ps = &PsGlobal;
|
||||
|
||||
PsGlobal.fullScreen = FALSE;
|
||||
PsGlobal.cursorIsInWindow = TRUE;
|
||||
PsGlobal.cursorIsInWindow = FALSE;
|
||||
WindowFocused = TRUE;
|
||||
WindowIconified = FALSE;
|
||||
|
||||
PsGlobal.joy1id = -1;
|
||||
PsGlobal.joy2id = -1;
|
||||
|
@ -838,11 +853,15 @@ psSelectDevice()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef GET_KEYBOARD_INPUT_FROM_X11
|
||||
void keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
#endif
|
||||
void resizeCB(GLFWwindow* window, int width, int height);
|
||||
void scrollCB(GLFWwindow* window, double xoffset, double yoffset);
|
||||
void cursorCB(GLFWwindow* window, double xpos, double ypos);
|
||||
void cursorEnterCB(GLFWwindow* window, int entered);
|
||||
void windowFocusCB(GLFWwindow* window, int focused);
|
||||
void windowIconifyCB(GLFWwindow* window, int iconified);
|
||||
void joysChangeCB(int jid, int event);
|
||||
|
||||
bool IsThisJoystickBlacklisted(int i)
|
||||
|
@ -930,11 +949,15 @@ void psPostRWinit(void)
|
|||
RwVideoMode vm;
|
||||
RwEngineGetVideoModeInfo(&vm, GcurSelVM);
|
||||
|
||||
#ifndef GET_KEYBOARD_INPUT_FROM_X11
|
||||
glfwSetKeyCallback(PSGLOBAL(window), keypressCB);
|
||||
#endif
|
||||
glfwSetFramebufferSizeCallback(PSGLOBAL(window), resizeCB);
|
||||
glfwSetScrollCallback(PSGLOBAL(window), scrollCB);
|
||||
glfwSetCursorPosCallback(PSGLOBAL(window), cursorCB);
|
||||
glfwSetCursorEnterCallback(PSGLOBAL(window), cursorEnterCB);
|
||||
glfwSetWindowIconifyCallback(PSGLOBAL(window), windowIconifyCB);
|
||||
glfwSetWindowFocusCallback(PSGLOBAL(window), windowFocusCB);
|
||||
glfwSetJoystickCallback(joysChangeCB);
|
||||
|
||||
_InputInitialiseJoys();
|
||||
|
@ -1286,6 +1309,10 @@ void scrollCB(GLFWwindow* window, double xoffset, double yoffset) {
|
|||
PSGLOBAL(mouseWheel) = yoffset;
|
||||
}
|
||||
|
||||
bool lshiftStatus = false;
|
||||
bool rshiftStatus = false;
|
||||
|
||||
#ifndef GET_KEYBOARD_INPUT_FROM_X11
|
||||
int keymap[GLFW_KEY_LAST + 1];
|
||||
|
||||
static void
|
||||
|
@ -1416,9 +1443,6 @@ initkeymap(void)
|
|||
keymap[GLFW_KEY_MENU] = rsNULL;
|
||||
}
|
||||
|
||||
bool lshiftStatus = false;
|
||||
bool rshiftStatus = false;
|
||||
|
||||
void
|
||||
keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
|
@ -1436,6 +1460,266 @@ keypressCB(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
uint32 keymap[512]; // 256 ascii + 256 KeySyms between 0xff00 - 0xffff
|
||||
bool keyStates[512];
|
||||
uint32 keyCodeToKeymapIndex[256]; // cache for physical keys
|
||||
|
||||
#define KEY_MAP_OFFSET (0xff00 - 256)
|
||||
static void
|
||||
initkeymap(void)
|
||||
{
|
||||
Display *display = glfwGetX11Display();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(keymap); i++)
|
||||
keymap[i] = rsNULL;
|
||||
|
||||
// You can add new ASCII mappings to here freely (but beware that if right hand side of assignment isn't supported on CFont, it'll be blank/won't work on binding screen)
|
||||
// Right hand side of assigments should always be uppercase counterpart of character
|
||||
keymap[XK_space] = ' ';
|
||||
keymap[XK_apostrophe] = '\'';
|
||||
keymap[XK_ampersand] = '&';
|
||||
keymap[XK_percent] = '%';
|
||||
keymap[XK_dollar] = '$';
|
||||
keymap[XK_comma] = ',';
|
||||
keymap[XK_minus] = '-';
|
||||
keymap[XK_period] = '.';
|
||||
keymap[XK_slash] = '/';
|
||||
keymap[XK_question] = '?';
|
||||
keymap[XK_exclam] = '!';
|
||||
keymap[XK_quotedbl] = '"';
|
||||
keymap[XK_colon] = ':';
|
||||
keymap[XK_semicolon] = ';';
|
||||
keymap[XK_equal] = '=';
|
||||
keymap[XK_bracketleft] = '[';
|
||||
keymap[XK_backslash] = '\\';
|
||||
keymap[XK_bracketright] = ']';
|
||||
keymap[XK_grave] = '`';
|
||||
keymap[XK_0] = '0';
|
||||
keymap[XK_1] = '1';
|
||||
keymap[XK_2] = '2';
|
||||
keymap[XK_3] = '3';
|
||||
keymap[XK_4] = '4';
|
||||
keymap[XK_5] = '5';
|
||||
keymap[XK_6] = '6';
|
||||
keymap[XK_7] = '7';
|
||||
keymap[XK_8] = '8';
|
||||
keymap[XK_9] = '9';
|
||||
keymap[XK_a] = 'A';
|
||||
keymap[XK_b] = 'B';
|
||||
keymap[XK_c] = 'C';
|
||||
keymap[XK_d] = 'D';
|
||||
keymap[XK_e] = 'E';
|
||||
keymap[XK_f] = 'F';
|
||||
keymap[XK_g] = 'G';
|
||||
keymap[XK_h] = 'H';
|
||||
keymap[XK_i] = 'I';
|
||||
keymap[XK_I] = 'I'; // Turkish I problem
|
||||
keymap[XK_j] = 'J';
|
||||
keymap[XK_k] = 'K';
|
||||
keymap[XK_l] = 'L';
|
||||
keymap[XK_m] = 'M';
|
||||
keymap[XK_n] = 'N';
|
||||
keymap[XK_o] = 'O';
|
||||
keymap[XK_p] = 'P';
|
||||
keymap[XK_q] = 'Q';
|
||||
keymap[XK_r] = 'R';
|
||||
keymap[XK_s] = 'S';
|
||||
keymap[XK_t] = 'T';
|
||||
keymap[XK_u] = 'U';
|
||||
keymap[XK_v] = 'V';
|
||||
keymap[XK_w] = 'W';
|
||||
keymap[XK_x] = 'X';
|
||||
keymap[XK_y] = 'Y';
|
||||
keymap[XK_z] = 'Z';
|
||||
|
||||
// Some of regional but ASCII characters that GTA supports
|
||||
keymap[XK_agrave] = 0x00c0;
|
||||
keymap[XK_aacute] = 0x00c1;
|
||||
keymap[XK_acircumflex] = 0x00c2;
|
||||
keymap[XK_adiaeresis] = 0x00c4;
|
||||
|
||||
keymap[XK_ae] = 0x00c6;
|
||||
|
||||
keymap[XK_egrave] = 0x00c8;
|
||||
keymap[XK_eacute] = 0x00c9;
|
||||
keymap[XK_ecircumflex] = 0x00ca;
|
||||
keymap[XK_ediaeresis] = 0x00cb;
|
||||
|
||||
keymap[XK_igrave] = 0x00cc;
|
||||
keymap[XK_iacute] = 0x00cd;
|
||||
keymap[XK_icircumflex] = 0x00ce;
|
||||
keymap[XK_idiaeresis] = 0x00cf;
|
||||
|
||||
keymap[XK_ccedilla] = 0x00c7;
|
||||
keymap[XK_odiaeresis] = 0x00d6;
|
||||
keymap[XK_udiaeresis] = 0x00dc;
|
||||
|
||||
// These are 0xff00 - 0xffff range of KeySym's, and subtracting KEY_MAP_OFFSET is needed
|
||||
keymap[XK_Escape - KEY_MAP_OFFSET] = rsESC;
|
||||
keymap[XK_Return - KEY_MAP_OFFSET] = rsENTER;
|
||||
keymap[XK_Tab - KEY_MAP_OFFSET] = rsTAB;
|
||||
keymap[XK_BackSpace - KEY_MAP_OFFSET] = rsBACKSP;
|
||||
keymap[XK_Insert - KEY_MAP_OFFSET] = rsINS;
|
||||
keymap[XK_Delete - KEY_MAP_OFFSET] = rsDEL;
|
||||
keymap[XK_Right - KEY_MAP_OFFSET] = rsRIGHT;
|
||||
keymap[XK_Left - KEY_MAP_OFFSET] = rsLEFT;
|
||||
keymap[XK_Down - KEY_MAP_OFFSET] = rsDOWN;
|
||||
keymap[XK_Up - KEY_MAP_OFFSET] = rsUP;
|
||||
keymap[XK_Page_Up - KEY_MAP_OFFSET] = rsPGUP;
|
||||
keymap[XK_Page_Down - KEY_MAP_OFFSET] = rsPGDN;
|
||||
keymap[XK_Home - KEY_MAP_OFFSET] = rsHOME;
|
||||
keymap[XK_End - KEY_MAP_OFFSET] = rsEND;
|
||||
keymap[XK_Caps_Lock - KEY_MAP_OFFSET] = rsCAPSLK;
|
||||
keymap[XK_Scroll_Lock - KEY_MAP_OFFSET] = rsSCROLL;
|
||||
keymap[XK_Num_Lock - KEY_MAP_OFFSET] = rsNUMLOCK;
|
||||
keymap[XK_Pause - KEY_MAP_OFFSET] = rsPAUSE;
|
||||
|
||||
keymap[XK_F1 - KEY_MAP_OFFSET] = rsF1;
|
||||
keymap[XK_F2 - KEY_MAP_OFFSET] = rsF2;
|
||||
keymap[XK_F3 - KEY_MAP_OFFSET] = rsF3;
|
||||
keymap[XK_F4 - KEY_MAP_OFFSET] = rsF4;
|
||||
keymap[XK_F5 - KEY_MAP_OFFSET] = rsF5;
|
||||
keymap[XK_F6 - KEY_MAP_OFFSET] = rsF6;
|
||||
keymap[XK_F7 - KEY_MAP_OFFSET] = rsF7;
|
||||
keymap[XK_F8 - KEY_MAP_OFFSET] = rsF8;
|
||||
keymap[XK_F9 - KEY_MAP_OFFSET] = rsF9;
|
||||
keymap[XK_F10 - KEY_MAP_OFFSET] = rsF10;
|
||||
keymap[XK_F11 - KEY_MAP_OFFSET] = rsF11;
|
||||
keymap[XK_F12 - KEY_MAP_OFFSET] = rsF12;
|
||||
keymap[XK_F13 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F14 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F15 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F16 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F17 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F18 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F19 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F20 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F21 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F22 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F23 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F24 - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_F25 - KEY_MAP_OFFSET] = rsNULL;
|
||||
|
||||
keymap[XK_KP_0 - KEY_MAP_OFFSET] = rsPADINS;
|
||||
keymap[XK_KP_1 - KEY_MAP_OFFSET] = rsPADEND;
|
||||
keymap[XK_KP_2 - KEY_MAP_OFFSET] = rsPADDOWN;
|
||||
keymap[XK_KP_3 - KEY_MAP_OFFSET] = rsPADPGDN;
|
||||
keymap[XK_KP_4 - KEY_MAP_OFFSET] = rsPADLEFT;
|
||||
keymap[XK_KP_5 - KEY_MAP_OFFSET] = rsPAD5;
|
||||
keymap[XK_KP_6 - KEY_MAP_OFFSET] = rsPADRIGHT;
|
||||
keymap[XK_KP_7 - KEY_MAP_OFFSET] = rsPADHOME;
|
||||
keymap[XK_KP_8 - KEY_MAP_OFFSET] = rsPADUP;
|
||||
keymap[XK_KP_9 - KEY_MAP_OFFSET] = rsPADPGUP;
|
||||
keymap[XK_KP_Insert - KEY_MAP_OFFSET] = rsPADINS;
|
||||
keymap[XK_KP_End - KEY_MAP_OFFSET] = rsPADEND;
|
||||
keymap[XK_KP_Down - KEY_MAP_OFFSET] = rsPADDOWN;
|
||||
keymap[XK_KP_Page_Down - KEY_MAP_OFFSET] = rsPADPGDN;
|
||||
keymap[XK_KP_Left - KEY_MAP_OFFSET] = rsPADLEFT;
|
||||
keymap[XK_KP_Begin - KEY_MAP_OFFSET] = rsPAD5;
|
||||
keymap[XK_KP_Right - KEY_MAP_OFFSET] = rsPADRIGHT;
|
||||
keymap[XK_KP_Home - KEY_MAP_OFFSET] = rsPADHOME;
|
||||
keymap[XK_KP_Up - KEY_MAP_OFFSET] = rsPADUP;
|
||||
keymap[XK_KP_Page_Up - KEY_MAP_OFFSET] = rsPADPGUP;
|
||||
|
||||
keymap[XK_KP_Decimal - KEY_MAP_OFFSET] = rsPADDEL;
|
||||
keymap[XK_KP_Divide - KEY_MAP_OFFSET] = rsDIVIDE;
|
||||
keymap[XK_KP_Multiply - KEY_MAP_OFFSET] = rsTIMES;
|
||||
keymap[XK_KP_Subtract - KEY_MAP_OFFSET] = rsMINUS;
|
||||
keymap[XK_KP_Add - KEY_MAP_OFFSET] = rsPLUS;
|
||||
keymap[XK_KP_Enter - KEY_MAP_OFFSET] = rsPADENTER;
|
||||
keymap[XK_KP_Equal - KEY_MAP_OFFSET] = rsNULL;
|
||||
keymap[XK_Shift_L - KEY_MAP_OFFSET] = rsLSHIFT;
|
||||
keymap[XK_Control_L - KEY_MAP_OFFSET] = rsLCTRL;
|
||||
keymap[XK_Alt_L - KEY_MAP_OFFSET] = rsLALT;
|
||||
keymap[XK_Super_L - KEY_MAP_OFFSET] = rsLWIN;
|
||||
keymap[XK_Shift_R - KEY_MAP_OFFSET] = rsRSHIFT;
|
||||
keymap[XK_Control_R - KEY_MAP_OFFSET] = rsRCTRL;
|
||||
keymap[XK_Alt_R - KEY_MAP_OFFSET] = rsRALT;
|
||||
keymap[XK_Super_R - KEY_MAP_OFFSET] = rsRWIN;
|
||||
keymap[XK_Menu - KEY_MAP_OFFSET] = rsNULL;
|
||||
|
||||
// Cache the key codes' key symbol equivelants, otherwise we will have to do it on each frame
|
||||
// KeyCode is always in [0,255], and represents a physical key
|
||||
|
||||
int min_keycode, max_keycode, keysyms_per_keycode;
|
||||
KeySym *keymap, *origkeymap;
|
||||
|
||||
char *keyboardLang = setlocale (LC_CTYPE, NULL);
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
XDisplayKeycodes(display, &min_keycode, &max_keycode);
|
||||
origkeymap = XGetKeyboardMapping(display, min_keycode, (max_keycode - min_keycode + 1), &keysyms_per_keycode);
|
||||
keymap = origkeymap;
|
||||
for (int i = min_keycode; i <= max_keycode; i++) {
|
||||
int j, lastKeysym;
|
||||
|
||||
lastKeysym = keysyms_per_keycode - 1;
|
||||
while ((lastKeysym >= 0) && (keymap[lastKeysym] == NoSymbol))
|
||||
lastKeysym--;
|
||||
|
||||
for (j = 0; j <= lastKeysym; j++) {
|
||||
KeySym ks = keymap[j];
|
||||
|
||||
if (ks == NoSymbol)
|
||||
continue;
|
||||
|
||||
if (ks < 256) {
|
||||
keyCodeToKeymapIndex[i] = ks;
|
||||
break;
|
||||
} else if (ks >= 0xff00 && ks < 0xffff) {
|
||||
keyCodeToKeymapIndex[i] = ks - KEY_MAP_OFFSET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
keymap += keysyms_per_keycode;
|
||||
}
|
||||
XFree(origkeymap);
|
||||
|
||||
setlocale(LC_CTYPE, keyboardLang);
|
||||
}
|
||||
#undef KEY_MAP_OFFSET
|
||||
|
||||
void checkKeyPresses()
|
||||
{
|
||||
Display *display = glfwGetX11Display();
|
||||
char keys[32];
|
||||
XQueryKeymap(display, keys);
|
||||
for (int i = 0; i < sizeof(keys); i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
KeyCode keycode = 8 * i + j;
|
||||
uint32 keymapIndex = keyCodeToKeymapIndex[keycode];
|
||||
if (keymapIndex != 0) {
|
||||
int rsCode = keymap[keymapIndex];
|
||||
if (rsCode == rsNULL)
|
||||
continue;
|
||||
|
||||
bool pressed = WindowFocused && !!(keys[i] & (1 << j));
|
||||
|
||||
// idk why R* does that
|
||||
if (rsCode == rsLSHIFT)
|
||||
lshiftStatus = pressed;
|
||||
else if (rsCode == rsRSHIFT)
|
||||
rshiftStatus = pressed;
|
||||
|
||||
if (keyStates[keymapIndex] != pressed) {
|
||||
if (pressed) {
|
||||
RsKeyboardEventHandler(rsKEYDOWN, &rsCode);
|
||||
} else {
|
||||
RsKeyboardEventHandler(rsKEYUP, &rsCode);
|
||||
}
|
||||
}
|
||||
|
||||
keyStates[keymapIndex] = pressed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// R* calls that in ControllerConfig, idk why
|
||||
void
|
||||
_InputTranslateShiftKeyUpDown(RsKeyCodes *rs) {
|
||||
|
@ -1460,6 +1744,16 @@ cursorEnterCB(GLFWwindow* window, int entered) {
|
|||
PSGLOBAL(cursorIsInWindow) = !!entered;
|
||||
}
|
||||
|
||||
void
|
||||
windowFocusCB(GLFWwindow* window, int focused) {
|
||||
WindowFocused = !!focused;
|
||||
}
|
||||
|
||||
void
|
||||
windowIconifyCB(GLFWwindow* window, int iconified) {
|
||||
WindowIconified = !!iconified;
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
@ -1712,6 +2006,9 @@ main(int argc, char *argv[])
|
|||
#endif
|
||||
{
|
||||
glfwPollEvents();
|
||||
#ifdef GET_KEYBOARD_INPUT_FROM_X11
|
||||
checkKeyPresses();
|
||||
#endif
|
||||
#ifndef MASTER
|
||||
if (gbModelViewer) {
|
||||
// This is TheModelViewerCore in LCS, but TheModelViewer on other state-machine III-VCs.
|
||||
|
@ -1849,7 +2146,7 @@ main(int argc, char *argv[])
|
|||
|
||||
case GS_FRONTEND:
|
||||
{
|
||||
if(!glfwGetWindowAttrib(PSGLOBAL(window), GLFW_ICONIFIED))
|
||||
if(!WindowIconified)
|
||||
RsEventHandler(rsFRONTENDIDLE, nil);
|
||||
|
||||
#ifdef PS2_MENU
|
||||
|
|
Loading…
Reference in a new issue