diff --git a/src/common/console/c_buttons.cpp b/src/common/console/c_buttons.cpp index 3464553e3..2c6e23dbb 100644 --- a/src/common/console/c_buttons.cpp +++ b/src/common/console/c_buttons.cpp @@ -39,6 +39,8 @@ #include "printf.h" #include "cmdlib.h" #include "c_console.h" +#include "m_joy.h" +#include "c_bind.h" ButtonMap buttonMap; @@ -150,6 +152,26 @@ void ButtonMap::ResetButtonStates () // //============================================================================= +void ButtonMap::GetAxes () +{ + float joyaxes[NUM_AXIS_CODES]; + I_GetAxes(joyaxes); + + for (int i = 0; i < Buttons.Size(); i++) + { + FButtonStatus &btn = Buttons[i]; + FString &btn_name = NumToName[i]; + + btn.AddAxes(btn_name, joyaxes); + } +} + +//============================================================================= +// +// +// +//============================================================================= + bool FButtonStatus::PressKey (int keynum) { int i, open; @@ -246,6 +268,53 @@ bool FButtonStatus::ReleaseKey (int keynum) // //============================================================================= +void FButtonStatus::AddAxes (FString &btn_name, float joyaxes[NUM_AXIS_CODES]) +{ + int i; + + bIsAxis = false; + Axis = 0.0f; + + char cmd_name[16]; + strcpy(&cmd_name[1], btn_name.GetChars()); + + cmd_name[0] = '+'; + TArray positive_keys = Bindings.GetKeysForCommand(cmd_name); + + cmd_name[0] = '-'; + TArray negative_keys = Bindings.GetKeysForCommand(cmd_name); + + for (i = 0; i < NUM_AXIS_CODES; i++) + { + float axis_value = joyaxes[i]; + + if (axis_value > 0.0) + { + int key_code = KeyAxisMapping[i]; + + if (positive_keys.Contains(key_code)) + { + Axis += axis_value; + bIsAxis = true; + } + + if (negative_keys.Contains(key_code)) + { + Axis -= axis_value; + bIsAxis = true; + } + } + } + + Axis = clamp(Axis, 0.0f, 1.0f); +} + +//============================================================================= +// +// +// +//============================================================================= + void ButtonMap::AddButtonTabCommands() { // Add all the action commands for tab completion diff --git a/src/common/console/c_buttons.h b/src/common/console/c_buttons.h index 3bfbbd0fb..fd5040a84 100644 --- a/src/common/console/c_buttons.h +++ b/src/common/console/c_buttons.h @@ -3,6 +3,7 @@ #include #include "tarray.h" #include "name.h" +#include "keydef.h" // Actions struct FButtonStatus @@ -14,13 +15,18 @@ struct FButtonStatus bool bWentDown; // Button went down this tic bool bWentUp; // Button went up this tic bool bReleaseLock; // Lock ReleaseKey call in ResetButtonStates + + bool bIsAxis; // Whenever or not this button is being controlled by any axis. + float Axis; // How far the button has been pressed. Updated by I_GetAxes. + void (*PressHandler)(); // for optional game-side customization void (*ReleaseHandler)(); bool PressKey (int keynum); // Returns true if this key caused the button to be pressed. bool ReleaseKey (int keynum); // Returns true if this key is no longer pressed. + void AddAxes (FString &btn_name, float joyaxes[NUM_AXIS_CODES]); // Update joystick axis information. void ResetTriggers () { bWentDown = bWentUp = false; } - void Reset () { bDown = bWentDown = bWentUp = false; } + void Reset () { bDown = bWentDown = bWentUp = bIsAxis = false; Axis = 0.0f; } }; class ButtonMap @@ -53,6 +59,7 @@ public: void ResetButtonTriggers(); // Call ResetTriggers for all buttons void ResetButtonStates(); // Same as above, but also clear bDown + void GetAxes(); // Call AddAxes for all buttons int ListActionCommands(const char* pattern); void AddButtonTabCommands(); @@ -62,6 +69,28 @@ public: return Buttons[x].bDown; } + bool ButtonDownDigital(int x) const + { + // Like ButtonDown, but only for digital buttons. + // This is necessary, because of how the game runs different + // code for both digital and analog, and they can't be rolled + // together without introducing some subtle gameplay differences. + return (Buttons[x].bIsAxis == false && Buttons[x].bDown == true); + } + + float ButtonAnalog(int x) const + { + // Get the analog value of a button. + // This is 0.0 (not 1.0) for digital presses, because again, + // of how the game logic is split between the two. + if (Buttons[x].bIsAxis == true) + { + return Buttons[x].Axis; + } + + return 0.0f; + } + bool ButtonPressed(int x) const { return Buttons[x].bWentDown; diff --git a/src/common/console/keydef.h b/src/common/console/keydef.h index 620b5f5e7..ca9179ca7 100644 --- a/src/common/console/keydef.h +++ b/src/common/console/keydef.h @@ -147,3 +147,77 @@ enum EKeyCodes NUM_JOYAXISBUTTONS = 8, }; + +// Axes are provided per-key now, but passing around +// an entire NUM_KEYS-sized array is overkill. These +// codes are used for translating between axes and keys. +enum EAxisCodes +{ + AXIS_CODE_NULL = -1, + + AXIS_CODE_JOY1_PLUS = 0, + AXIS_CODE_JOY1_MINUS, + AXIS_CODE_JOY2_PLUS, + AXIS_CODE_JOY2_MINUS, + AXIS_CODE_JOY3_PLUS, + AXIS_CODE_JOY3_MINUS, + AXIS_CODE_JOY4_PLUS, + AXIS_CODE_JOY4_MINUS, + AXIS_CODE_JOY5_PLUS, + AXIS_CODE_JOY5_MINUS, + AXIS_CODE_JOY6_PLUS, + AXIS_CODE_JOY6_MINUS, + AXIS_CODE_JOY7_PLUS, + AXIS_CODE_JOY7_MINUS, + AXIS_CODE_JOY8_PLUS, + AXIS_CODE_JOY8_MINUS, + + AXIS_CODE_PAD_LTHUMB_RIGHT, + AXIS_CODE_PAD_LTHUMB_LEFT, + AXIS_CODE_PAD_LTHUMB_DOWN, + AXIS_CODE_PAD_LTHUMB_UP, + + AXIS_CODE_PAD_RTHUMB_RIGHT, + AXIS_CODE_PAD_RTHUMB_LEFT, + AXIS_CODE_PAD_RTHUMB_DOWN, + AXIS_CODE_PAD_RTHUMB_UP, + + AXIS_CODE_PAD_LTRIGGER, + AXIS_CODE_PAD_RTRIGGER, + + NUM_AXIS_CODES, +}; + + +static const int KeyAxisMapping[NUM_AXIS_CODES] = { + KEY_JOYAXIS1PLUS, + KEY_JOYAXIS1MINUS, + KEY_JOYAXIS2PLUS, + KEY_JOYAXIS2MINUS, + KEY_JOYAXIS3PLUS, + KEY_JOYAXIS3MINUS, + KEY_JOYAXIS4PLUS, + KEY_JOYAXIS4MINUS, + KEY_JOYAXIS5PLUS, + KEY_JOYAXIS5MINUS, + KEY_JOYAXIS6PLUS, + KEY_JOYAXIS6MINUS, + KEY_JOYAXIS7PLUS, + KEY_JOYAXIS7MINUS, + KEY_JOYAXIS8PLUS, + KEY_JOYAXIS8MINUS, + + KEY_PAD_LTHUMB_RIGHT, + KEY_PAD_LTHUMB_LEFT, + KEY_PAD_LTHUMB_DOWN, + KEY_PAD_LTHUMB_UP, + + KEY_PAD_RTHUMB_RIGHT, + KEY_PAD_RTHUMB_LEFT, + KEY_PAD_RTHUMB_DOWN, + KEY_PAD_RTHUMB_UP, + + KEY_PAD_LTRIGGER, + KEY_PAD_RTRIGGER, +}; + diff --git a/src/common/engine/m_joy.cpp b/src/common/engine/m_joy.cpp index 4ea016879..6b44bf228 100644 --- a/src/common/engine/m_joy.cpp +++ b/src/common/engine/m_joy.cpp @@ -222,18 +222,6 @@ bool M_LoadJoystickConfig(IJoystickConfig *joy) { joy->SetAxisResponseCurvePoint(i, 3, (float)atof(value)); } - - mysnprintf(key + axislen, countof(key) - axislen, "map"); - value = GameConfig->GetValueForKey(key); - if (value) - { - EJoyAxis gameaxis = (EJoyAxis)atoi(value); - if (gameaxis < JOYAXIS_None || gameaxis >= NUM_JOYAXIS) - { - gameaxis = JOYAXIS_None; - } - joy->SetAxisMap(i, gameaxis); - } } return true; } @@ -314,12 +302,6 @@ void M_SaveJoystickConfig(IJoystickConfig *joy) mysnprintf(value, countof(value), "%g", joy->GetAxisResponseCurvePoint(i, 3)); GameConfig->SetValueForKey(key, value); } - if (!joy->IsAxisMapDefault(i)) - { - mysnprintf(key + axislen, countof(key) - axislen, "map"); - mysnprintf(value, countof(value), "%d", joy->GetAxisMap(i)); - GameConfig->SetValueForKey(key, value); - } } // If the joystick is entirely at its defaults, delete this section // so that we don't write out a lone section header. @@ -355,7 +337,6 @@ CCMD (gamepad) "\n\tgamepad curve-y1 pad.axis [float]" "\n\tgamepad curve-x2 pad.axis [float]" "\n\tgamepad curve-y2 pad.axis [float]" - "\n\tgamepad map pad.axis [-1|0|1|2|3|4]" "\n" ); }; @@ -490,11 +471,6 @@ CCMD (gamepad) if (set) sticks[pad]->SetAxisResponseCurvePoint(axis, 3, value); return (void) Printf("%g\n", sticks[pad]->GetAxisResponseCurvePoint(axis, 3)); } - if (command == "map") - { - if (set) sticks[pad]->SetAxisMap(axis, (EJoyAxis)value); - return (void) Printf("%d\n", sticks[pad]->GetAxisMap(axis)); - } return usage(); } diff --git a/src/common/engine/m_joy.h b/src/common/engine/m_joy.h index 87dca60a3..2418bb4ed 100644 --- a/src/common/engine/m_joy.h +++ b/src/common/engine/m_joy.h @@ -5,6 +5,7 @@ #include "keydef.h" #include "tarray.h" #include "c_cvars.h" +#include "keydef.h" union CubicBezier { struct { @@ -26,18 +27,6 @@ enum EJoyCurve { NUM_JOYCURVE }; -enum EJoyAxis -{ - JOYAXIS_None = -1, - JOYAXIS_Yaw, - JOYAXIS_Pitch, - JOYAXIS_Forward, - JOYAXIS_Side, - JOYAXIS_Up, -// JOYAXIS_Roll, // Ha ha. No roll for you. - NUM_JOYAXIS, -}; - extern const float JOYDEADZONE_DEFAULT; extern const float JOYSENSITIVITY_DEFAULT; @@ -61,7 +50,6 @@ struct IJoystickConfig virtual int GetNumAxes() = 0; virtual float GetAxisDeadZone(int axis) = 0; - virtual EJoyAxis GetAxisMap(int axis) = 0; virtual const char *GetAxisName(int axis) = 0; virtual float GetAxisScale(int axis) = 0; virtual float GetAxisDigitalThreshold(int axis) = 0; @@ -69,7 +57,6 @@ struct IJoystickConfig virtual float GetAxisResponseCurvePoint(int axis, int point) = 0; virtual void SetAxisDeadZone(int axis, float zone) = 0; - virtual void SetAxisMap(int axis, EJoyAxis gameaxis) = 0; virtual void SetAxisScale(int axis, float scale) = 0; virtual void SetAxisDigitalThreshold(int axis, float threshold) = 0; virtual void SetAxisResponseCurve(int axis, EJoyCurve preset) = 0; @@ -85,7 +72,6 @@ struct IJoystickConfig // Used by the saver to not save properties that are at their defaults. virtual bool IsSensitivityDefault() = 0; virtual bool IsAxisDeadZoneDefault(int axis) = 0; - virtual bool IsAxisMapDefault(int axis) = 0; virtual bool IsAxisScaleDefault(int axis) = 0; virtual bool IsAxisDigitalThresholdDefault(int axis) = 0; virtual bool IsAxisResponseCurveDefault(int axis) = 0; @@ -107,7 +93,7 @@ double Joy_RemoveDeadZone(double axisval, double deadzone, uint8_t *buttons); double Joy_ApplyResponseCurveBezier(const CubicBezier &curve, double input); // These ought to be provided by a system-specific i_input.cpp. -void I_GetAxes(float axes[NUM_JOYAXIS]); +void I_GetAxes(float axes[NUM_AXIS_CODES]); void I_GetJoysticks(TArray &sticks); IJoystickConfig *I_UpdateDeviceList(); extern void UpdateJoystickMenu(IJoystickConfig *); diff --git a/src/common/menu/joystickmenu.cpp b/src/common/menu/joystickmenu.cpp index e3bb8544b..662a004ae 100644 --- a/src/common/menu/joystickmenu.cpp +++ b/src/common/menu/joystickmenu.cpp @@ -134,22 +134,6 @@ DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisResponseCurvePoint) return 0; } -DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisMap) -{ - PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); - PARAM_INT(axis); - ACTION_RETURN_INT(self->GetAxisMap(axis)); -} - -DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisMap) -{ - PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); - PARAM_INT(axis); - PARAM_INT(map); - self->SetAxisMap(axis, (EJoyAxis)map); - return 0; -} - DEFINE_ACTION_FUNCTION(IJoystickConfig, GetName) { PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig); diff --git a/src/common/platform/posix/cocoa/i_joystick.cpp b/src/common/platform/posix/cocoa/i_joystick.cpp index ffb9f90a0..0ddd7cb43 100644 --- a/src/common/platform/posix/cocoa/i_joystick.cpp +++ b/src/common/platform/posix/cocoa/i_joystick.cpp @@ -91,7 +91,6 @@ public: virtual int GetNumAxes(); virtual float GetAxisDeadZone(int axis); - virtual EJoyAxis GetAxisMap(int axis); virtual const char* GetAxisName(int axis); virtual float GetAxisScale(int axis); float GetAxisDigitalThreshold(int axis); @@ -99,7 +98,6 @@ public: float GetAxisResponseCurvePoint(int axis, int point); virtual void SetAxisDeadZone(int axis, float deadZone); - virtual void SetAxisMap(int axis, EJoyAxis gameAxis); virtual void SetAxisScale(int axis, float scale); void SetAxisDigitalThreshold(int axis, float threshold); void SetAxisResponseCurve(int axis, EJoyCurve preset); @@ -107,7 +105,6 @@ public: virtual bool IsSensitivityDefault(); virtual bool IsAxisDeadZoneDefault(int axis); - virtual bool IsAxisMapDefault(int axis); virtual bool IsAxisScaleDefault(int axis); bool IsAxisDigitalThresholdDefault(int axis); bool IsAxisResponseCurveDefault(int axis); @@ -122,7 +119,7 @@ public: virtual void SetDefaultConfig(); virtual FString GetIdentifier(); - void AddAxes(float axes[NUM_JOYAXIS]) const; + void AddAxes(float axes[NUM_AXIS_CODES]) const; void Update(); @@ -160,8 +157,7 @@ private: EJoyCurve defaultResponseCurvePreset; CubicBezier responseCurve; - EJoyAxis gameAxis; - EJoyAxis defaultGameAxis; + uint8_t buttonValue; AnalogAxis() { @@ -376,11 +372,6 @@ float IOKitJoystick::GetAxisDeadZone(int axis) return IS_AXIS_VALID ? m_axes[axis].deadZone : 0.0f; } -EJoyAxis IOKitJoystick::GetAxisMap(int axis) -{ - return IS_AXIS_VALID ? m_axes[axis].gameAxis : JOYAXIS_None; -} - const char* IOKitJoystick::GetAxisName(int axis) { return IS_AXIS_VALID ? m_axes[axis].name : "Invalid"; @@ -414,16 +405,6 @@ void IOKitJoystick::SetAxisDeadZone(int axis, float deadZone) } } -void IOKitJoystick::SetAxisMap(int axis, EJoyAxis gameAxis) -{ - if (IS_AXIS_VALID) - { - m_axes[axis].gameAxis = (gameAxis> JOYAXIS_None && gameAxis = 3) { - m_axes[0].gameAxis = JOYAXIS_Side; m_axes[0].digitalThreshold = JOYTHRESH_STICK_X; - - m_axes[1].gameAxis = JOYAXIS_Forward; m_axes[1].digitalThreshold = JOYTHRESH_STICK_Y; - - m_axes[2].gameAxis = JOYAXIS_Yaw; m_axes[2].digitalThreshold = JOYTHRESH_STICK_X; // Four axes? First two are movement, last two are looking around. if (axisCount >= 4) { - m_axes[3].gameAxis = JOYAXIS_Pitch; // ??? m_axes[3].sensitivity = 0.75f; m_axes[3].digitalThreshold = JOYTHRESH_STICK_Y; @@ -563,7 +527,6 @@ void IOKitJoystick::SetDefaultConfig() if (axisCount >= 5) { - m_axes[4].gameAxis = JOYAXIS_Up; m_axes[4].digitalThreshold = JOYTHRESH_STICK_Y; } } @@ -578,7 +541,6 @@ void IOKitJoystick::SetDefaultConfig() { m_axes[i].defaultDeadZone = m_axes[i].deadZone; m_axes[i].defaultSensitivity = m_axes[i].sensitivity; - m_axes[i].defaultGameAxis = m_axes[i].gameAxis; m_axes[i].defaultDigitalThreshold = m_axes[i].digitalThreshold; m_axes[i].defaultResponseCurvePreset = m_axes[i].responseCurvePreset; } @@ -591,18 +553,30 @@ FString IOKitJoystick::GetIdentifier() } -void IOKitJoystick::AddAxes(float axes[NUM_JOYAXIS]) const +void IOKitJoystick::AddAxes(float axes[NUM_AXIS_CODES]) const { for (size_t i = 0, count = m_axes.Size(); i < count; ++i) { - const EJoyAxis axis = m_axes[i].gameAxis; + // Add to the game axis. + float axis_value = m_axes[i].value; + int code = AXIS_CODE_NULL; - if (JOYAXIS_None == axis) + if (i < NUM_JOYAXISBUTTONS) { - continue; + if (axis_value > 0.0f) + { + code = AXIS_CODE_JOY1_PLUS + (i * 2); + } + else if (axis_value < 0.0f) + { + code = AXIS_CODE_JOY1_PLUS + (i * 2) + 1; + } } - axes[axis] -= m_axes[i].value; + if (code != AXIS_CODE_NULL) + { + axes[code] += fabs(axis_value); + } } } @@ -665,6 +639,7 @@ void IOKitJoystick::ProcessAxes() for (size_t i = 0, count = m_axes.Size(); i < count; ++i) { AnalogAxis& axis = m_axes[i]; + uint8_t buttonstate = 0; static const double scaledMin = -1; static const double scaledMax = 1; @@ -675,7 +650,7 @@ void IOKitJoystick::ProcessAxes() { const double scaledValue = scaledMin + (event.value - axis.minValue) * (scaledMax - scaledMin) / (axis.maxValue - axis.minValue); - const double filteredValue = Joy_RemoveDeadZone(scaledValue, axis.deadZone, NULL); + const double filteredValue = Joy_RemoveDeadZone(scaledValue, axis.deadZone, &buttonstate); const double smoothedValue = Joy_ApplyResponseCurveBezier(axis.responseCurve, filteredValue); axis.value = static_cast(smoothedValue * m_sensitivity * axis.sensitivity); @@ -684,6 +659,19 @@ void IOKitJoystick::ProcessAxes() { axis.value = 0.0f; } + + if (i < NUM_JOYAXISBUTTONS && (i > 2 || m_axes.Size() == 1)) + { + Joy_GenerateButtonEvents(axis.buttonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2); + } + else if (i == 1) + { + // Since we sorted the axes, we know that the first two are definitely X and Y. + // They are probably a single stick, so use angular position to determine buttons. + buttonstate = Joy_XYAxesToButtons(m_axes[0].value, axis.value); + Joy_GenerateButtonEvents(axis.buttonValue, buttonstate, 4, KEY_JOYAXIS1PLUS); + } + axis.buttonValue = buttonstate; } } @@ -703,17 +691,23 @@ bool IOKitJoystick::ProcessAxis(const IOHIDEventStruct& event) } AnalogAxis& axis = m_axes[i]; + uint8_t buttonstate = 0; static const double scaledMin = -1; static const double scaledMax = 1; const double scaledValue = scaledMin + (event.value - axis.minValue) * (scaledMax - scaledMin) / (axis.maxValue - axis.minValue); - const double filteredValue = Joy_RemoveDeadZone(scaledValue, axis.deadZone, NULL); + const double filteredValue = Joy_RemoveDeadZone(scaledValue, axis.deadZone, &buttonstate); const double smoothedValue = Joy_ApplyResponseCurveBezier(axis.responseCurve, filteredValue); axis.value = static_cast(smoothedValue * m_sensitivity * axis.sensitivity); + if (i < NUM_JOYAXISBUTTONS) + { + Joy_GenerateButtonEvents(axis.buttonValue, buttonstate, 2, KEY_JOYAXIS1PLUS + i*2); + } + axis.buttonValue = buttonstate; return true; } @@ -1042,7 +1036,7 @@ public: void GetJoysticks(TArray& joysticks) const; - void AddAxes(float axes[NUM_JOYAXIS]) const; + void AddAxes(float axes[NUM_AXIS_CODES]) const; // Updates axes/buttons states void Update(); @@ -1133,7 +1127,7 @@ void IOKitJoystickManager::GetJoysticks(TArray& joysticks) con } } -void IOKitJoystickManager::AddAxes(float axes[NUM_JOYAXIS]) const +void IOKitJoystickManager::AddAxes(float axes[NUM_AXIS_CODES]) const { for (size_t i = 0, count = m_joysticks.Size(); i < count; ++i) { @@ -1296,9 +1290,9 @@ void I_GetJoysticks(TArray& sticks) } } -void I_GetAxes(float axes[NUM_JOYAXIS]) +void I_GetAxes(float axes[NUM_AXIS_CODES]) { - for (size_t i = 0; i < NUM_JOYAXIS; ++i) + for (size_t i = 0; i < NUM_AXIS_CODES; ++i) { axes[i] = 0.0f; } diff --git a/src/common/platform/posix/sdl/i_joystick.cpp b/src/common/platform/posix/sdl/i_joystick.cpp index d37b4f3a6..2c4677c00 100644 --- a/src/common/platform/posix/sdl/i_joystick.cpp +++ b/src/common/platform/posix/sdl/i_joystick.cpp @@ -124,10 +124,6 @@ public: { return Axes[axis].DeadZone; } - EJoyAxis GetAxisMap(int axis) - { - return Axes[axis].GameAxis; - } const char *GetAxisName(int axis) { return Axes[axis].Name.GetChars(); @@ -156,11 +152,6 @@ public: SettingsChanged = true; Axes[axis].DeadZone = clamp(zone, 0.f, 1.f); } - void SetAxisMap(int axis, EJoyAxis gameaxis) - { - SettingsChanged = true; - Axes[axis].GameAxis = gameaxis; - } void SetAxisScale(int axis, float scale) { SettingsChanged = true; @@ -200,12 +191,6 @@ public: return Axes[axis].DeadZone == JOYDEADZONE_DEFAULT; return Axes[axis].DeadZone == DefaultAxes[axis].DeadZone; } - bool IsAxisMapDefault(int axis) - { - if(axis >= DefaultAxesCount) - return Axes[axis].GameAxis == JOYAXIS_None; - return Axes[axis].GameAxis == DefaultAxes[axis].GameAxis; - } bool IsAxisScaleDefault(int axis) { if(axis >= DefaultAxesCount) @@ -259,7 +244,6 @@ public: if (i < DefaultAxesCount) { - Axes[i].GameAxis = DefaultAxes[i].GameAxis; Axes[i].DeadZone = DefaultAxes[i].DeadZone; Axes[i].Multiplier = DefaultAxes[i].Multiplier; Axes[i].DigitalThreshold = DefaultAxes[i].DigitalThreshold; @@ -268,7 +252,6 @@ public: } else { - Axes[i].GameAxis = JOYAXIS_None; Axes[i].DeadZone = JOYDEADZONE_DEFAULT; Axes[i].Multiplier = JOYSENSITIVITY_DEFAULT; Axes[i].DigitalThreshold = JOYTHRESH_DEFAULT; @@ -300,17 +283,32 @@ public: return id; } - void AddAxes(float axes[NUM_JOYAXIS]) + void AddAxes(float axes[NUM_AXIS_CODES]) { // Add to game axes. for (int i = 0; i < GetNumAxes(); ++i) { - if(Axes[i].GameAxis != JOYAXIS_None) - axes[Axes[i].GameAxis] -= float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + float axis_value = float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + int code = AXIS_CODE_NULL; + + if (axis_value > 0.0f) + { + code = Axes[i].Codes[0]; + } + else if (axis_value < 0.0f) + { + code = Axes[i].Codes[1]; + } + + if (code != AXIS_CODE_NULL) + { + axes[code] += fabs(axis_value); + } } } - void ProcessInput() { + void ProcessInput() + { uint8_t buttonstate; if (Mapping) @@ -324,6 +322,16 @@ public: { buttonstate = 0; + if (i < NUM_JOYAXISBUTTONS) + { + Axes[i].Codes[0] = AXIS_CODE_JOY1_PLUS + (i * 2); + Axes[i].Codes[1] = AXIS_CODE_JOY1_PLUS + (i * 2) + 1; + } + else + { + Axes[i].Codes[0] = Axes[i].Codes[1] = AXIS_CODE_NULL; + } + Axes[i].Value = SDL_GameControllerGetAxis(Mapping, static_cast(i))/32767.0; Axes[i].Value = Joy_RemoveDeadZone(Axes[i].Value, Axes[i].DeadZone, &buttonstate); Axes[i].Value = Joy_ApplyResponseCurveBezier(Axes[i].ResponseCurve, Axes[i].Value); @@ -351,6 +359,16 @@ public: { buttonstate = 0; + if (i < NUM_JOYAXISBUTTONS) + { + Axes[i].Codes[0] = AXIS_CODE_JOY1_PLUS + (i * 2); + Axes[i].Codes[1] = AXIS_CODE_JOY1_PLUS + (i * 2) + 1; + } + else + { + Axes[i].Codes[0] = Axes[i].Codes[1] = AXIS_CODE_NULL; + } + Axes[i].Value = SDL_JoystickGetAxis(Device, i)/32767.0; Axes[i].Value = Joy_RemoveDeadZone(Axes[i].Value, Axes[i].DeadZone, &buttonstate); Axes[i].Value = Joy_ApplyResponseCurveBezier(Axes[i].ResponseCurve, Axes[i].Value); @@ -364,7 +382,7 @@ public: } } - if(NumAxes > 1) + if (NumAxes > 1) { buttonstate = Joy_XYAxesToButtons( abs(Axes[0].Value) < Axes[0].DigitalThreshold ? 0 : Axes[0].Value, @@ -400,7 +418,7 @@ public: else x.Value = 0.0; - if(i < 4) + if (i < 4) { Joy_GenerateButtonEvents(x.ButtonValue, buttonstate, 4, KEY_JOYPOV1_UP + i*4); x.ButtonValue = buttonstate; @@ -418,14 +436,13 @@ protected: float DigitalThreshold; EJoyCurve ResponseCurvePreset; CubicBezier ResponseCurve; - EJoyAxis GameAxis; + int Codes[2]; // 0: positive, 1: negative double Value; uint8_t ButtonValue; }; struct DefaultAxisConfig { float DeadZone; - EJoyAxis GameAxis; float Multiplier; float DigitalThreshold; EJoyCurve ResponseCurvePreset; @@ -452,21 +469,21 @@ protected: // [Nash 4 Feb 2024] seems like on Linux, the third axis is actually the Left Trigger, resulting in the player uncontrollably looking upwards. const SDLInputJoystick::DefaultAxisConfig SDLInputJoystick::DefaultJoystickAxes[5] = { - {JOYDEADZONE_DEFAULT, JOYAXIS_Side, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_Forward, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_None, JOYSENSITIVITY_DEFAULT, JOYTHRESH_DEFAULT, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_Yaw, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_Pitch, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT} + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_DEFAULT, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT} }; // Defaults if we have access to the GameController API for this device const SDLInputJoystick::DefaultAxisConfig SDLInputJoystick::DefaultControllerAxes[6] = { - {JOYDEADZONE_DEFAULT, JOYAXIS_Side, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_Forward, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_Yaw, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_Pitch, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_None, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT}, - {JOYDEADZONE_DEFAULT, JOYAXIS_None, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT}, + {JOYDEADZONE_DEFAULT, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT}, }; class SDLInputJoystickManager @@ -490,7 +507,7 @@ public: } } - void AddAxes(float axes[NUM_JOYAXIS]) + void AddAxes(float axes[NUM_AXIS_CODES]) { for(unsigned int i = 0;i < Joysticks.Size();i++) Joysticks[i]->AddAxes(axes); @@ -553,12 +570,13 @@ void I_GetJoysticks(TArray &sticks) JoystickManager->GetDevices(sticks); } -void I_GetAxes(float axes[NUM_JOYAXIS]) +void I_GetAxes(float axes[NUM_AXIS_CODES]) { - for (int i = 0; i < NUM_JOYAXIS; ++i) + for (int i = 0; i < NUM_AXIS_CODES; ++i) { - axes[i] = 0; + axes[i] = 0.0f; } + if (use_joystick && JoystickManager) { JoystickManager->AddAxes(axes); diff --git a/src/common/platform/win32/i_dijoy.cpp b/src/common/platform/win32/i_dijoy.cpp index 2340bfc84..af9082a4f 100644 --- a/src/common/platform/win32/i_dijoy.cpp +++ b/src/common/platform/win32/i_dijoy.cpp @@ -157,7 +157,7 @@ public: bool GetDevice(); void ProcessInput(); - void AddAxes(float axes[NUM_JOYAXIS]); + void AddAxes(float axes[NUM_AXIS_CODES]); // IJoystickConfig interface FString GetName(); @@ -166,7 +166,6 @@ public: int GetNumAxes(); float GetAxisDeadZone(int axis); - EJoyAxis GetAxisMap(int axis); const char *GetAxisName(int axis); float GetAxisScale(int axis); float GetAxisDigitalThreshold(int axis); @@ -174,7 +173,6 @@ public: float GetAxisResponseCurvePoint(int axis, int point); void SetAxisDeadZone(int axis, float deadzone); - void SetAxisMap(int axis, EJoyAxis gameaxis); void SetAxisScale(int axis, float scale); void SetAxisDigitalThreshold(int axis, float threshold); void SetAxisResponseCurve(int axis, EJoyCurve preset); @@ -182,7 +180,6 @@ public: bool IsSensitivityDefault(); bool IsAxisDeadZoneDefault(int axis); - bool IsAxisMapDefault(int axis); bool IsAxisScaleDefault(int axis); bool IsAxisDigitalThresholdDefault(int axis); bool IsAxisResponseCurveDefault(int axis); @@ -211,7 +208,6 @@ protected: float DigitalThreshold, DefaultDigitalThreshold; EJoyCurve ResponseCurvePreset, DefaultResponseCurvePreset; CubicBezier ResponseCurve; - EJoyAxis GameAxis, DefaultGameAxis; uint8_t ButtonValue; }; struct ButtonInfo @@ -254,7 +250,7 @@ public: bool GetDevice(); void ProcessInput(); - void AddAxes(float axes[NUM_JOYAXIS]); + void AddAxes(float axes[NUM_AXIS_CODES]); void GetDevices(TArray &sticks); IJoystickConfig *Rescan(); @@ -527,12 +523,30 @@ void FDInputJoystick::ProcessInput() // //=========================================================================== -void FDInputJoystick::AddAxes(float axes[NUM_JOYAXIS]) +void FDInputJoystick::AddAxes(float axes[NUM_AXIS_CODES]) { for (unsigned i = 0; i < Axes.Size(); ++i) { // Add to the game axis. - axes[Axes[i].GameAxis] -= float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + float axis_value = float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + int code = AXIS_CODE_NULL; + + if (i < NUM_JOYAXISBUTTONS) + { + if (axis_value > 0.0f) + { + code = AXIS_CODE_JOY1_PLUS + (i * 2); + } + else if (axis_value < 0.0f) + { + code = AXIS_CODE_JOY1_PLUS + (i * 2) + 1; + } + } + + if (code != AXIS_CODE_NULL) + { + axes[code] += fabs(axis_value); + } } } @@ -608,7 +622,6 @@ BOOL CALLBACK FDInputJoystick::EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpd info.Ofs = 0; info.Min = diprg.lMin; info.Max = diprg.lMax; - info.GameAxis = JOYAXIS_None; info.Value = 0; info.ButtonValue = 0; joy->Axes.Push(info); @@ -781,7 +794,6 @@ void FDInputJoystick::SetDefaultConfig() { Axes[i].DeadZone = JOYDEADZONE_DEFAULT; Axes[i].Multiplier = JOYSENSITIVITY_DEFAULT; - Axes[i].GameAxis = JOYAXIS_None; Axes[i].DigitalThreshold = JOYTHRESH_DEFAULT; Axes[i].ResponseCurvePreset = JOYCURVE_DEFAULT; Axes[i].ResponseCurve = JOYCURVE[JOYCURVE_DEFAULT]; @@ -795,34 +807,24 @@ void FDInputJoystick::SetDefaultConfig() // Two axes? Horizontal is yaw and vertical is forward. if (Axes.Size() == 2) { - Axes[0].GameAxis = JOYAXIS_Yaw; Axes[0].DigitalThreshold = JOYTHRESH_STICK_X; - - Axes[1].GameAxis = JOYAXIS_Forward; Axes[1].DigitalThreshold = JOYTHRESH_STICK_Y; } // Three axes? First two are movement, third is yaw. else if (Axes.Size() >= 3) { - Axes[0].GameAxis = JOYAXIS_Side; Axes[0].DigitalThreshold = JOYTHRESH_STICK_X; - - Axes[1].GameAxis = JOYAXIS_Forward; Axes[1].DigitalThreshold = JOYTHRESH_STICK_Y; - - Axes[2].GameAxis = JOYAXIS_Yaw; Axes[2].DigitalThreshold = JOYTHRESH_STICK_X; // Four axes? First two are movement, last two are looking around. if (Axes.Size() >= 4) { - Axes[3].GameAxis = JOYAXIS_Pitch; // Axes[3].Multiplier = 0.75f; Axes[3].DigitalThreshold = JOYTHRESH_STICK_Y; // Five axes? Use the fifth one for moving up and down. if (Axes.Size() >= 5) { - Axes[4].GameAxis = JOYAXIS_Up; Axes[4].DigitalThreshold = JOYTHRESH_STICK_Y; } } @@ -835,7 +837,6 @@ void FDInputJoystick::SetDefaultConfig() { Axes[i].DefaultDeadZone = Axes[i].DeadZone; Axes[i].DefaultMultiplier = Axes[i].Multiplier; - Axes[i].DefaultGameAxis = Axes[i].GameAxis; Axes[i].DefaultDigitalThreshold = Axes[i].DigitalThreshold; Axes[i].DefaultResponseCurvePreset = Axes[i].ResponseCurvePreset; } @@ -911,21 +912,6 @@ float FDInputJoystick::GetAxisDeadZone(int axis) return Axes[axis].DeadZone; } -//=========================================================================== -// -// FDInputJoystick :: GetAxisMap -// -//=========================================================================== - -EJoyAxis FDInputJoystick::GetAxisMap(int axis) -{ - if (unsigned(axis) >= Axes.Size()) - { - return JOYAXIS_None; - } - return Axes[axis].GameAxis; -} - //=========================================================================== // // FDInputJoystick :: GetAxisName @@ -1015,20 +1001,6 @@ void FDInputJoystick::SetAxisDeadZone(int axis, float deadzone) } } -//=========================================================================== -// -// FDInputJoystick :: SetAxisMap -// -//=========================================================================== - -void FDInputJoystick::SetAxisMap(int axis, EJoyAxis gameaxis) -{ - if (unsigned(axis) < Axes.Size()) - { - Axes[axis].GameAxis = (unsigned(gameaxis) < NUM_JOYAXIS) ? gameaxis : JOYAXIS_None; - } -} - //=========================================================================== // // FDInputJoystick :: SetAxisScale @@ -1171,21 +1143,6 @@ void FDInputJoystick::SetEnabled(bool enabled) Enabled = enabled; } -//=========================================================================== -// -// FDInputJoystick :: IsAxisMapDefault -// -//=========================================================================== - -bool FDInputJoystick::IsAxisMapDefault(int axis) -{ - if (unsigned(axis) < Axes.Size()) - { - return Axes[axis].GameAxis == Axes[axis].DefaultGameAxis; - } - return true; -} - //=========================================================================== // // FDInputJoystickManager - Constructor @@ -1253,7 +1210,7 @@ void FDInputJoystickManager::ProcessInput() // //=========================================================================== -void FDInputJoystickManager :: AddAxes(float axes[NUM_JOYAXIS]) +void FDInputJoystickManager :: AddAxes(float axes[NUM_AXIS_CODES]) { for (unsigned i = 0; i < Devices.Size(); ++i) { diff --git a/src/common/platform/win32/i_input.cpp b/src/common/platform/win32/i_input.cpp index 2a4ea0ddd..6569ae8d3 100644 --- a/src/common/platform/win32/i_input.cpp +++ b/src/common/platform/win32/i_input.cpp @@ -636,14 +636,15 @@ void I_StartFrame () } } -void I_GetAxes(float axes[NUM_JOYAXIS]) +void I_GetAxes(float axes[NUM_AXIS_CODES]) { int i; - for (i = 0; i < NUM_JOYAXIS; ++i) + for (i = 0; i < NUM_AXIS_CODES; ++i) { - axes[i] = 0; + axes[i] = 0.0f; } + if (use_joystick) { for (i = 0; i < NUM_JOYDEVICES; ++i) diff --git a/src/common/platform/win32/i_input.h b/src/common/platform/win32/i_input.h index 553a1cd21..21ce81a45 100644 --- a/src/common/platform/win32/i_input.h +++ b/src/common/platform/win32/i_input.h @@ -120,7 +120,7 @@ protected: class FJoystickCollection : public FInputDevice { public: - virtual void AddAxes(float axes[NUM_JOYAXIS]) = 0; + virtual void AddAxes(float axes[NUM_AXIS_CODES]) = 0; virtual void GetDevices(TArray &sticks) = 0; virtual IJoystickConfig *Rescan() = 0; }; diff --git a/src/common/platform/win32/i_rawps2.cpp b/src/common/platform/win32/i_rawps2.cpp index 09bb314b0..bf758a940 100644 --- a/src/common/platform/win32/i_rawps2.cpp +++ b/src/common/platform/win32/i_rawps2.cpp @@ -90,7 +90,7 @@ public: ~FRawPS2Controller(); bool ProcessInput(RAWHID *raw, int code); - void AddAxes(float axes[NUM_JOYAXIS]); + void AddAxes(float axes[NUM_AXIS_CODES]); bool IsConnected() { return Connected; } // IJoystickConfig interface @@ -100,7 +100,6 @@ public: int GetNumAxes(); float GetAxisDeadZone(int axis); - EJoyAxis GetAxisMap(int axis); const char *GetAxisName(int axis); float GetAxisScale(int axis); float GetAxisDigitalThreshold(int axis); @@ -108,7 +107,6 @@ public: float GetAxisResponseCurvePoint(int axis, int point); void SetAxisDeadZone(int axis, float deadzone); - void SetAxisMap(int axis, EJoyAxis gameaxis); void SetAxisScale(int axis, float scale); void SetAxisDigitalThreshold(int axis, float threshold); void SetAxisResponseCurve(int axis, EJoyCurve preset); @@ -116,7 +114,6 @@ public: bool IsSensitivityDefault(); bool IsAxisDeadZoneDefault(int axis); - bool IsAxisMapDefault(int axis); bool IsAxisScaleDefault(int axis); bool IsAxisDigitalThresholdDefault(int axis); bool IsAxisResponseCurveDefault(int axis); @@ -140,12 +137,10 @@ protected: float DigitalThreshold; EJoyCurve ResponseCurvePreset; CubicBezier ResponseCurve; - EJoyAxis GameAxis; uint8_t ButtonValue; }; struct DefaultAxisConfig { - EJoyAxis GameAxis; float Multiplier; float DigitalThreshold; EJoyCurve ResponseCurvePreset; @@ -191,7 +186,7 @@ public: bool GetDevice(); bool ProcessRawInput(RAWINPUT *raw, int code); - void AddAxes(float axes[NUM_JOYAXIS]); + void AddAxes(float axes[NUM_AXIS_CODES]); void GetDevices(TArray &sticks); IJoystickConfig *Rescan(); @@ -367,13 +362,21 @@ static const char *AxisNames[] = "Right Thumb Y Axis", }; +static const EAxisCodes AxisCodes[][2] = +{ + { AXIS_CODE_PAD_LTHUMB_RIGHT, AXIS_CODE_PAD_LTHUMB_LEFT }, + { AXIS_CODE_PAD_LTHUMB_DOWN, AXIS_CODE_PAD_LTHUMB_UP }, + { AXIS_CODE_PAD_RTHUMB_RIGHT, AXIS_CODE_PAD_RTHUMB_LEFT }, + { AXIS_CODE_PAD_RTHUMB_DOWN, AXIS_CODE_PAD_RTHUMB_UP } +}; + FRawPS2Controller::DefaultAxisConfig FRawPS2Controller::DefaultAxes[NUM_AXES] = { - // Game axis, multiplier, digital threshold, response curve A, response curve B - { JOYAXIS_Side, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbLX - { JOYAXIS_Forward, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbLY - { JOYAXIS_Yaw, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbRX - { JOYAXIS_Pitch, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbRY + // multiplier, digital threshold, response curve A, response curve B + { JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbLX + { JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbLY + { JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbRX + { JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbRY }; // CODE -------------------------------------------------------------------- @@ -644,12 +647,27 @@ void FRawPS2Controller::NeutralInput() // //========================================================================== -void FRawPS2Controller::AddAxes(float axes[NUM_JOYAXIS]) +void FRawPS2Controller::AddAxes(float axes[NUM_AXIS_CODES]) { - // Add to game axes. for (int i = 0; i < NUM_AXES; ++i) { - axes[Axes[i].GameAxis] -= float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + // Add to the game axis. + float axis_value = float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + int code = AXIS_CODE_NULL; + + if (axis_value > 0.0f) + { + code = AxisCodes[i][0]; + } + else if (axis_value < 0.0f) + { + code = AxisCodes[i][1]; + } + + if (code != AXIS_CODE_NULL) + { + axes[code] += fabs(axis_value); + } } } @@ -665,7 +683,6 @@ void FRawPS2Controller::SetDefaultConfig() for (int i = 0; i < NUM_AXES; ++i) { Axes[i].DeadZone = JOYDEADZONE_DEFAULT; - Axes[i].GameAxis = DefaultAxes[i].GameAxis; Axes[i].Multiplier = DefaultAxes[i].Multiplier; } } @@ -758,21 +775,6 @@ float FRawPS2Controller::GetAxisDeadZone(int axis) return 0; } -//========================================================================== -// -// FRawPS2Controller :: GetAxisMap -// -//========================================================================== - -EJoyAxis FRawPS2Controller::GetAxisMap(int axis) -{ - if (unsigned(axis) < NUM_AXES) - { - return Axes[axis].GameAxis; - } - return JOYAXIS_None; -} - //========================================================================== // // FRawPS2Controller :: GetAxisName @@ -862,20 +864,6 @@ void FRawPS2Controller::SetAxisDeadZone(int axis, float deadzone) } } -//========================================================================== -// -// FRawPS2Controller :: SetAxisMap -// -//========================================================================== - -void FRawPS2Controller::SetAxisMap(int axis, EJoyAxis gameaxis) -{ - if (unsigned(axis) < NUM_AXES) - { - Axes[axis].GameAxis = (unsigned(gameaxis) < NUM_JOYAXIS) ? gameaxis : JOYAXIS_None; - } -} - //========================================================================== // // FRawPS2Controller :: SetAxisScale @@ -1018,21 +1006,6 @@ void FRawPS2Controller::SetEnabled(bool enabled) Enabled = enabled; } -//=========================================================================== -// -// FRawPS2Controller :: IsAxisMapDefault -// -//=========================================================================== - -bool FRawPS2Controller::IsAxisMapDefault(int axis) -{ - if (unsigned(axis) < NUM_AXES) - { - return Axes[axis].GameAxis == DefaultAxes[axis].GameAxis; - } - return true; -} - //========================================================================== // // FRawPS2Manager - Constructor @@ -1094,7 +1067,7 @@ bool FRawPS2Manager::GetDevice() // //=========================================================================== -void FRawPS2Manager::AddAxes(float axes[NUM_JOYAXIS]) +void FRawPS2Manager::AddAxes(float axes[NUM_AXIS_CODES]) { for (unsigned i = 0; i < Devices.Size(); ++i) { diff --git a/src/common/platform/win32/i_xinput.cpp b/src/common/platform/win32/i_xinput.cpp index 890888a4b..12049b4a0 100644 --- a/src/common/platform/win32/i_xinput.cpp +++ b/src/common/platform/win32/i_xinput.cpp @@ -81,7 +81,7 @@ public: ~FXInputController(); void ProcessInput(); - void AddAxes(float axes[NUM_JOYAXIS]); + void AddAxes(float axes[NUM_AXIS_CODES]); bool IsConnected() { return Connected; } // IJoystickConfig interface @@ -91,7 +91,6 @@ public: int GetNumAxes(); float GetAxisDeadZone(int axis); - EJoyAxis GetAxisMap(int axis); const char *GetAxisName(int axis); float GetAxisScale(int axis); float GetAxisDigitalThreshold(int axis); @@ -99,7 +98,6 @@ public: float GetAxisResponseCurvePoint(int axis, int point); void SetAxisDeadZone(int axis, float deadzone); - void SetAxisMap(int axis, EJoyAxis gameaxis); void SetAxisScale(int axis, float scale); void SetAxisDigitalThreshold(int axis, float threshold); void SetAxisResponseCurve(int axis, EJoyCurve preset); @@ -107,7 +105,6 @@ public: bool IsSensitivityDefault(); bool IsAxisDeadZoneDefault(int axis); - bool IsAxisMapDefault(int axis); bool IsAxisScaleDefault(int axis); bool IsAxisDigitalThresholdDefault(int axis); bool IsAxisResponseCurveDefault(int axis); @@ -128,7 +125,6 @@ protected: float Value; float DeadZone; float Multiplier; - EJoyAxis GameAxis; uint8_t ButtonValue; float DigitalThreshold; EJoyCurve ResponseCurvePreset; @@ -137,7 +133,6 @@ protected: struct DefaultAxisConfig { float DeadZone; - EJoyAxis GameAxis; float Multiplier; float DigitalThreshold; EJoyCurve ResponseCurvePreset; @@ -179,7 +174,7 @@ public: bool GetDevice(); void ProcessInput(); bool WndProcHook(HWND hWnd, uint32_t message, WPARAM wParam, LPARAM lParam, LRESULT *result); - void AddAxes(float axes[NUM_JOYAXIS]); + void AddAxes(float axes[NUM_AXIS_CODES]); void GetDevices(TArray &sticks); IJoystickConfig *Rescan(); @@ -222,15 +217,25 @@ static const char *AxisNames[] = "Right Trigger" }; +static const EAxisCodes AxisCodes[][2] = +{ + { AXIS_CODE_PAD_LTHUMB_RIGHT, AXIS_CODE_PAD_LTHUMB_LEFT }, + { AXIS_CODE_PAD_LTHUMB_DOWN, AXIS_CODE_PAD_LTHUMB_UP }, + { AXIS_CODE_PAD_RTHUMB_RIGHT, AXIS_CODE_PAD_RTHUMB_LEFT }, + { AXIS_CODE_PAD_RTHUMB_DOWN, AXIS_CODE_PAD_RTHUMB_UP }, + { AXIS_CODE_PAD_LTRIGGER, AXIS_CODE_NULL }, + { AXIS_CODE_PAD_RTRIGGER, AXIS_CODE_NULL } +}; + FXInputController::DefaultAxisConfig FXInputController::DefaultAxes[NUM_AXES] = { - // Dead zone, game axis, multiplier, digitalthreshold, curveA, curveB - { XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE / 32768.f, JOYAXIS_Side, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbLX - { XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE / 32768.f, JOYAXIS_Forward, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbLY - { XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE / 32768.f, JOYAXIS_Yaw, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbRX - { XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE / 32768.f, JOYAXIS_Pitch, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbRY - { XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 256.f, JOYAXIS_None, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT }, // LeftTrigger - { XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 256.f, JOYAXIS_None, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT } // RightTrigger + // Dead zone, multiplier, digitalthreshold, curveA, curveB + { XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE / 32768.f, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbLX + { XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE / 32768.f, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbLY + { XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE / 32768.f, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_X, JOYCURVE_DEFAULT }, // ThumbRX + { XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE / 32768.f, JOYSENSITIVITY_DEFAULT, JOYTHRESH_STICK_Y, JOYCURVE_DEFAULT }, // ThumbRY + { XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 256.f, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT }, // LeftTrigger + { XINPUT_GAMEPAD_TRIGGER_THRESHOLD / 256.f, JOYSENSITIVITY_DEFAULT, JOYTHRESH_TRIGGER, JOYCURVE_DEFAULT } // RightTrigger }; // CODE -------------------------------------------------------------------- @@ -437,12 +442,27 @@ void FXInputController::Detached() // //========================================================================== -void FXInputController::AddAxes(float axes[NUM_JOYAXIS]) +void FXInputController::AddAxes(float axes[NUM_AXIS_CODES]) { - // Add to game axes. for (int i = 0; i < NUM_AXES; ++i) { - axes[Axes[i].GameAxis] -= float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + // Add to the game axis. + float axis_value = float(Axes[i].Value * Multiplier * Axes[i].Multiplier); + int code = AXIS_CODE_NULL; + + if (axis_value > 0.0f) + { + code = AxisCodes[i][0]; + } + else if (axis_value < 0.0f) + { + code = AxisCodes[i][1]; + } + + if (code != AXIS_CODE_NULL) + { + axes[code] += fabs(axis_value); + } } } @@ -458,7 +478,6 @@ void FXInputController::SetDefaultConfig() for (int i = 0; i < NUM_AXES; ++i) { Axes[i].DeadZone = DefaultAxes[i].DeadZone; - Axes[i].GameAxis = DefaultAxes[i].GameAxis; Axes[i].Multiplier = DefaultAxes[i].Multiplier; Axes[i].DigitalThreshold = DefaultAxes[i].DigitalThreshold; Axes[i].ResponseCurve = JOYCURVE[DefaultAxes[i].ResponseCurvePreset]; @@ -549,21 +568,6 @@ float FXInputController::GetAxisDeadZone(int axis) return 0; } -//========================================================================== -// -// FXInputController :: GetAxisMap -// -//========================================================================== - -EJoyAxis FXInputController::GetAxisMap(int axis) -{ - if (unsigned(axis) < NUM_AXES) - { - return Axes[axis].GameAxis; - } - return JOYAXIS_None; -} - //========================================================================== // // FXInputController :: GetAxisName @@ -653,20 +657,6 @@ void FXInputController::SetAxisDeadZone(int axis, float deadzone) } } -//========================================================================== -// -// FXInputController :: SetAxisMap -// -//========================================================================== - -void FXInputController::SetAxisMap(int axis, EJoyAxis gameaxis) -{ - if (unsigned(axis) < NUM_AXES) - { - Axes[axis].GameAxis = (unsigned(gameaxis) < NUM_JOYAXIS) ? gameaxis : JOYAXIS_None; - } -} - //========================================================================== // // FXInputController :: SetAxisScale @@ -809,21 +799,6 @@ void FXInputController::SetEnabled(bool enabled) Enabled = enabled; } -//=========================================================================== -// -// FXInputController :: IsAxisMapDefault -// -//=========================================================================== - -bool FXInputController::IsAxisMapDefault(int axis) -{ - if (unsigned(axis) < NUM_AXES) - { - return Axes[axis].GameAxis == DefaultAxes[axis].GameAxis; - } - return true; -} - //========================================================================== // // FXInputManager - Constructor @@ -913,7 +888,7 @@ void FXInputManager::ProcessInput() // //=========================================================================== -void FXInputManager::AddAxes(float axes[NUM_JOYAXIS]) +void FXInputManager::AddAxes(float axes[NUM_AXIS_CODES]) { for (int i = 0; i < XUSER_MAX_COUNT; ++i) { diff --git a/src/g_game.cpp b/src/g_game.cpp index 2cc8e58d2..c8dad9b10 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -611,6 +611,9 @@ void G_BuildTiccmd (usercmd_t *cmd) base = G_BaseTiccmd (); *cmd = *base; + // Update axis polling for the button map + buttonMap.GetAxes(); + strafe = buttonMap.ButtonDown(Button_Strafe); speed = buttonMap.ButtonDown(Button_Speed) ^ (int)cl_run; @@ -619,7 +622,7 @@ void G_BuildTiccmd (usercmd_t *cmd) // [RH] only use two stage accelerative turning on the keyboard // and not the joystick, since we treat the joystick as // the analog device it is. - if (buttonMap.ButtonDown(Button_Left) || buttonMap.ButtonDown(Button_Right)) + if (buttonMap.ButtonDownDigital(Button_Left) || buttonMap.ButtonDownDigital(Button_Right)) turnheld += TicDup; else turnheld = 0; @@ -627,9 +630,9 @@ void G_BuildTiccmd (usercmd_t *cmd) // let movement keys cancel each other out if (strafe) { - if (buttonMap.ButtonDown(Button_Right)) + if (buttonMap.ButtonDownDigital(Button_Right)) side += sidemove[speed]; - if (buttonMap.ButtonDown(Button_Left)) + if (buttonMap.ButtonDownDigital(Button_Left)) side -= sidemove[speed]; } else @@ -639,48 +642,48 @@ void G_BuildTiccmd (usercmd_t *cmd) if (turnheld < SLOWTURNTICS) tspeed += 2; // slow turn - if (buttonMap.ButtonDown(Button_Right)) + if (buttonMap.ButtonDownDigital(Button_Right)) { G_AddViewAngle (*angleturn[tspeed]); } - if (buttonMap.ButtonDown(Button_Left)) + if (buttonMap.ButtonDownDigital(Button_Left)) { G_AddViewAngle (-*angleturn[tspeed]); } } - if (buttonMap.ButtonDown(Button_LookUp)) + if (buttonMap.ButtonDownDigital(Button_LookUp)) { G_AddViewPitch (lookspeed[speed]); } - if (buttonMap.ButtonDown(Button_LookDown)) + if (buttonMap.ButtonDownDigital(Button_LookDown)) { G_AddViewPitch (-lookspeed[speed]); } - if (buttonMap.ButtonDown(Button_MoveUp)) + if (buttonMap.ButtonDownDigital(Button_MoveUp)) fly += flyspeed[speed]; - if (buttonMap.ButtonDown(Button_MoveDown)) + if (buttonMap.ButtonDownDigital(Button_MoveDown)) fly -= flyspeed[speed]; if (buttonMap.ButtonDown(Button_Klook)) { - if (buttonMap.ButtonDown(Button_Forward)) + if (buttonMap.ButtonDownDigital(Button_Forward)) G_AddViewPitch (lookspeed[speed]); - if (buttonMap.ButtonDown(Button_Back)) + if (buttonMap.ButtonDownDigital(Button_Back)) G_AddViewPitch (-lookspeed[speed]); } else { - if (buttonMap.ButtonDown(Button_Forward)) + if (buttonMap.ButtonDownDigital(Button_Forward)) forward += forwardmove[speed]; - if (buttonMap.ButtonDown(Button_Back)) + if (buttonMap.ButtonDownDigital(Button_Back)) forward -= forwardmove[speed]; } - if (buttonMap.ButtonDown(Button_MoveRight)) + if (buttonMap.ButtonDownDigital(Button_MoveRight)) side += sidemove[speed]; - if (buttonMap.ButtonDown(Button_MoveLeft)) + if (buttonMap.ButtonDownDigital(Button_MoveLeft)) side -= sidemove[speed]; // buttons @@ -712,35 +715,37 @@ void G_BuildTiccmd (usercmd_t *cmd) if (buttonMap.ButtonDown(Button_ShowScores)) cmd->buttons |= BT_SHOWSCORES; if (speed) cmd->buttons |= BT_RUN; - // Handle joysticks/game controllers. - float joyaxes[NUM_JOYAXIS]; - - I_GetAxes(joyaxes); - // Remap some axes depending on button state. + float axis_yaw = buttonMap.ButtonAnalog(Button_Left) - buttonMap.ButtonAnalog(Button_Right); + float axis_pitch = buttonMap.ButtonAnalog(Button_LookUp) - buttonMap.ButtonAnalog(Button_LookDown); + float axis_forward = buttonMap.ButtonAnalog(Button_Forward) - buttonMap.ButtonAnalog(Button_Back); + float axis_side = buttonMap.ButtonAnalog(Button_MoveLeft) - buttonMap.ButtonAnalog(Button_MoveRight); + float axis_up = buttonMap.ButtonAnalog(Button_MoveUp) - buttonMap.ButtonAnalog(Button_MoveDown); + if (buttonMap.ButtonDown(Button_Strafe) || (buttonMap.ButtonDown(Button_Mlook) && lookstrafe)) { - joyaxes[JOYAXIS_Side] = joyaxes[JOYAXIS_Yaw]; - joyaxes[JOYAXIS_Yaw] = 0; + axis_side = axis_yaw; + axis_yaw = 0.0f; } + if (buttonMap.ButtonDown(Button_Mlook)) { - joyaxes[JOYAXIS_Pitch] = joyaxes[JOYAXIS_Forward]; - joyaxes[JOYAXIS_Forward] = 0; + axis_pitch = axis_forward; + axis_forward = 0.0f; } - if (joyaxes[JOYAXIS_Pitch] != 0) + if (axis_pitch != 0) { - G_AddViewPitch(joyint(joyaxes[JOYAXIS_Pitch] * 2048)); + G_AddViewPitch(joyint(axis_pitch * 2048)); } - if (joyaxes[JOYAXIS_Yaw] != 0) + if (axis_yaw != 0) { - G_AddViewAngle(joyint(-1280 * joyaxes[JOYAXIS_Yaw])); + G_AddViewAngle(joyint(-1280 * axis_yaw)); } - side -= joyint(sidemove[speed] * joyaxes[JOYAXIS_Side]); - forward += joyint(joyaxes[JOYAXIS_Forward] * forwardmove[speed]); - fly += joyint(joyaxes[JOYAXIS_Up] * 2048); + side -= joyint(sidemove[speed] * axis_side); + forward += joyint(axis_forward * forwardmove[speed]); + fly += joyint(axis_up * 2048); // Handle mice. if (!buttonMap.ButtonDown(Button_Mlook) && !freelook) diff --git a/wadsrc/static/engine/commonbinds.txt b/wadsrc/static/engine/commonbinds.txt index 8493529f2..d1c62ec5f 100644 --- a/wadsrc/static/engine/commonbinds.txt +++ b/wadsrc/static/engine/commonbinds.txt @@ -64,6 +64,14 @@ dpadup togglemap pad_start menu_main pad_back pause lthumb crouch +lstickleft +moveleft +lstickright +moveright +lstickup +forward +lstickdown +back +rstickleft +left +rstickright +right +rstickup +lookup +rstickdown +lookdown // Generic gamepad bindings joy1 +use @@ -79,6 +87,10 @@ pov1up togglemap joy8 menu_main joy7 pause joy10 crouch +axis1minus +moveleft +axis1plus +moveright +axis2minus +forward +axis2plus +back /* Default automap bindings */ mapbind f am_togglefollow diff --git a/wadsrc/static/zscript/engine/ui/menu/joystickmenu.zs b/wadsrc/static/zscript/engine/ui/menu/joystickmenu.zs index 425b7dd67..39f5e8e38 100644 --- a/wadsrc/static/zscript/engine/ui/menu/joystickmenu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/joystickmenu.zs @@ -267,6 +267,9 @@ class OptionMenuItemJoyCurve : OptionMenuItemOptionBase class OptionMenuItemJoyMap : OptionMenuItemOptionBase { + // For backwards compatibility with menu mods, we need to leave this class alone. + // It simply is always set to "None" and does nothing now. + int mAxis; JoystickConfig mJoy; @@ -465,7 +468,7 @@ class OptionMenuItemJoyConfigMenu : OptionMenuItemSubmenu it = new("OptionMenuItemStaticText").Init(" ", false); opt.mItems.Push(it); - it = new("OptionMenuItemJoyMap").Init(joy.GetAxisName(i), i, "JoyAxisMapNames", false, joy); + it = new("OptionMenuItemStaticText").Init(joy.GetAxisName(i), false); opt.mItems.Push(it); it = new("OptionMenuSliderJoyScale").Init("$JOYMNU_OVRSENS", i, 0, 4, 0.1, 3, joy); opt.mItems.Push(it); diff --git a/wadsrc/static/zscript/engine/ui/menu/menu.zs b/wadsrc/static/zscript/engine/ui/menu/menu.zs index cb8756f3b..1119c8962 100644 --- a/wadsrc/static/zscript/engine/ui/menu/menu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/menu.zs @@ -96,8 +96,15 @@ struct JoystickConfig native version("2.4") native float GetAxisResponseCurvePoint(int axis, int point); native void SetAxisResponseCurvePoint(int axis, int point, float value); - native int GetAxisMap(int axis); - native void SetAxisMap(int axis, int gameaxis); + deprecated("4.15.1", "Axis mapping was replaced with binds; remove this menu item") int GetAxisMap(int axis) + { + return JOYAXIS_None; + } + + deprecated("4.15.1", "Axis mapping was replaced with binds; remove this menu item") void SetAxisMap(int axis, int gameaxis) + { + // NOP + } native String GetName(); native int GetNumAxes();