From 8b0f96fdfebeb7b1e28dc543a5b916b4bbcbf9c4 Mon Sep 17 00:00:00 2001 From: Petr Bartos Date: Thu, 7 Apr 2022 18:08:45 +0200 Subject: [PATCH] Controller mapping refactoring --- android/app/src/main/assets/autoexec.cfg | 56 +- .../src/main/cpp/code/q3_ui/ui_controls3.c | 24 - android/app/src/main/cpp/code/ui/ui_main.c | 24 - android/app/src/main/cpp/code/vr/vr_base.c | 24 - android/app/src/main/cpp/code/vr/vr_input.c | 820 +++++++----------- 5 files changed, 338 insertions(+), 610 deletions(-) diff --git a/android/app/src/main/assets/autoexec.cfg b/android/app/src/main/assets/autoexec.cfg index 20852869..d20733e8 100644 --- a/android/app/src/main/assets/autoexec.cfg +++ b/android/app/src/main/assets/autoexec.cfg @@ -14,36 +14,52 @@ set cg_weaponbob 0 set sv_pure 0 set sv_master1 "13.36.227.32:27950" -// VR Button mappings - ONLY put overrides of defaults in here, such as alt key mappings -// set vr_button_map_A "" +////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// Custom Button mappings - ONLY put overrides of defaults in here, such as alt key mappings. // +// // +// Contained sample mapping corresponds to default control schema. Note that by mapping // +// thumbstick diagonals, thumbstick switches to 8-way mode requiring more precise input! // +// // +// To activate mapping, do not forget to remove "//" (marking commented out / inactive line). // +// Also note that custom mappings will be overridden by defaults until game restart in case // +// controls are changed from in-game menu. // +// // +////////////////////////////////////////////////////////////////////////////////////////////////// + +// set vr_button_map_A "+moveup" // set vr_button_map_A_ALT "" -// set vr_button_map_B "" +// set vr_button_map_B "+movedown" // set vr_button_map_B_ALT "" -// set vr_button_map_X "" +// set vr_button_map_X "+button2" // set vr_button_map_X_ALT "" -// set vr_button_map_Y "" +// set vr_button_map_Y "+button3" // set vr_button_map_Y_ALT "" -// set vr_button_map_SECONDARYTHUMBSTICK "" +// set vr_button_map_SECONDARYTHUMBSTICK "+scores" // set vr_button_map_SECONDARYTHUMBSTICK_ALT "" // set vr_button_map_PRIMARYTHUMBSTICK "" // set vr_button_map_PRIMARYTHUMBSTICK_ALT "" -// set vr_button_map_RTHUMBFORWARD "" +// set vr_button_map_SECONDARYTRIGGER "+moveup" +// set vr_button_map_SECONDARYTRIGGER_ALT "" +// set vr_button_map_PRIMARYTRIGGER "+attack" +// set vr_button_map_PRIMARYTRIGGER_ALT "" +// set vr_button_map_SECONDARYGRIP "+weapon_stabilise" +// set vr_button_map_SECONDARYGRIP_ALT "" +// set vr_button_map_PRIMARYGRIP "+weapon_select" +// set vr_button_map_PRIMARYGRIP_ALT "" +// set vr_button_map_RTHUMBFORWARD "weapnext" // set vr_button_map_RTHUMBFORWARD_ALT "" -// set vr_button_map_RTHUMBFORWARDLEFT "" -// set vr_button_map_RTHUMBFORWARDLEFT_ALT "" // set vr_button_map_RTHUMBFORWARDRIGHT "" // set vr_button_map_RTHUMBFORWARDRIGHT_ALT "" -// set vr_button_map_RTHUMBBACK "" +// set vr_button_map_RTHUMBRIGHT "turnright" +// set vr_button_map_RTHUMBRIGHT_ALT "" +// set vr_button_map_RTHUMBBACKRIGHT "" +// set vr_button_map_RTHUMBBACKRIGHT_ALT "" +// set vr_button_map_RTHUMBBACK "weapprev" // set vr_button_map_RTHUMBBACK_ALT "" // set vr_button_map_RTHUMBBACKLEFT "" // set vr_button_map_RTHUMBBACKLEFT_ALT "" -// set vr_button_map_RTHUMBBACKRIGHT "" -// set vr_button_map_RTHUMBBACKRIGHT_ALT "" -// set vr_button_map_SECONDARYTRIGGER "" -// set vr_button_map_SECONDARYTRIGGER_ALT "" -// set vr_button_map_PRIMARYTRIGGER "" -// set vr_button_map_PRIMARYTRIGGER_ALT "" -// set vr_button_map_SECONDARYGRIP "" -// set vr_button_map_SECONDARYGRIP_ALT "" -// set vr_button_map_PRIMARYGRIP "+alt" -// set vr_button_map_PRIMARYGRIP_ALT "" +// set vr_button_map_RTHUMBLEFT "turnleft" +// set vr_button_map_RTHUMBLEFT_ALT "" +// set vr_button_map_RTHUMBFORWARDLEFT "" +// set vr_button_map_RTHUMBFORWARDLEFT_ALT "" diff --git a/android/app/src/main/cpp/code/q3_ui/ui_controls3.c b/android/app/src/main/cpp/code/q3_ui/ui_controls3.c index d0ad8187..bf224e0d 100644 --- a/android/app/src/main/cpp/code/q3_ui/ui_controls3.c +++ b/android/app/src/main/cpp/code/q3_ui/ui_controls3.c @@ -169,27 +169,15 @@ static void Controls3_MenuEvent( void* ptr, int notification ) { trap_Cvar_Set("vr_button_map_PRIMARYGRIP", "+weapon_select"); // weapon selector trap_Cvar_Set("vr_button_map_PRIMARYTHUMBSTICK", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBFORWARD_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBRIGHT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBBACK_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT_ALT", ""); // unmapped break; case 1: // Weapon wheel on thumbstick - all directions as weapon select (useful for HMD wheel) trap_Cvar_Set("vr_button_map_RTHUMBFORWARD", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT", "+weapon_select"); trap_Cvar_Set("vr_button_map_RTHUMBRIGHT", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT", "+weapon_select"); trap_Cvar_Set("vr_button_map_RTHUMBBACK", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT", "+weapon_select"); trap_Cvar_Set("vr_button_map_RTHUMBLEFT", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT", "+weapon_select"); trap_Cvar_Set("vr_button_map_PRIMARYTHUMBSTICK", "+weapon_select"); trap_Cvar_Set("vr_button_map_PRIMARYGRIP", "+alt"); // switch to alt layout trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", "turnleft"); // turn left @@ -200,10 +188,6 @@ static void Controls3_MenuEvent( void* ptr, int notification ) { } else { trap_Cvar_Set("vr_button_map_RTHUMBBACK_ALT", "weapprev"); } - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT_ALT", "blank"); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT_ALT", "blank"); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT_ALT", "blank"); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT_ALT", "blank"); // unmapped break; default: // Weapon wheel disabled - only prev/next weapon switch is active trap_Cvar_Set("vr_button_map_RTHUMBLEFT", "turnleft"); // turn left @@ -217,17 +201,9 @@ static void Controls3_MenuEvent( void* ptr, int notification ) { trap_Cvar_Set("vr_button_map_PRIMARYGRIP", ""); // unmapped trap_Cvar_Set("vr_button_map_PRIMARYTHUMBSTICK", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBFORWARD_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBRIGHT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBBACK_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT_ALT", ""); // unmapped break; } } diff --git a/android/app/src/main/cpp/code/ui/ui_main.c b/android/app/src/main/cpp/code/ui/ui_main.c index 8a36c653..d37fa0fa 100644 --- a/android/app/src/main/cpp/code/ui/ui_main.c +++ b/android/app/src/main/cpp/code/ui/ui_main.c @@ -3186,27 +3186,15 @@ static void UI_Update(const char *name) { trap_Cvar_Set("vr_button_map_PRIMARYGRIP", "+weapon_select"); // weapon selector trap_Cvar_Set("vr_button_map_PRIMARYTHUMBSTICK", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBFORWARD_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBRIGHT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBBACK_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT_ALT", ""); // unmapped break; case 1: // Weapon wheel on thumbstick - all directions as weapon select (useful for HMD wheel) trap_Cvar_Set("vr_button_map_RTHUMBFORWARD", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT", "+weapon_select"); trap_Cvar_Set("vr_button_map_RTHUMBRIGHT", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT", "+weapon_select"); trap_Cvar_Set("vr_button_map_RTHUMBBACK", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT", "+weapon_select"); trap_Cvar_Set("vr_button_map_RTHUMBLEFT", "+weapon_select"); - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT", "+weapon_select"); trap_Cvar_Set("vr_button_map_PRIMARYTHUMBSTICK", "+weapon_select"); trap_Cvar_Set("vr_button_map_PRIMARYGRIP", "+alt"); // switch to alt layout trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", "turnleft"); // turn left @@ -3217,10 +3205,6 @@ static void UI_Update(const char *name) { } else { trap_Cvar_Set("vr_button_map_RTHUMBBACK_ALT", "weapprev"); } - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT_ALT", "blank"); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT_ALT", "blank"); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT_ALT", "blank"); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT_ALT", "blank"); // unmapped break; default: // Weapon wheel disabled - only prev/next weapon switch is active trap_Cvar_Set("vr_button_map_RTHUMBLEFT", "turnleft"); // turn left @@ -3234,17 +3218,9 @@ static void UI_Update(const char *name) { trap_Cvar_Set("vr_button_map_PRIMARYGRIP", ""); // unmapped trap_Cvar_Set("vr_button_map_PRIMARYTHUMBSTICK", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBFORWARD_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBRIGHT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKRIGHT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBBACK_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBBACKLEFT_ALT", ""); // unmapped trap_Cvar_Set("vr_button_map_RTHUMBLEFT_ALT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT", ""); // unmapped - trap_Cvar_Set("vr_button_map_RTHUMBFORWARDLEFT_ALT", ""); // unmapped break; } } else if (Q_stricmp(name, "vr_uturn") == 0) { diff --git a/android/app/src/main/cpp/code/vr/vr_base.c b/android/app/src/main/cpp/code/vr/vr_base.c index c0649f3d..1fb3a243 100644 --- a/android/app/src/main/cpp/code/vr/vr_base.c +++ b/android/app/src/main/cpp/code/vr/vr_base.c @@ -124,27 +124,15 @@ void VR_InitCvars( void ) Cvar_Get ("vr_button_map_PRIMARYGRIP", "+weapon_select", CVAR_ARCHIVE); // weapon selector Cvar_Get ("vr_button_map_PRIMARYTHUMBSTICK", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBFORWARD_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDRIGHT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDRIGHT_ALT", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBRIGHT_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKRIGHT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKRIGHT_ALT", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBBACK_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKLEFT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKLEFT_ALT", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBLEFT_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDLEFT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDLEFT_ALT", "", CVAR_ARCHIVE); // unmapped } else if (controlSchema == 1) { // Weapon wheel on thumbstick - all directions as weapon select (useful for HMD wheel) Cvar_Get ("vr_button_map_RTHUMBFORWARD", "+weapon_select", CVAR_ARCHIVE); - Cvar_Get ("vr_button_map_RTHUMBFORWARDRIGHT", "+weapon_select", CVAR_ARCHIVE); Cvar_Get ("vr_button_map_RTHUMBRIGHT", "+weapon_select", CVAR_ARCHIVE); - Cvar_Get ("vr_button_map_RTHUMBBACKRIGHT", "+weapon_select", CVAR_ARCHIVE); Cvar_Get ("vr_button_map_RTHUMBBACK", "+weapon_select", CVAR_ARCHIVE); - Cvar_Get ("vr_button_map_RTHUMBBACKLEFT", "+weapon_select", CVAR_ARCHIVE); Cvar_Get ("vr_button_map_RTHUMBLEFT", "+weapon_select", CVAR_ARCHIVE); - Cvar_Get ("vr_button_map_RTHUMBFORWARDLEFT", "+weapon_select", CVAR_ARCHIVE); Cvar_Get ("vr_button_map_PRIMARYTHUMBSTICK", "+weapon_select", CVAR_ARCHIVE); Cvar_Get ("vr_button_map_PRIMARYGRIP", "+alt", CVAR_ARCHIVE); // switch to alt layout Cvar_Get ("vr_button_map_RTHUMBLEFT_ALT", "turnleft", CVAR_ARCHIVE); // turn left @@ -155,10 +143,6 @@ void VR_InitCvars( void ) } else { Cvar_Get ("vr_button_map_RTHUMBBACK_ALT", "weapprev", CVAR_ARCHIVE); } - Cvar_Get ("vr_button_map_RTHUMBFORWARDRIGHT_ALT", "blank", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKRIGHT_ALT", "blank", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKLEFT_ALT", "blank", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDLEFT_ALT", "blank", CVAR_ARCHIVE); // unmapped } else { // Weapon wheel disabled - only prev/next weapon switch is active Cvar_Get ("vr_button_map_RTHUMBLEFT", "turnleft", CVAR_ARCHIVE); // turn left @@ -172,17 +156,9 @@ void VR_InitCvars( void ) Cvar_Get ("vr_button_map_PRIMARYGRIP", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_PRIMARYTHUMBSTICK", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBFORWARD_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDRIGHT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDRIGHT_ALT", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBRIGHT_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKRIGHT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKRIGHT_ALT", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBBACK_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKLEFT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBBACKLEFT_ALT", "", CVAR_ARCHIVE); // unmapped Cvar_Get ("vr_button_map_RTHUMBLEFT_ALT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDLEFT", "", CVAR_ARCHIVE); // unmapped - Cvar_Get ("vr_button_map_RTHUMBFORWARDLEFT_ALT", "", CVAR_ARCHIVE); // unmapped } //Remaining button mapping (buttons not affected by schemas) diff --git a/android/app/src/main/cpp/code/vr/vr_input.c b/android/app/src/main/cpp/code/vr/vr_input.c index 691a482e..891b6869 100644 --- a/android/app/src/main/cpp/code/vr/vr_input.c +++ b/android/app/src/main/cpp/code/vr/vr_input.c @@ -105,6 +105,11 @@ static ovrVector3f normalizeVec(ovrVector3f vec) { return result; } +static float length(float x, float y) +{ + return sqrtf(powf(x, 2.0f) + powf(y, 2.0f)); +} + void NormalizeAngles(vec3_t angles) { while (angles[0] >= 90) angles[0] -= 180; @@ -244,23 +249,51 @@ static void VR_processHaptics() { } } -// Returns true in case button press should be auto-repeated when holding (now only applicable for smooth-turn) -static qboolean IN_SendButtonAction(const char* action, qboolean pressed, qboolean isThumbstickAxis, float axisValue) +static qboolean IN_GetInputAction(const char* inputName, char* action) +{ + char cvarname[256]; + Com_sprintf(cvarname, 256, "vr_button_map_%s%s", inputName, alt_key_mode_active ? "_ALT" : ""); + char * val = Cvar_VariableString(cvarname); + if (val && strlen(val) > 0) + { + if (strcmp(val, "blank") == 0) { + // Empty function to block alt fallback on unmapped alt inputs + return qfalse; + } else { + Com_sprintf(action, 256, "%s", val); + return qtrue; + } + } + + //If we didn't find something for this input and the alt key is active, then see if the un-alt key has a function + if (alt_key_mode_active) + { + Com_sprintf(cvarname, 256, "vr_button_map_%s", inputName); + char * val = Cvar_VariableString(cvarname); + if (val && strlen(val) > 0) + { + Com_sprintf(action, 256, "%s", val); + return qtrue; + } + } + + return qfalse; +} + +// Returns true in case active input should be auto-repeated (now only applicable for smooth-turn) +static qboolean IN_SendInputAction(const char* action, qboolean inputActive, float axisValue, qboolean thumbstickAxis) { if (action) { //handle our special actions first - if (strcmp(action, "blank") == 0) { - // empty function to block alt fallback on unmapped alt buttons - } - else if (strcmp(action, "+alt") == 0) + if (strcmp(action, "+alt") == 0) { - alt_key_mode_active = pressed; + alt_key_mode_active = inputActive; } else if (strcmp(action, "+weapon_stabilise") == 0) { //stabilised weapon only triggered when controllers close enough (40cm) to each other - if (pressed) + if (inputActive) { vec3_t l; VectorSubtract(vr.weaponposition, vr.offhandposition, l); @@ -275,13 +308,13 @@ static qboolean IN_SendButtonAction(const char* action, qboolean pressed, qboole //server search in the server menu else if (strcmp(action, "+moveup") == 0) { - Com_QueueEvent(in_vrEventTime, SE_KEY, K_SPACE, pressed, 0, NULL); + Com_QueueEvent(in_vrEventTime, SE_KEY, K_SPACE, inputActive, 0, NULL); } else if (strcmp(action, "+weapon_select") == 0) { - vr.weapon_select = pressed; - vr.weapon_select_autoclose = isThumbstickAxis; - if (!pressed) + vr.weapon_select = inputActive; + vr.weapon_select_autoclose = thumbstickAxis; + if (!inputActive) { Cbuf_AddText("weapon_select"); } @@ -289,10 +322,10 @@ static qboolean IN_SendButtonAction(const char* action, qboolean pressed, qboole else if (action[0] == '+') { char command[256]; - Com_sprintf(command, sizeof(command), "%s%s\n", pressed ? "+" : "-", action + 1); + Com_sprintf(command, sizeof(command), "%s%s\n", inputActive ? "+" : "-", action + 1); Cbuf_AddText(command); } - else if (pressed) + else if (inputActive) { if (strcmp(action, "turnleft") == 0) { if (vr_snapturn->integer > 0) { // snap turn @@ -302,7 +335,7 @@ static qboolean IN_SendButtonAction(const char* action, qboolean pressed, qboole } CL_SnapTurn(-snap); } else { // yaw (smooth turn) - float value = (isThumbstickAxis ? axisValue : 1.0f) * cl_sensitivity->value * m_yaw->value; + float value = (axisValue > 0.0f ? axisValue : 1.0f) * cl_sensitivity->value * m_yaw->value; Com_QueueEvent(in_vrEventTime, SE_MOUSE, -value, 0, 0, NULL); return qtrue; } @@ -314,7 +347,7 @@ static qboolean IN_SendButtonAction(const char* action, qboolean pressed, qboole } CL_SnapTurn(snap); } else { // yaw (smooth turn) - float value = (isThumbstickAxis ? axisValue : 1.0f) * cl_sensitivity->value * m_yaw->value; + float value = (axisValue > 0.0f ? axisValue : 1.0f) * cl_sensitivity->value * m_yaw->value; Com_QueueEvent(in_vrEventTime, SE_MOUSE, value, 0, 0, NULL); return qtrue; } @@ -330,6 +363,53 @@ static qboolean IN_SendButtonAction(const char* action, qboolean pressed, qboole return qfalse; } +static void IN_ActivateInput(uint32_t * inputGroup, int inputFlag) { + *inputGroup |= inputFlag; +} + +static void IN_DeactivateInput(uint32_t * inputGroup, int inputFlag) { + *inputGroup &= ~inputFlag; +} + +static qboolean IN_InputActivated(uint32_t * inputGroup, int inputFlag) { + return (*inputGroup & inputFlag); +} + +static void IN_HandleActiveInput(uint32_t * inputGroup, int inputFlag, char* inputName, float axisValue, qboolean thumbstickAxis) { + if (IN_InputActivated(inputGroup, inputFlag)) { + // Input is already in activated state, nothing to do + return; + } + char action[256]; + if (IN_GetInputAction(inputName, action)) { + // Activate input action + if (!IN_SendInputAction(action, qtrue, axisValue, thumbstickAxis)) { + // Action should not be repeated, mark input as activated + IN_ActivateInput(inputGroup, inputFlag); + } + } else { + // No assigned action -> mark input as activated + // (to avoid unnecessary action lookup next time) + IN_ActivateInput(inputGroup, inputFlag); + } +} + +static void IN_HandleInactiveInput(uint32_t * inputGroup, int inputFlag, char* inputName, float axisValue, qboolean thumbstickAxis) { + if (!IN_InputActivated(inputGroup, inputFlag)) { + // Input is not in activated state, nothing to do + return; + } + char action[256]; + if (IN_GetInputAction(inputName, action)) { + // Deactivate input action and remove input activated state + IN_SendInputAction(action, qfalse, axisValue, thumbstickAxis); + IN_DeactivateInput(inputGroup, inputFlag); + } else { + // No assigned action -> just remove input activated state + IN_DeactivateInput(inputGroup, inputFlag); + } +} + void VR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight ) { if (vr_hapticIntensity->value == 0.0f) @@ -388,37 +468,6 @@ void VR_HapticEvent(const char* event, int position, int flags, int intensity, f } } -static qboolean IN_GetButtonAction(const char* button, char* action) -{ - char cvarname[256]; - Com_sprintf(cvarname, 256, "vr_button_map_%s%s", button, alt_key_mode_active ? "_ALT" : ""); - char * val = Cvar_VariableString(cvarname); - if (val && strlen(val) > 0) - { - Com_sprintf(action, 256, "%s", val); - return qtrue; - } - - //If we didn't find something for this button and the alt key is active, then see if the un-alt key has a function - if (alt_key_mode_active) - { - Com_sprintf(cvarname, 256, "vr_button_map_%s", button); - char * val = Cvar_VariableString(cvarname); - if (val && strlen(val) > 0) - { - Com_sprintf(action, 256, "%s", val); - return qtrue; - } - } - - return qfalse; -} - -static float length(float x, float y) -{ - return sqrtf(powf(x, 2.0f) + powf(y, 2.0f)); -} - void IN_VRInit( void ) { memset(&vr, 0, sizeof(vr)); @@ -515,9 +564,120 @@ static void IN_VRController( qboolean isRightController, ovrTracking remoteTrack } } +static qboolean IN_VRJoystickUse8WayMapping( void ) { + char action[256]; + return IN_GetInputAction("RTHUMBFORWARDRIGHT", action) + || IN_GetInputAction("RTHUMBBACKRIGHT", action) + || IN_GetInputAction("RTHUMBBACKLEFT", action) + || IN_GetInputAction("RTHUMBFORWARDLEFT", action); +} + +static void IN_VRJoystickHandle4WayMapping( uint32_t * inputGroup, float joystickAngle, float joystickValue ) { + if (joystickAngle >= 315.0 || joystickAngle < 45.0) { // UP + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + // Activate UP + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + } else if (joystickAngle < 135.0) { // RIGHT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + // Activate RIGHT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + } else if (joystickAngle < 225.0) { // DOWN + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + // Activate DOWN + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + } else { // LEFT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + // Activate LEFT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + } +} + +static void IN_VRJoystickHandle8WayMapping( uint32_t * inputGroup, float joystickAngle, float joystickValue ) { + if (joystickAngle > 337.5 || joystickAngle < 22.5) { // UP + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + // Activate UP + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + } else if (joystickAngle < 67.5) { // UP-RIGHT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + // Activate UP-RIGHT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + } else if (joystickAngle < 112.5) { // RIGHT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + // Activate RIGHT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + } else if (joystickAngle < 157.5) { // DOWN-RIGHT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + // Activate DOWN-RIGHT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + } else if (joystickAngle < 202.5) { // DOWN + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + // Activate DOWN + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + } else if (joystickAngle < 247.5) { // DOWN-LEFT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + // Activate DOWN-LEFT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + } else if (joystickAngle < 292.5) { // LEFT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + // Activate LEFT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + } else { // UP-LEFT + // Deactivate neighboring inputs + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + IN_HandleInactiveInput(inputGroup, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + // Activate UP-LEFT + IN_HandleActiveInput(inputGroup, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); + } +} + static void IN_VRJoystick( qboolean isRightController, float joystickX, float joystickY ) { - char action[256]; vrController_t* controller = isRightController == qtrue ? &rightController : &leftController; vr.thumbstick_location[isRightController][0] = joystickX; @@ -567,557 +727,183 @@ static void IN_VRJoystick( qboolean isRightController, float joystickX, float jo //forward/back Com_QueueEvent(in_vrEventTime, SE_JOYSTICK_AXIS, 1, joystick[1] * 127.0f + positional[1] * 127.0f, 0, NULL); } + // In case weapon wheel is opened, and is in HMD/thumbstick mode or was opened by thumbstick, ignore standard thumbstick inputs // In case weapon wheel is in controller mode and is opened by grip, allow use use of thumbstick e.g. to not block turning while wheel is open else if (!vr.weapon_select || ((int)Cvar_VariableValue("vr_weaponSelectorMode") == WS_CONTROLLER && !vr.weapon_select_autoclose)) { - float absoluteAxisValue = sqrt(joystickY*joystickY + joystickX*joystickX); - - // up, up-left, up-right (use release threshold to be more sensitive) - if (joystickY > releasedThreshold) { - - // stop left & right - if ((controller->axisButtons & VR_TOUCH_AXIS_LEFT) && IN_GetButtonAction("RTHUMBLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_LEFT; - if ((controller->axisButtons & VR_TOUCH_AXIS_RIGHT) && IN_GetButtonAction("RTHUMBRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_RIGHT; - - // up-left (use release threshold to be more sensitive) - if (joystickX < -releasedThreshold) { - // stop up - if ((controller->axisButtons & VR_TOUCH_AXIS_UP) && IN_GetButtonAction("RTHUMBFORWARD", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UP; - // stop up-right - if ((controller->axisButtons & VR_TOUCH_AXIS_UPRIGHT) && IN_GetButtonAction("RTHUMBFORWARDRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UPRIGHT; - // start up-left - if (!(controller->axisButtons & VR_TOUCH_AXIS_UPLEFT)) { - if (IN_GetButtonAction("RTHUMBFORWARDLEFT", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_UPLEFT; - }; - } else { - controller->axisButtons |= VR_TOUCH_AXIS_UPLEFT; - } - } - - // up-right (use release threshold to be more sensitive) - } else if (joystickX > releasedThreshold) { - // stop up - if ((controller->axisButtons & VR_TOUCH_AXIS_UP) && IN_GetButtonAction("RTHUMBFORWARD", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UP; - // stop up-left - if ((controller->axisButtons & VR_TOUCH_AXIS_UPLEFT) && IN_GetButtonAction("RTHUMBFORWARDLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UPLEFT; - // start up-right - if (!(controller->axisButtons & VR_TOUCH_AXIS_UPRIGHT)) { - if (IN_GetButtonAction("RTHUMBFORWARDRIGHT", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_UPRIGHT; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_UPRIGHT; - } - } - - // direct-up - } else { - // stop up-left - if ((controller->axisButtons & VR_TOUCH_AXIS_UPLEFT) && IN_GetButtonAction("RTHUMBFORWARDLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UPLEFT; - // stop up-right - if ((controller->axisButtons & VR_TOUCH_AXIS_UPRIGHT) && IN_GetButtonAction("RTHUMBFORWARDRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UPRIGHT; - // start up - if (!(controller->axisButtons & VR_TOUCH_AXIS_UP) && joystickY > pressedThreshold) { - if (IN_GetButtonAction("RTHUMBFORWARD", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_UP; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_UP; - } - } - } - - // down, down-left, down-right (use release threshold to be more sensitive) - } else if (joystickY < -releasedThreshold) { - - // stop left & right - if ((controller->axisButtons & VR_TOUCH_AXIS_LEFT) && IN_GetButtonAction("RTHUMBLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_LEFT; - if ((controller->axisButtons & VR_TOUCH_AXIS_RIGHT) && IN_GetButtonAction("RTHUMBRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_RIGHT; - - // down-left (use release threshold to be more sensitive) - if (joystickX < -releasedThreshold) { - // stop down - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWN) && IN_GetButtonAction("RTHUMBBACK", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWN; - // stop down-right - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWNRIGHT) && IN_GetButtonAction("RTHUMBBACKRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWNRIGHT; - // start down-left - if (!(controller->axisButtons & VR_TOUCH_AXIS_DOWNLEFT)) { - if (IN_GetButtonAction("RTHUMBBACKLEFT", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_DOWNLEFT; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_DOWNLEFT; - } - } - - // down-right (use release threshold to be more sensitive) - } else if (joystickX > releasedThreshold) { - // stop down - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWN) && IN_GetButtonAction("RTHUMBBACK", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWN; - // stop down-left - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWNLEFT) && IN_GetButtonAction("RTHUMBBACKLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWNLEFT; - // start down-right - if (!(controller->axisButtons & VR_TOUCH_AXIS_DOWNRIGHT)) { - if (IN_GetButtonAction("RTHUMBBACKRIGHT", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_DOWNRIGHT; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_DOWNRIGHT; - } - } - - // direct-down - } else { - // stop down-left - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWNLEFT) && IN_GetButtonAction("RTHUMBBACKLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWNLEFT; - // stop down-right - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWNRIGHT) && IN_GetButtonAction("RTHUMBBACKRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWNRIGHT; - // start down - if (!(controller->axisButtons & VR_TOUCH_AXIS_DOWN) && joystickY < -pressedThreshold) { - if (IN_GetButtonAction("RTHUMBBACK", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_DOWN; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_DOWN; - } - } - } - - // left & right + float joystickValue = length(joystickX, joystickY); + if (joystickValue < releasedThreshold) { + // Joystick within threshold -> disable all inputs + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_UP, "RTHUMBFORWARD", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_UPRIGHT, "RTHUMBFORWARDRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_RIGHT, "RTHUMBRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_DOWNRIGHT, "RTHUMBBACKRIGHT", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_DOWN, "RTHUMBBACK", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_DOWNLEFT, "RTHUMBBACKLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_LEFT, "RTHUMBLEFT", joystickValue, qtrue); + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_UPLEFT, "RTHUMBFORWARDLEFT", joystickValue, qtrue); } else { - - // stop up-left - if ((controller->axisButtons & VR_TOUCH_AXIS_UPLEFT) && IN_GetButtonAction("RTHUMBFORWARDLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); + float joystickAngle = AngleNormalize360(RAD2DEG(atan2(joystickX, joystickY))); + if (IN_VRJoystickUse8WayMapping()) { + IN_VRJoystickHandle8WayMapping(&controller->axisButtons, joystickAngle, joystickValue); + } else { + IN_VRJoystickHandle4WayMapping(&controller->axisButtons, joystickAngle, joystickValue); } - controller->axisButtons &= ~VR_TOUCH_AXIS_UPLEFT; - // stop up - if ((controller->axisButtons & VR_TOUCH_AXIS_UP) && IN_GetButtonAction("RTHUMBFORWARD", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UP; - // stop up-right - if ((controller->axisButtons & VR_TOUCH_AXIS_UPRIGHT) && IN_GetButtonAction("RTHUMBFORWARDRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_UPRIGHT; - // stop down-left - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWNLEFT) && IN_GetButtonAction("RTHUMBBACKLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWNLEFT; - // stop down - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWN) && IN_GetButtonAction("RTHUMBBACK", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWN; - // stop down-right - if ((controller->axisButtons & VR_TOUCH_AXIS_DOWNRIGHT) && IN_GetButtonAction("RTHUMBBACKRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_DOWNRIGHT; - - // left - if (joystickX < -pressedThreshold) { - if (!(controller->axisButtons & VR_TOUCH_AXIS_LEFT)) { - if (IN_GetButtonAction("RTHUMBLEFT", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_LEFT; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_LEFT; - } - } - } else if (joystickX > -releasedThreshold) { - if ((controller->axisButtons & VR_TOUCH_AXIS_LEFT) && IN_GetButtonAction("RTHUMBLEFT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_LEFT; - } - - // right - if (joystickX > pressedThreshold) { - if (!(controller->axisButtons & VR_TOUCH_AXIS_RIGHT)) { - if (IN_GetButtonAction("RTHUMBRIGHT", action)) { - if (!IN_SendButtonAction(action, qtrue, qtrue, absoluteAxisValue)) { - controller->axisButtons |= VR_TOUCH_AXIS_RIGHT; - } - } else { - controller->axisButtons |= VR_TOUCH_AXIS_RIGHT; - } - } - } else if (joystickX < releasedThreshold) { - if ((controller->axisButtons & VR_TOUCH_AXIS_RIGHT) && IN_GetButtonAction("RTHUMBRIGHT", action)) { - IN_SendButtonAction(action, qfalse, qtrue, absoluteAxisValue); - } - controller->axisButtons &= ~VR_TOUCH_AXIS_RIGHT; - } - } - } + } } -static void IN_VRTriggers( qboolean isRightController, float index ) { +static void IN_VRTriggers( qboolean isRightController, float triggerValue ) { vrController_t* controller = isRightController == qtrue ? &rightController : &leftController; - // Controllers are used for menu navigation in screen mode or in intermission - if (VR_useScreenLayer() || cl.snap.ps.pm_type == PM_INTERMISSION) - { - if (!(controller->axisButtons & VR_TOUCH_AXIS_TRIGGER_INDEX) && index > pressedThreshold) + if (VR_useScreenLayer() || cl.snap.ps.pm_type == PM_INTERMISSION) { + + // Triggers are used for menu navigation in screen mode or in intermission + if (triggerValue > pressedThreshold && !IN_InputActivated(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX)) { - controller->axisButtons |= VR_TOUCH_AXIS_TRIGGER_INDEX; + IN_ActivateInput(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX); if ((isRightController && !vr.menuLeftHanded) || (!isRightController && vr.menuLeftHanded)) { // Active controller confirms selection Com_QueueEvent(in_vrEventTime, SE_KEY, K_MOUSE1, qtrue, 0, NULL); - VR_Vibrate(200, vr_righthanded->integer ? 2 : 1, 0.8); + VR_Vibrate(200, vr.menuLeftHanded ? 1 : 2, 0.8); } else { // Inactive controller becomes active one vr.menuLeftHanded = !vr.menuLeftHanded; } } - else if ((controller->axisButtons & VR_TOUCH_AXIS_TRIGGER_INDEX) && index < releasedThreshold) + else if (triggerValue < releasedThreshold && IN_InputActivated(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX)) { - controller->axisButtons &= ~VR_TOUCH_AXIS_TRIGGER_INDEX; + IN_DeactivateInput(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX); if ((isRightController && !vr.menuLeftHanded) || (!isRightController && vr.menuLeftHanded)) { Com_QueueEvent(in_vrEventTime, SE_KEY, K_MOUSE1, qfalse, 0, NULL); } } - } - else - { - char action[256]; + + } else { - //Primary trigger + // Primary trigger if (isRightController == (vr_righthanded->integer != 0)) { - if (!(controller->axisButtons & VR_TOUCH_AXIS_TRIGGER_INDEX) && - index > pressedThreshold) - { - if (IN_GetButtonAction("PRIMARYTRIGGER", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->axisButtons |= VR_TOUCH_AXIS_TRIGGER_INDEX; - } - } - else - { - controller->axisButtons |= VR_TOUCH_AXIS_TRIGGER_INDEX; - } - } - else if ((controller->axisButtons & VR_TOUCH_AXIS_TRIGGER_INDEX) && - index < releasedThreshold) - { - controller->axisButtons &= ~VR_TOUCH_AXIS_TRIGGER_INDEX; - if (IN_GetButtonAction("PRIMARYTRIGGER", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } + if (triggerValue > pressedThreshold) { + IN_HandleActiveInput(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX, "PRIMARYTRIGGER", triggerValue, qfalse); + } else if (triggerValue < releasedThreshold) { + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX, "PRIMARYTRIGGER", triggerValue, qfalse); } } - //off hand trigger + // Off hand trigger if (isRightController != (vr_righthanded->integer != 0)) { - if (!(controller->axisButtons & VR_TOUCH_AXIS_TRIGGER_INDEX) && - index > pressedThreshold) - { - if (IN_GetButtonAction("SECONDARYTRIGGER", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->axisButtons |= VR_TOUCH_AXIS_TRIGGER_INDEX; - } - } - else - { - controller->axisButtons |= VR_TOUCH_AXIS_TRIGGER_INDEX; - } - } - else if ((controller->axisButtons & VR_TOUCH_AXIS_TRIGGER_INDEX) && - index < releasedThreshold) - { - controller->axisButtons &= ~VR_TOUCH_AXIS_TRIGGER_INDEX; - if (IN_GetButtonAction("SECONDARYTRIGGER", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } + if (triggerValue > pressedThreshold) { + IN_HandleActiveInput(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX, "SECONDARYTRIGGER", triggerValue, qfalse); + } else if (triggerValue < releasedThreshold) { + IN_HandleInactiveInput(&controller->axisButtons, VR_TOUCH_AXIS_TRIGGER_INDEX, "SECONDARYTRIGGER", triggerValue, qfalse); } } + } } static void IN_VRButtons( qboolean isRightController, uint32_t buttons ) { - char action[256]; - vrController_t* controller = isRightController == qtrue ? &rightController : &leftController; - { - if ((buttons & ovrButton_Enter) && !(controller->buttons & ovrButton_Enter)) { - controller->buttons |= ovrButton_Enter; - Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qtrue, 0, NULL); - } else if (!(buttons & ovrButton_Enter) && (controller->buttons & ovrButton_Enter)) { - controller->buttons &= ~ovrButton_Enter; - Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qfalse, 0, NULL); - } + // Menu button + if ((buttons & ovrButton_Enter) && !IN_InputActivated(&controller->buttons, ovrButton_Enter)) { + IN_ActivateInput(&controller->buttons, ovrButton_Enter); + Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qtrue, 0, NULL); + } else if (!(buttons & ovrButton_Enter) && IN_InputActivated(&controller->buttons, ovrButton_Enter)) { + IN_DeactivateInput(&controller->buttons, ovrButton_Enter); + Com_QueueEvent(in_vrEventTime, SE_KEY, K_ESCAPE, qfalse, 0, NULL); } if (isRightController == !vr_righthanded->integer) { - if ((buttons & ovrButton_GripTrigger) && !(controller->buttons & ovrButton_GripTrigger)) - { - if (IN_GetButtonAction("SECONDARYGRIP", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_GripTrigger; - } - } - else - { - controller->buttons |= ovrButton_GripTrigger; - } - } - else if (!(buttons & ovrButton_GripTrigger) && - (controller->buttons & ovrButton_GripTrigger)) - { - controller->buttons &= ~ovrButton_GripTrigger; - if (IN_GetButtonAction("SECONDARYGRIP", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } + if (buttons & ovrButton_GripTrigger) { + IN_HandleActiveInput(&controller->buttons, ovrButton_GripTrigger, "SECONDARYGRIP", 0, qfalse); + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_GripTrigger, "SECONDARYGRIP", 0, qfalse); } } else { - if ((buttons & ovrButton_GripTrigger) && !(controller->buttons & ovrButton_GripTrigger)) - { - if (IN_GetButtonAction("PRIMARYGRIP", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_GripTrigger; - } - } - else - { - controller->buttons |= ovrButton_GripTrigger; - } - } - else if (!(buttons & ovrButton_GripTrigger) && - (controller->buttons & ovrButton_GripTrigger)) - { - controller->buttons &= ~ovrButton_GripTrigger; - if (IN_GetButtonAction("PRIMARYGRIP", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } + if (buttons & ovrButton_GripTrigger) { + IN_HandleActiveInput(&controller->buttons, ovrButton_GripTrigger, "PRIMARYGRIP", 0, qfalse); + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_GripTrigger, "PRIMARYGRIP", 0, qfalse); } } - if (isRightController == !vr_righthanded->integer) { - if ((buttons & ovrButton_LThumb) && !(controller->buttons & ovrButton_LThumb)) { - if (IN_GetButtonAction("SECONDARYTHUMBSTICK", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_LThumb; - } - } - else - { - controller->buttons |= ovrButton_LThumb; - } - - vr.realign = 3; - } else if (!(buttons & ovrButton_LThumb) && (controller->buttons & ovrButton_LThumb)) { - controller->buttons &= ~ovrButton_LThumb; - if (IN_GetButtonAction("SECONDARYTHUMBSTICK", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); + if (buttons & ovrButton_LThumb) { + if (!IN_InputActivated(&controller->buttons, ovrButton_LThumb)) { + // Initiate position reset for fake 6DoF + vr.realign = 3; } + IN_HandleActiveInput(&controller->buttons, ovrButton_LThumb, "SECONDARYTHUMBSTICK", 0, qfalse); + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_LThumb, "SECONDARYTHUMBSTICK", 0, qfalse); } } else { - if ((buttons & ovrButton_RThumb) && !(controller->buttons & ovrButton_RThumb)) { - if (IN_GetButtonAction("PRIMARYTHUMBSTICK", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_RThumb; - } - } - else - { - controller->buttons |= ovrButton_RThumb; - } - } else if (!(buttons & ovrButton_RThumb) && (controller->buttons & ovrButton_RThumb)) { - controller->buttons &= ~ovrButton_RThumb; - if (IN_GetButtonAction("PRIMARYTHUMBSTICK", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } + if (buttons & ovrButton_RThumb) { + IN_HandleActiveInput(&controller->buttons, ovrButton_RThumb, "PRIMARYTHUMBSTICK", 0, qfalse); + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_RThumb, "PRIMARYTHUMBSTICK", 0, qfalse); } } - //Jump - if ((buttons & ovrButton_A) && !(controller->buttons & ovrButton_A)) - { + if (buttons & ovrButton_A) { if (cl.snap.ps.pm_flags & PMF_FOLLOW) { - controller->buttons |= ovrButton_A; - Cbuf_AddText("cmd team spectator\n"); - } - else - { - if (IN_GetButtonAction("A", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_A; - } - } - else - { - controller->buttons |= ovrButton_A; - } - } - } - else if (!(buttons & ovrButton_A) && (controller->buttons & ovrButton_A)) - { - controller->buttons &= ~ovrButton_A; - if (IN_GetButtonAction("A", action) && !(cl.snap.ps.pm_flags & PMF_FOLLOW)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } - } - - //Crouch - if ((buttons & ovrButton_B) && !(controller->buttons & ovrButton_B)) { - if (IN_GetButtonAction("B", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_B; + // Go back to free spectator mode if following player + if (!IN_InputActivated(&controller->buttons, ovrButton_A)) { + IN_ActivateInput(&controller->buttons, ovrButton_A); + Cbuf_AddText("cmd team spectator\n"); } } else { - controller->buttons |= ovrButton_B; - } - } else if (!(buttons & ovrButton_B) && (controller->buttons & ovrButton_B)) { - controller->buttons &= ~ovrButton_B; - if (IN_GetButtonAction("B", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); + IN_HandleActiveInput(&controller->buttons, ovrButton_A, "A", 0, qfalse); } + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_A, "A", 0, qfalse); } - //X default is "use item" - if ((buttons & ovrButton_X) && !(controller->buttons & ovrButton_X)) - { + if (buttons & ovrButton_B) { + IN_HandleActiveInput(&controller->buttons, ovrButton_B, "B", 0, qfalse); + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_B, "B", 0, qfalse); + } + + if (buttons & ovrButton_X) { if (cl.snap.ps.pm_flags & PMF_FOLLOW) { - controller->buttons |= ovrButton_X; - //Switch follow mode - vr.follow_mode = (vr.follow_mode+1) % VRFM_NUM_FOLLOWMODES; + // Switch follow mode + if (!IN_InputActivated(&controller->buttons, ovrButton_X)) { + IN_ActivateInput(&controller->buttons, ovrButton_X); + vr.follow_mode = (vr.follow_mode+1) % VRFM_NUM_FOLLOWMODES; + } } else { - if (IN_GetButtonAction("X", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_X; - } - } - else - { - controller->buttons |= ovrButton_X; - } - } - } - else if (!(buttons & ovrButton_X) && (controller->buttons & ovrButton_X)) - { - controller->buttons &= ~ovrButton_X; - if (IN_GetButtonAction("X", action) && !(cl.snap.ps.pm_flags & PMF_FOLLOW)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); + IN_HandleActiveInput(&controller->buttons, ovrButton_X, "X", 0, qfalse); } + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_X, "X", 0, qfalse); } - //Y default is Gesture - if ((buttons & ovrButton_Y) && !(controller->buttons & ovrButton_Y)) { - if (IN_GetButtonAction("Y", action)) - { - if (!IN_SendButtonAction(action, qtrue, qfalse, 0)) { - controller->buttons |= ovrButton_Y; - } - } - else - { - controller->buttons |= ovrButton_Y; - } - } else if (!(buttons & ovrButton_Y) && (controller->buttons & ovrButton_Y)) { - controller->buttons &= ~ovrButton_Y; - if (IN_GetButtonAction("Y", action)) - { - IN_SendButtonAction(action, qfalse, qfalse, 0); - } + if (buttons & ovrButton_Y) { + IN_HandleActiveInput(&controller->buttons, ovrButton_Y, "Y", 0, qfalse); + } else { + IN_HandleInactiveInput(&controller->buttons, ovrButton_Y, "Y", 0, qfalse); } + } void IN_VRInputFrame( void ) @@ -1182,7 +968,6 @@ void IN_VRInputFrame( void ) vr.clientview_yaw_last = clientview_yaw; } - ovrInputCapabilityHeader capsHeader; uint32_t index = 0; for (;;) { @@ -1217,7 +1002,6 @@ void IN_VRInputFrame( void ) continue; } - qboolean isRight; vrController_t* controller; if (caps.ControllerCapabilities & ovrControllerCaps_LeftHand) {