From d7c78727be1765ff293cfddb889b540cd62abbfd Mon Sep 17 00:00:00 2001 From: myT <> Date: Thu, 31 Oct 2024 02:10:33 +0100 Subject: [PATCH] added the in_qwerty CVar --- changelog.txt | 8 +- code/win32/win_wndproc.cpp | 301 ++++++++++++++++++++++++++++++++++++- 2 files changed, 302 insertions(+), 7 deletions(-) diff --git a/changelog.txt b/changelog.txt index 665f1ee..40c7204 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,10 @@ See the end of this file for known issues. DD Mmm YY - 1.54 +add: in_qwerty <0|1> (default: 1) forces the QWERTY layout for key bindings + 0 - uses your active regional layout (such as AZERTY, QWERTZ, etc.) + 1 - uses the QWERTY layout + add: FFmpeg piping support for compression of audio/video captures cl_ffmpeg <0|1> (default: 0) uses FFmpeg instead of writing raw .avi files cl_ffmpegCommand are the FFmpeg command-line options for the output file @@ -22,7 +26,7 @@ add: key binds starting with "keycatchgui" always take precedence over everythin bind F1 "keycatchgui;togglegui" bind F2 "keycatchgui;toggleguiinput" -add: r_guiFont <0 to 2> (default: 0) sets the GUI's font +add: r_guiFont <0|1|2> (default: 0) sets the GUI's font 0 - Proggy Clean (13px) 1 - Sweet16 Mono (16px) 2 - custom font file (see r_guiFontFile and r_guiFontHeight) @@ -32,7 +36,7 @@ add: r_guiFontFile (default: "") is the file path to the custom .ttf fo add: r_guiFontHeight <7 to 48> (default: 24) is the custom font's height -add: r_gpuPreference <0 to 2> (default: 0) sets the GPU selection preference +add: r_gpuPreference <0|1|2> (default: 0) sets the GPU selection preference 0 - high performance (discrete graphics) 1 - low power (integrated graphics) 2 - none diff --git a/code/win32/win_wndproc.cpp b/code/win32/win_wndproc.cpp index 531d619..84c3bdb 100644 --- a/code/win32/win_wndproc.cpp +++ b/code/win32/win_wndproc.cpp @@ -24,10 +24,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "win_local.h" -// Console variables that we need to access from this module -cvar_t *vid_xpos; // X coordinate of window position -cvar_t *vid_ypos; // Y coordinate of window position -cvar_t *r_fullscreen; +#define DEBUG_KEYPRESS 0 + + +static cvar_t* vid_xpos; // X coordinate of window position +static cvar_t* vid_ypos; // Y coordinate of window position +static cvar_t* in_qwerty; // forces the QWERTY layout for key bindings +cvar_t* r_fullscreen; static void WIN_AppActivate( BOOL fActive, BOOL fMinimized ) @@ -44,10 +47,147 @@ static void WIN_AppActivate( BOOL fActive, BOOL fMinimized ) } +#if DEBUG_KEYPRESS +static const char* GetKeyName( int q3key ) +{ + switch ( q3key ) + { + case K_TAB: return "TAB"; + case K_ENTER: return "ENTER"; + case K_ESCAPE: return "ESCAPE"; + case K_SPACE: return "SPACE"; + case K_BACKSPACE: return "BACKSPACE"; + case K_COMMAND: return "COMMAND"; + case K_CAPSLOCK: return "CAPSLOCK"; + case K_POWER: return "POWER"; + case K_PAUSE: return "PAUSE"; + case K_UPARROW: return "UPARROW"; + case K_DOWNARROW: return "DOWNARROW"; + case K_LEFTARROW: return "LEFTARROW"; + case K_RIGHTARROW: return "RIGHTARROW"; + case K_ALT: return "ALT"; + case K_CTRL: return "CTRL"; + case K_SHIFT: return "SHIFT"; + case K_INS: return "INS"; + case K_DEL: return "DEL"; + case K_PGDN: return "PGDN"; + case K_PGUP: return "PGUP"; + case K_HOME: return "HOME"; + case K_END: return "END"; + case K_F1: return "F1"; + case K_F2: return "F2"; + case K_F3: return "F3"; + case K_F4: return "F4"; + case K_F5: return "F5"; + case K_F6: return "F6"; + case K_F7: return "F7"; + case K_F8: return "F8"; + case K_F9: return "F9"; + case K_F10: return "F10"; + case K_F11: return "F11"; + case K_F12: return "F12"; + case K_F13: return "F13"; + case K_F14: return "F14"; + case K_F15: return "F15"; + case K_KP_HOME: return "KP_HOME"; + case K_KP_UPARROW: return "KP_UPARROW"; + case K_KP_PGUP: return "KP_PGUP"; + case K_KP_LEFTARROW: return "KP_LEFTARROW"; + case K_KP_5: return "KP_5"; + case K_KP_RIGHTARROW: return "KP_RIGHTARROW"; + case K_KP_END: return "KP_END"; + case K_KP_DOWNARROW: return "KP_DOWNARROW"; + case K_KP_PGDN: return "KP_PGDN"; + case K_KP_ENTER: return "KP_ENTER"; + case K_KP_INS: return "KP_INS"; + case K_KP_DEL: return "KP_DEL"; + case K_KP_SLASH: return "KP_SLASH"; + case K_KP_MINUS: return "KP_MINUS"; + case K_KP_PLUS: return "KP_PLUS"; + case K_KP_NUMLOCK: return "KP_NUMLOCK"; + case K_KP_STAR: return "KP_STAR"; + case K_KP_EQUALS: return "KP_EQUALS"; + case K_MOUSE1: return "MOUSE1"; + case K_MOUSE2: return "MOUSE2"; + case K_MOUSE3: return "MOUSE3"; + case K_MOUSE4: return "MOUSE4"; + case K_MOUSE5: return "MOUSE5"; + case K_MWHEELDOWN: return "MWHEELDOWN"; + case K_MWHEELUP: return "MWHEELUP"; + case K_JOY1: return "JOY1"; + case K_JOY2: return "JOY2"; + case K_JOY3: return "JOY3"; + case K_JOY4: return "JOY4"; + case K_JOY5: return "JOY5"; + case K_JOY6: return "JOY6"; + case K_JOY7: return "JOY7"; + case K_JOY8: return "JOY8"; + case K_JOY9: return "JOY9"; + case K_JOY10: return "JOY10"; + case K_JOY11: return "JOY11"; + case K_JOY12: return "JOY12"; + case K_JOY13: return "JOY13"; + case K_JOY14: return "JOY14"; + case K_JOY15: return "JOY15"; + case K_JOY16: return "JOY16"; + case K_JOY17: return "JOY17"; + case K_JOY18: return "JOY18"; + case K_JOY19: return "JOY19"; + case K_JOY20: return "JOY20"; + case K_JOY21: return "JOY21"; + case K_JOY22: return "JOY22"; + case K_JOY23: return "JOY23"; + case K_JOY24: return "JOY24"; + case K_JOY25: return "JOY25"; + case K_JOY26: return "JOY26"; + case K_JOY27: return "JOY27"; + case K_JOY28: return "JOY28"; + case K_JOY29: return "JOY29"; + case K_JOY30: return "JOY30"; + case K_JOY31: return "JOY31"; + case K_JOY32: return "JOY32"; + case K_AUX1: return "AUX1"; + case K_AUX2: return "AUX2"; + case K_AUX3: return "AUX3"; + case K_AUX4: return "AUX4"; + case K_AUX5: return "AUX5"; + case K_AUX6: return "AUX6"; + case K_AUX7: return "AUX7"; + case K_AUX8: return "AUX8"; + case K_AUX9: return "AUX9"; + case K_AUX10: return "AUX10"; + case K_AUX11: return "AUX11"; + case K_AUX12: return "AUX12"; + case K_AUX13: return "AUX13"; + case K_AUX14: return "AUX14"; + case K_AUX15: return "AUX15"; + case K_AUX16: return "AUX16"; + case K_MOUSE6: return "MOUSE6"; + case K_MOUSE7: return "MOUSE7"; + case K_MOUSE8: return "MOUSE8"; + case K_MOUSE9: return "MOUSE9"; + case K_WIN: return "WIN"; + case K_MENU: return "MENU"; + case K_BACKSLASH: return "BACKSLASH"; + case K_F16: return "F16"; + case K_F17: return "F17"; + case K_F18: return "F18"; + case K_F19: return "F19"; + case K_F20: return "F20"; + case K_F21: return "F21"; + case K_F22: return "F22"; + case K_F23: return "F23"; + case K_F24: return "F24"; + default: return "???"; + } +} +#endif + + /////////////////////////////////////////////////////////////// -static byte s_scantokey[128] = +static const byte s_scantokey[128] = { // 0 1 2 3 4 5 6 7 // 8 9 A B C D E F @@ -69,6 +209,128 @@ static byte s_scantokey[128] = 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7 }; + +static byte s_winVKeyToQ3Key[256]; +static qbool s_keyTableValid = qfalse; + +static void InitKeyMap() +{ + if ( s_keyTableValid ) + { + return; + } + + for ( int c = '0'; c <= '9'; c++ ) + { + s_winVKeyToQ3Key[c] = c; + } + + for ( int c = 'A'; c <= 'Z'; c++ ) + { + s_winVKeyToQ3Key[c] = c + 32; + } + + struct keyMap_t + { + byte winKey; + byte quakeKey; + }; + +#define KEY(WinKey, QuakeKey) { WinKey, QuakeKey } + static const keyMap_t keys[] = + { + KEY(VK_TAB, K_TAB), + KEY(VK_RETURN, K_ENTER), + KEY(VK_ESCAPE, K_ESCAPE), + KEY(VK_SPACE, K_SPACE), + KEY(VK_BACK, K_BACKSPACE), + KEY(VK_CAPITAL, K_CAPSLOCK), + KEY(VK_PAUSE, K_PAUSE), + KEY(VK_UP, K_UPARROW), + KEY(VK_DOWN, K_DOWNARROW), + KEY(VK_LEFT, K_LEFTARROW), + KEY(VK_RIGHT, K_RIGHTARROW), + KEY(VK_MENU, K_ALT), + KEY(VK_CONTROL, K_CTRL), + KEY(VK_SHIFT, K_SHIFT), + KEY(VK_INSERT, K_INS), + KEY(VK_DELETE, K_DEL), + KEY(VK_NEXT, K_PGDN), + KEY(VK_PRIOR, K_PGUP), + KEY(VK_HOME, K_HOME), + KEY(VK_END, K_END), + KEY(VK_F1, K_F1), + KEY(VK_F2, K_F2), + KEY(VK_F3, K_F3), + KEY(VK_F4, K_F4), + KEY(VK_F5, K_F5), + KEY(VK_F6, K_F6), + KEY(VK_F7, K_F7), + KEY(VK_F8, K_F8), + KEY(VK_F9, K_F9), + KEY(VK_F10, K_F10), + KEY(VK_F11, K_F11), + KEY(VK_F12, K_F12), + KEY(VK_F13, K_F13), + KEY(VK_F14, K_F14), + KEY(VK_F15, K_F15), + KEY(VK_NUMPAD7, K_KP_HOME), + KEY(VK_NUMPAD8, K_KP_UPARROW), + KEY(VK_NUMPAD9, K_KP_PGUP), + KEY(VK_NUMPAD4, K_KP_LEFTARROW), + KEY(VK_NUMPAD5, K_KP_5), + KEY(VK_NUMPAD6, K_KP_RIGHTARROW), + KEY(VK_NUMPAD1, K_KP_END), + KEY(VK_NUMPAD2, K_KP_DOWNARROW), + KEY(VK_NUMPAD3, K_KP_PGDN), + KEY(VK_NUMPAD0, K_KP_INS), + KEY(VK_NUMLOCK, K_KP_DEL), + KEY(VK_DIVIDE, K_KP_SLASH), + KEY(VK_SUBTRACT, K_KP_MINUS), + KEY(VK_ADD, K_KP_PLUS), + KEY(VK_DECIMAL, K_KP_NUMLOCK), + KEY(VK_MULTIPLY, K_KP_STAR), + KEY(VK_LBUTTON, K_MOUSE1), + KEY(VK_RBUTTON, K_MOUSE2), + KEY(VK_MBUTTON, K_MOUSE3), + KEY(VK_XBUTTON1, K_MOUSE4), + KEY(VK_XBUTTON2, K_MOUSE5), + KEY(VK_F16, K_F16), + KEY(VK_F17, K_F17), + KEY(VK_F18, K_F18), + KEY(VK_F19, K_F19), + KEY(VK_F20, K_F20), + KEY(VK_F21, K_F21), + KEY(VK_F22, K_F22), + KEY(VK_F23, K_F23), + KEY(VK_F24, K_F24) +#if 0 // not handled + K_COMMAND + K_POWER + K_BACKSLASH + K_MOUSE6 + K_MOUSE7 + K_MOUSE8 + K_MOUSE9 + K_KP_ENTER + K_KP_EQUALS + K_WIN + K_MENU +#endif + }; +#undef KEY + + for ( int i = 0; i < ARRAY_LEN(keys); i++ ) + { + const byte winKey = keys[i].winKey; + const byte quakeKey = keys[i].quakeKey; + s_winVKeyToQ3Key[winKey] = quakeKey; + } + + s_keyTableValid = qtrue; +} + + /* ======= MapKey @@ -78,6 +340,7 @@ Map from windows to quake keynums */ static int MapKey( int wParam, int lParam ) { + // this is needed for the in_qwerty 1 case // the K_F13 to K_F24 values are *not* contiguous for mod compatibility reasons switch ( wParam ) { @@ -96,6 +359,29 @@ static int MapKey( int wParam, int lParam ) default: break; } +#if DEBUG_KEYPRESS + char keyName[64]; + if ( GetKeyNameTextA((LONG)lParam, keyName, (int)sizeof(keyName)) > 0 ) + { + Sys_DebugPrintf( "Key: Win32 %d %s\n", wParam, keyName ); + } +#endif + + Q_assert( in_qwerty != NULL ); + const qbool qwerty = in_qwerty != NULL && in_qwerty->integer != 0; + if ( !qwerty && wParam < ARRAY_LEN(s_winVKeyToQ3Key) ) + { + const int q3key = s_winVKeyToQ3Key[wParam]; + if ( q3key > 0 ) + { +#if DEBUG_KEYPRESS + Sys_DebugPrintf( "Mapped key: Win32 %d -> Q3 %d (%c, %s)\n", + wParam, q3key, (char)q3key, GetKeyName(q3key) ); +#endif + return q3key; + } + } + const int scanCode = ( lParam >> 16 ) & 255; if ( scanCode > 127 ) return 0; // why? @@ -179,9 +465,14 @@ LRESULT CALLBACK MainWndProc ( vid_ypos = Cvar_Get( "vid_ypos", "22", CVAR_ARCHIVE ); r_fullscreen = Cvar_Get( "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH ); Cvar_Get( "r_monitor", "0", CVAR_ARCHIVE | CVAR_LATCH ); // 1-based monitor index, 0 means primary + in_qwerty = Cvar_Get( "in_qwerty", "1", CVAR_ARCHIVE ); + Cvar_SetRange( "in_qwerty", CVART_BOOL, NULL, NULL ); + Cvar_SetHelp( "in_qwerty", "forces the QWERTY layout for key bindings" ); WIN_RegisterLastValidHotKey(); + InitKeyMap(); + break; case WM_DESTROY: