From ca89b4d82d9ba76e99e832da962e2f0582802955 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 14:26:41 +0200 Subject: [PATCH 01/12] Report bidirectional axis and triggers separately --- ddio/sdlcontroller.cpp | 14 ++++++----- ddio/sdljoy.cpp | 54 +++++++++++++++++++----------------------- lib/joystick.h | 8 ++----- 3 files changed, 34 insertions(+), 42 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 35eadbb00..73719e343 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -908,12 +908,14 @@ bool sdlgameController::enum_controllers() { ((jc.axes_mask & JOYFLAG_VVALID) ? CTF_V_AXIS : 0) | ((jc.axes_mask & JOYFLAG_POVVALID) ? CTF_POV : 0) | ((jc.axes_mask & JOYFLAG_POV2VALID) ? CTF_POV2 : 0) | ((jc.axes_mask & JOYFLAG_POV3VALID) ? CTF_POV3 : 0) | ((jc.axes_mask & JOYFLAG_POV4VALID) ? CTF_POV4 : 0); - m_ControlList[num_devs].normalizer[0] = (jc.maxx - jc.minx) / 2.0f; - m_ControlList[num_devs].normalizer[1] = (jc.maxy - jc.miny) / 2.0f; - m_ControlList[num_devs].normalizer[2] = (jc.maxz - jc.minz) / 2.0f; - m_ControlList[num_devs].normalizer[3] = (jc.maxr - jc.minr) / 2.0f; - m_ControlList[num_devs].normalizer[4] = (jc.maxu - jc.minu) / 2.0f; - m_ControlList[num_devs].normalizer[5] = (jc.maxv - jc.minv) / 2.0f; + + int minV = -32768, maxV = 32768; + m_ControlList[num_devs].normalizer[0] = (maxV - minV) / 2.0f; + m_ControlList[num_devs].normalizer[1] = (maxV - minV) / 2.0f; + m_ControlList[num_devs].normalizer[2] = (maxV - minV) / 2.0f; + m_ControlList[num_devs].normalizer[3] = (maxV - minV) / 2.0f; + m_ControlList[num_devs].normalizer[4] = (maxV - minV) / 2.0f; + m_ControlList[num_devs].normalizer[5] = (maxV - minV) / 2.0f; for (i = 0; i < CT_NUM_AXES; i++) { m_ControlList[num_devs].sens[i] = 1.0f; diff --git a/ddio/sdljoy.cpp b/ddio/sdljoy.cpp index eb59a2c57..304d9c694 100644 --- a/ddio/sdljoy.cpp +++ b/ddio/sdljoy.cpp @@ -1,5 +1,5 @@ /* -* Descent 3 +* Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify @@ -67,7 +67,9 @@ */ #include +#include #include +#include #include // rcg06182000 need this for specific joystick stuff. @@ -150,36 +152,28 @@ static bool joy_InitStick(tJoystick joy, char *server_adr) { strncpy(caps.name, SDL_JoystickNameForIndex(joy), sizeof(caps.name) - 1); caps.num_btns = SDL_JoystickNumButtons(stick); int axes = SDL_JoystickNumAxes(stick); - switch (axes) { - default: - // Fall through to 6 axes - case 6: - caps.axes_mask |= JOYFLAG_VVALID; - caps.minv = -32767; - caps.maxv = 32768; - case 5: - caps.axes_mask |= JOYFLAG_UVALID; - caps.minu = -32767; - caps.maxu = 32768; - case 4: - caps.axes_mask |= JOYFLAG_RVALID; - caps.minr = -32767; - caps.maxr = 32768; - case 3: - caps.axes_mask |= JOYFLAG_ZVALID; - caps.minz = -32767; - caps.maxz = 32768; - case 2: - caps.axes_mask |= JOYFLAG_YVALID; - caps.miny = -32767; - caps.maxy = 32768; - case 1: - caps.axes_mask |= JOYFLAG_XVALID; - caps.minx = -32767; - caps.maxx = 32768; - case 0: - break; + + + + std::array axis_flags{JOYFLAG_XVALID, JOYFLAG_YVALID, JOYFLAG_ZVALID, + JOYFLAG_RVALID, JOYFLAG_UVALID, JOYFLAG_VVALID}; + for (int axis = 0; axis < SDL_JoystickNumAxes(stick); axis++) { + caps.axes_mask |= axis_flags[axis]; + + int16_t initialVal = 0; + SDL_JoystickGetAxisInitialState(stick, axis, &initialVal); + LOG_DEBUG << "Initial axis " << axis << " value is " << initialVal; + + if (initialVal < -32768 * 0.75) { + // Axis is an analog button/trigger, because it's initial value + // is at the start of the range and not in the middle + LOG_DEBUG << "Axis " << axis << " is an analog button"; + caps.trigger_axis_mask |= axis_flags[axis]; + } else { + LOG_DEBUG << "Axis " << axis << " is a bidirectional axis"; + } } + int hats = SDL_JoystickNumHats(stick); switch (hats) { default: diff --git a/lib/joystick.h b/lib/joystick.h index b0d07e46a..e2558af68 100644 --- a/lib/joystick.h +++ b/lib/joystick.h @@ -66,6 +66,7 @@ #define JOYSTICK_H #include +#include // joystick ids. used to initialize a stick and get its position #define MAX_JOYSTICKS 8 @@ -108,13 +109,8 @@ typedef int tJoystick; struct tJoyInfo { char name[128]; unsigned axes_mask; + unsigned trigger_axis_mask; unsigned num_btns; - int minx, maxx; - int miny, maxy; - int minz, maxz; - int minr, maxr; - int minu, maxu; - int minv, maxv; }; // shared between joystick remote server and local client. From 47be84b8e30f0d395dc1342cab4aa3f4bd951a91 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 15:43:54 +0200 Subject: [PATCH 02/12] Forward axis trigger information to sdlcontroller.cpp --- ddio/sdlcontroller.cpp | 9 +++++++++ ddio/sdlcontroller.h | 1 + 2 files changed, 10 insertions(+) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 73719e343..7f7a142d3 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -304,6 +304,7 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { } break; + case ctAnalogTrigger: case ctAxis: for (i = 2; i < m_NumControls; i++) { float pos; @@ -908,6 +909,14 @@ bool sdlgameController::enum_controllers() { ((jc.axes_mask & JOYFLAG_VVALID) ? CTF_V_AXIS : 0) | ((jc.axes_mask & JOYFLAG_POVVALID) ? CTF_POV : 0) | ((jc.axes_mask & JOYFLAG_POV2VALID) ? CTF_POV2 : 0) | ((jc.axes_mask & JOYFLAG_POV3VALID) ? CTF_POV3 : 0) | ((jc.axes_mask & JOYFLAG_POV4VALID) ? CTF_POV4 : 0); + + m_ControlList[num_devs].axis_is_trigger = + ((jc.trigger_axis_mask & JOYFLAG_XVALID) ? CTF_X_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_YVALID) ? CTF_Y_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_ZVALID) ? CTF_Z_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_RVALID) ? CTF_R_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_UVALID) ? CTF_U_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_VVALID) ? CTF_V_AXIS : 0); int minV = -32768, maxV = 32768; m_ControlList[num_devs].normalizer[0] = (maxV - minV) / 2.0f; diff --git a/ddio/sdlcontroller.h b/ddio/sdlcontroller.h index 0cb39e0a6..43db40052 100644 --- a/ddio/sdlcontroller.h +++ b/ddio/sdlcontroller.h @@ -112,6 +112,7 @@ class sdlgameController : public gameController { struct t_controller { int id = 0; uint16_t flags = 0; + uint16_t axis_is_trigger = 0; uint16_t buttons = 0; unsigned btnmask = 0; float normalizer[CT_NUM_AXES]{}; From c8987c8fc1d83114aa8168bd95499ef7037dce98 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 15:53:55 +0200 Subject: [PATCH 03/12] Don't allow mapping trigger axis to 2-directional controls --- ddio/sdlcontroller.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 7f7a142d3..57f2e5528 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -304,14 +304,13 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { } break; - case ctAnalogTrigger: case ctAxis: for (i = 2; i < m_NumControls; i++) { float pos; float limit; unsigned ctl = CONTROLLER_CTL_INFO(i, NULL_CONTROLLER); - if (m_ControlList[i].flags & CTF_V_AXIS) { + if ((m_ControlList[i].flags & CTF_V_AXIS) && !(m_ControlList[i].axis_is_trigger & CTF_V_AXIS)) { limit = (m_ControlList[i].sens[CT_V_AXIS - 1] > 1.5f) ? 0.95f : (m_ControlList[i].sens[CT_V_AXIS - 1] > 1.0f) ? 0.80f : (m_ControlList[i].sens[CT_V_AXIS - 1] / 2); @@ -319,7 +318,7 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { if (fabs(pos) > limit) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_V_AXIS, NULL_BINDING)); } - if (m_ControlList[i].flags & CTF_U_AXIS) { + if (m_ControlList[i].flags & CTF_U_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_U_AXIS)) { limit = (m_ControlList[i].sens[CT_U_AXIS - 1] > 1.5f) ? 0.95f : (m_ControlList[i].sens[CT_U_AXIS - 1] > 1.0f) ? 0.80f : (m_ControlList[i].sens[CT_U_AXIS - 1] / 2); @@ -327,7 +326,7 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { if (fabs(pos) > limit) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_U_AXIS, NULL_BINDING)); } - if (m_ControlList[i].flags & CTF_R_AXIS) { + if (m_ControlList[i].flags & CTF_R_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_R_AXIS)) { limit = (m_ControlList[i].sens[CT_R_AXIS - 1] > 1.5f) ? 0.95f : (m_ControlList[i].sens[CT_R_AXIS - 1] > 1.0f) ? 0.80f : (m_ControlList[i].sens[CT_R_AXIS - 1] / 2); @@ -335,7 +334,7 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { if (fabs(pos) > limit) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_R_AXIS, NULL_BINDING)); } - if (m_ControlList[i].flags & CTF_Z_AXIS) { + if (m_ControlList[i].flags & CTF_Z_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_Z_AXIS)) { limit = (m_ControlList[i].sens[CT_Z_AXIS - 1] > 1.5f) ? 0.95f : (m_ControlList[i].sens[CT_Z_AXIS - 1] > 1.0f) ? 0.80f : (m_ControlList[i].sens[CT_Z_AXIS - 1] / 2); @@ -343,7 +342,7 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { if (fabs(pos) > limit) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_Z_AXIS, NULL_BINDING)); } - if (m_ControlList[i].flags & CTF_Y_AXIS) { + if (m_ControlList[i].flags & CTF_Y_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_Y_AXIS)) { limit = (m_ControlList[i].sens[CT_Y_AXIS - 1] > 1.5f) ? 0.95f : (m_ControlList[i].sens[CT_Y_AXIS - 1] > 1.0f) ? 0.80f : (m_ControlList[i].sens[CT_Y_AXIS - 1] / 2); @@ -351,7 +350,7 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { if (fabs(pos) > limit) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_Y_AXIS, NULL_BINDING)); } - if (m_ControlList[i].flags & CTF_X_AXIS) { + if (m_ControlList[i].flags & CTF_X_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_X_AXIS)) { limit = (m_ControlList[i].sens[CT_X_AXIS - 1] > 1.5f) ? 0.95f : (m_ControlList[i].sens[CT_X_AXIS - 1] > 1.0f) ? 0.80f : (m_ControlList[i].sens[CT_X_AXIS - 1] / 2); From a95988dc36047ad611c62d8467be0b6d528dc04a Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 16:10:31 +0200 Subject: [PATCH 04/12] Factorize get_controller_value for axis inputs --- ddio/sdlcontroller.cpp | 95 +++++++++++++----------------------------- ddio/sdlcontroller.h | 3 ++ 2 files changed, 31 insertions(+), 67 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 57f2e5528..377ab3fec 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -305,59 +305,13 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { break; case ctAxis: - for (i = 2; i < m_NumControls; i++) { - float pos; - float limit; - unsigned ctl = CONTROLLER_CTL_INFO(i, NULL_CONTROLLER); - - if ((m_ControlList[i].flags & CTF_V_AXIS) && !(m_ControlList[i].axis_is_trigger & CTF_V_AXIS)) { - limit = (m_ControlList[i].sens[CT_V_AXIS - 1] > 1.5f) ? 0.95f - : (m_ControlList[i].sens[CT_V_AXIS - 1] > 1.0f) ? 0.80f - : (m_ControlList[i].sens[CT_V_AXIS - 1] / 2); - pos = get_axis_value(i, CT_V_AXIS, ctAnalog); - if (fabs(pos) > limit) - val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_V_AXIS, NULL_BINDING)); - } - if (m_ControlList[i].flags & CTF_U_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_U_AXIS)) { - limit = (m_ControlList[i].sens[CT_U_AXIS - 1] > 1.5f) ? 0.95f - : (m_ControlList[i].sens[CT_U_AXIS - 1] > 1.0f) ? 0.80f - : (m_ControlList[i].sens[CT_U_AXIS - 1] / 2); - pos = get_axis_value(i, CT_U_AXIS, ctAnalog); - if (fabs(pos) > limit) - val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_U_AXIS, NULL_BINDING)); - } - if (m_ControlList[i].flags & CTF_R_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_R_AXIS)) { - limit = (m_ControlList[i].sens[CT_R_AXIS - 1] > 1.5f) ? 0.95f - : (m_ControlList[i].sens[CT_R_AXIS - 1] > 1.0f) ? 0.80f - : (m_ControlList[i].sens[CT_R_AXIS - 1] / 2); - pos = get_axis_value(i, CT_R_AXIS, ctAnalog); - if (fabs(pos) > limit) - val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_R_AXIS, NULL_BINDING)); - } - if (m_ControlList[i].flags & CTF_Z_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_Z_AXIS)) { - limit = (m_ControlList[i].sens[CT_Z_AXIS - 1] > 1.5f) ? 0.95f - : (m_ControlList[i].sens[CT_Z_AXIS - 1] > 1.0f) ? 0.80f - : (m_ControlList[i].sens[CT_Z_AXIS - 1] / 2); - pos = get_axis_value(i, CT_Z_AXIS, ctAnalog); - if (fabs(pos) > limit) - val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_Z_AXIS, NULL_BINDING)); - } - if (m_ControlList[i].flags & CTF_Y_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_Y_AXIS)) { - limit = (m_ControlList[i].sens[CT_Y_AXIS - 1] > 1.5f) ? 0.95f - : (m_ControlList[i].sens[CT_Y_AXIS - 1] > 1.0f) ? 0.80f - : (m_ControlList[i].sens[CT_Y_AXIS - 1] / 2); - pos = get_axis_value(i, CT_Y_AXIS, ctAnalog); - if (fabs(pos) > limit) - val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_Y_AXIS, NULL_BINDING)); - } - if (m_ControlList[i].flags & CTF_X_AXIS && !(m_ControlList[i].axis_is_trigger & CTF_X_AXIS)) { - limit = (m_ControlList[i].sens[CT_X_AXIS - 1] > 1.5f) ? 0.95f - : (m_ControlList[i].sens[CT_X_AXIS - 1] > 1.0f) ? 0.80f - : (m_ControlList[i].sens[CT_X_AXIS - 1] / 2); - pos = get_axis_value(i, CT_X_AXIS, ctAnalog); - if (fabs(pos) > limit) - val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_X_AXIS, NULL_BINDING)); - } + for (int controllerId = 2; controllerId < m_NumControls; controllerId++) { + get_controller_axis_value(controllerId, CTF_V_AXIS, CT_V_AXIS, &val); + get_controller_axis_value(controllerId, CTF_U_AXIS, CT_U_AXIS, &val); + get_controller_axis_value(controllerId, CTF_R_AXIS, CT_R_AXIS, &val); + get_controller_axis_value(controllerId, CTF_Z_AXIS, CT_Z_AXIS, &val); + get_controller_axis_value(controllerId, CTF_Y_AXIS, CT_Y_AXIS, &val); + get_controller_axis_value(controllerId, CTF_X_AXIS, CT_X_AXIS, &val); } break; @@ -441,6 +395,18 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { return val; } +void sdlgameController::get_controller_axis_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val) { + + if ((m_ControlList[controllerId].flags & axis_ctf_flag) && !(m_ControlList[controllerId].axis_is_trigger & axis_ctf_flag)) { + float limit = (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.5f) ? 0.95f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.0f) ? 0.80f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 2); + float pos = get_axis_value(controllerId, axis_ct_flag, ctAnalog); + if (fabs(pos) > limit) + *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); + } +} + // sets the configuration of a function (type must be of an array == CTLBINDS_PER_FUNC) void sdlgameController::set_controller_function(int id, const ct_type *type, ct_config_data value, const uint8_t *flags) { @@ -707,13 +673,9 @@ unsigned sdlgameController::get_joy_raw_values(int *x, int *y) { return 0; } -gameController *CreateController(int num_funcs, ct_function *funcs) { - return new sdlgameController(num_funcs, funcs); -} +gameController *CreateController(int num_funcs, ct_function *funcs) { return new sdlgameController(num_funcs, funcs); } -void DestroyController(gameController *ctl) { - delete ctl; -} +void DestroyController(gameController *ctl) { delete ctl; } // activates or deactivates mouse and or controller void sdlgameController::mask_controllers(bool joystick, bool mouse) { @@ -909,14 +871,13 @@ bool sdlgameController::enum_controllers() { ((jc.axes_mask & JOYFLAG_POV2VALID) ? CTF_POV2 : 0) | ((jc.axes_mask & JOYFLAG_POV3VALID) ? CTF_POV3 : 0) | ((jc.axes_mask & JOYFLAG_POV4VALID) ? CTF_POV4 : 0); - m_ControlList[num_devs].axis_is_trigger = - ((jc.trigger_axis_mask & JOYFLAG_XVALID) ? CTF_X_AXIS : 0) | - ((jc.trigger_axis_mask & JOYFLAG_YVALID) ? CTF_Y_AXIS : 0) | - ((jc.trigger_axis_mask & JOYFLAG_ZVALID) ? CTF_Z_AXIS : 0) | - ((jc.trigger_axis_mask & JOYFLAG_RVALID) ? CTF_R_AXIS : 0) | - ((jc.trigger_axis_mask & JOYFLAG_UVALID) ? CTF_U_AXIS : 0) | - ((jc.trigger_axis_mask & JOYFLAG_VVALID) ? CTF_V_AXIS : 0); - + m_ControlList[num_devs].axis_is_trigger = ((jc.trigger_axis_mask & JOYFLAG_XVALID) ? CTF_X_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_YVALID) ? CTF_Y_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_ZVALID) ? CTF_Z_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_RVALID) ? CTF_R_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_UVALID) ? CTF_U_AXIS : 0) | + ((jc.trigger_axis_mask & JOYFLAG_VVALID) ? CTF_V_AXIS : 0); + int minV = -32768, maxV = 32768; m_ControlList[num_devs].normalizer[0] = (maxV - minV) / 2.0f; m_ControlList[num_devs].normalizer[1] = (maxV - minV) / 2.0f; diff --git a/ddio/sdlcontroller.h b/ddio/sdlcontroller.h index 43db40052..682559508 100644 --- a/ddio/sdlcontroller.h +++ b/ddio/sdlcontroller.h @@ -70,6 +70,9 @@ class sdlgameController : public gameController { // returns the value of a requested controller type. make sure you flush the controller before polling. ct_config_data get_controller_value(ct_type type_req) override; + // return the value associated of a controller axis, when active + void get_controller_axis_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val); + // sets the configuration of a function (type must be of an array == CTLBINDS_PER_FUNC) void set_controller_function(int id, const ct_type *type, ct_config_data value, const uint8_t *flags) override; From f9098b965d92df7cc7fccd6b4a8d7a8e68bcbc52 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 16:48:33 +0200 Subject: [PATCH 05/12] Support mapping controller analog triggers to buttons --- Descent3/CtlCfgElem.cpp | 14 +++++++++++--- Descent3/CtlCfgElem.h | 2 ++ Descent3/ctlconfig.cpp | 1 + ddio/controller.h | 3 ++- ddio/sdlcontroller.cpp | 31 ++++++++++++++++++++++++++++--- ddio/sdlcontroller.h | 5 ++++- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Descent3/CtlCfgElem.cpp b/Descent3/CtlCfgElem.cpp index 3d9885720..c7e59afd4 100644 --- a/Descent3/CtlCfgElem.cpp +++ b/Descent3/CtlCfgElem.cpp @@ -1,5 +1,5 @@ /* -* Descent 3 +* Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify @@ -491,6 +491,7 @@ const char *cfg_binding_text(ct_type ctype, uint8_t ctrl, uint8_t binding) { case ctPOV2: case ctPOV3: case ctPOV4: + case ctAnalogTrigger: case ctMouseButton: case ctButton: case ctMouseAxis: @@ -513,7 +514,7 @@ const char *cfg_binding_text(ct_type ctype, uint8_t ctrl, uint8_t binding) { class cfg_element_ui : public newuiMessageBox { uint8_t m_element; // element passed and returned. uint8_t m_controller; // controller. - int8_t m_alpha; // used for fx. + int8_t m_alpha; // used for fx. ct_type m_type; public: @@ -812,6 +813,7 @@ bool cfg_element::Configure(ct_type *new_elem_type, uint8_t *controller, uint8_t case ctPOV2: case ctPOV3: case ctPOV4: + case ctAnalogTrigger: case ctAxis: case ctMouseAxis: configure = true; @@ -872,6 +874,7 @@ void cfg_element_ui::Create(const char *title, ct_type type, uint8_t controller, case ctPOV2: case ctPOV3: case ctPOV4: + case ctAnalogTrigger: sheet->AddText(TXT_CTLBINDHELP2_0); sheet->AddText(TXT_CTLBINDHELP2_1); break; @@ -936,7 +939,8 @@ int cfg_element_ui::DoUI() { case ctPOV: case ctPOV2: case ctPOV3: - case ctPOV4: { + case ctPOV4: + case ctAnalogTrigger: { ct_config_data ccfgdata; ct_type new_type; @@ -960,6 +964,10 @@ int cfg_element_ui::DoUI() { if (!GCV_VALID_RESULT(ccfgdata)) { ccfgdata = Controller->get_controller_value(ctButton); // read hats before buttons new_type = ctButton; + if (!GCV_VALID_RESULT(ccfgdata)) { + ccfgdata = Controller->get_controller_value(ctAnalogTrigger); + new_type = ctAnalogTrigger; + } } } } diff --git a/Descent3/CtlCfgElem.h b/Descent3/CtlCfgElem.h index 2e5f34cff..6db85b9ed 100644 --- a/Descent3/CtlCfgElem.h +++ b/Descent3/CtlCfgElem.h @@ -131,6 +131,7 @@ static inline void parse_config_data(tCfgDataParts *parts, ct_type type0, ct_typ case ctPOV: case ctPOV2: case ctPOV3: + case ctAnalogTrigger: case ctPOV4: parts->bind_0 = CONTROLLER_CTL1_VALUE(CONTROLLER_VALUE(cfgdata)); break; @@ -150,6 +151,7 @@ static inline void parse_config_data(tCfgDataParts *parts, ct_type type0, ct_typ case ctPOV2: case ctPOV3: case ctPOV4: + case ctAnalogTrigger: parts->bind_1 = CONTROLLER_CTL2_VALUE(CONTROLLER_VALUE(cfgdata)); break; default: diff --git a/Descent3/ctlconfig.cpp b/Descent3/ctlconfig.cpp index 88bdb1dfc..7fde25181 100644 --- a/Descent3/ctlconfig.cpp +++ b/Descent3/ctlconfig.cpp @@ -1005,6 +1005,7 @@ void ctl_cfg_element_options_dialog(int16_t fnid) { case ctPOV2: case ctPOV3: case ctPOV4: + case ctAnalogTrigger: strcpy(str, TXT_CFGHELP_BTNS); break; default: diff --git a/ddio/controller.h b/ddio/controller.h index d4793cba2..f4d1d60fd 100644 --- a/ddio/controller.h +++ b/ddio/controller.h @@ -139,7 +139,8 @@ enum ct_type { ctMouseButton, ctPOV2, ctPOV3, - ctPOV4 // auxillary POV values. + ctPOV4, // auxillary POV values. + ctAnalogTrigger }; struct ct_function { diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 377ab3fec..8e982adb4 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -241,6 +241,9 @@ const char *sdlgameController::get_binding_text(ct_type type, uint8_t ctrl, uint } break; } + case ctAnalogTrigger: + snprintf(binding_text, sizeof(binding_text), "J%d:trig%d", (ctrl - 2) + 1, bind); + break; case ctKey: break; @@ -314,7 +317,16 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { get_controller_axis_value(controllerId, CTF_X_AXIS, CT_X_AXIS, &val); } break; - + case ctAnalogTrigger: + for (int controllerId = 2; controllerId < m_NumControls; controllerId++) { + get_trigger_value(controllerId, CTF_V_AXIS, CT_V_AXIS, &val); + get_trigger_value(controllerId, CTF_U_AXIS, CT_U_AXIS, &val); + get_trigger_value(controllerId, CTF_R_AXIS, CT_R_AXIS, &val); + get_trigger_value(controllerId, CTF_Z_AXIS, CT_Z_AXIS, &val); + get_trigger_value(controllerId, CTF_Y_AXIS, CT_Y_AXIS, &val); + get_trigger_value(controllerId, CTF_X_AXIS, CT_X_AXIS, &val); + } + break; case ctMouseAxis: { float pos = 0.0f; int ctl = CONTROLLER_CTL_INFO(1, NULL_CONTROLLER), i = 1; @@ -407,6 +419,17 @@ void sdlgameController::get_controller_axis_value(int controllerId, unsigned int } } +void sdlgameController::get_trigger_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val) { + if ((m_ControlList[controllerId].flags & axis_ctf_flag) && (m_ControlList[controllerId].axis_is_trigger & axis_ctf_flag)) { + float limit = (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.5f) ? 0.5f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.0f) ? 0.3f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 4); + float pos = get_axis_value(controllerId, axis_ct_flag, ctAnalog); + if (pos > limit) + *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); + } +} + // sets the configuration of a function (type must be of an array == CTLBINDS_PER_FUNC) void sdlgameController::set_controller_function(int id, const ct_type *type, ct_config_data value, const uint8_t *flags) { @@ -495,6 +518,7 @@ bool sdlgameController::get_packet(int id, ct_packet *packet, ct_format alt_form case ctMouseAxis: packet->flags |= CTPK_MOUSE; case ctAxis: + case ctAnalogTrigger: val = get_axis_value(controller, value, alt_format, (m_ElementList[id].flags[i] & CTFNF_INVERT) ? true : false); if (m_ElementList[id].flags[i] & CTFNF_INVERT) { if (alt_format == ctDigital) { @@ -503,8 +527,7 @@ bool sdlgameController::get_packet(int id, ct_packet *packet, ct_format alt_form val = -val; } } - break; - + break; case ctMouseButton: packet->flags |= CTPK_MOUSE; case ctButton: @@ -594,6 +617,7 @@ int sdlgameController::assign_function(ct_function *func) { case ctKey: elem.ctl[i] = 0; break; + case ctAnalogTrigger: case ctAxis: elem.ctl[i] = get_axis_controller(func->value[i]); break; @@ -994,6 +1018,7 @@ void sdlgameController::assign_element(int id, ct_element *elem) { case ctPOV2: case ctPOV3: case ctPOV4: + case ctAnalogTrigger: // if (!(m_ControlList[elem->ctl[i]].flags & CTF_POV)) // m_ElementList[id].ctl[i] = NULL_WINCONTROLLER; break; diff --git a/ddio/sdlcontroller.h b/ddio/sdlcontroller.h index 682559508..f70022e44 100644 --- a/ddio/sdlcontroller.h +++ b/ddio/sdlcontroller.h @@ -70,9 +70,12 @@ class sdlgameController : public gameController { // returns the value of a requested controller type. make sure you flush the controller before polling. ct_config_data get_controller_value(ct_type type_req) override; - // return the value associated of a controller axis, when active + // fill `val` with the axis and controller values if axis value is over a threshold. Used for control mapping. void get_controller_axis_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val); + // fill `val` with the axis and controller values if trigger value is over a threshold + void get_trigger_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val); + // sets the configuration of a function (type must be of an array == CTLBINDS_PER_FUNC) void set_controller_function(int id, const ct_type *type, ct_config_data value, const uint8_t *flags) override; From e17871db2472dfd1c87c3fb3145fda4725d22005 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 20:33:54 +0200 Subject: [PATCH 06/12] Read trigger analog value in the SDL adapter --- ddio/sdlcontroller.cpp | 131 ++++++++++++++++++++++++++++++++++------- ddio/sdlcontroller.h | 5 +- 2 files changed, 115 insertions(+), 21 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 8e982adb4..983f3445a 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -319,12 +319,12 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { break; case ctAnalogTrigger: for (int controllerId = 2; controllerId < m_NumControls; controllerId++) { - get_trigger_value(controllerId, CTF_V_AXIS, CT_V_AXIS, &val); - get_trigger_value(controllerId, CTF_U_AXIS, CT_U_AXIS, &val); - get_trigger_value(controllerId, CTF_R_AXIS, CT_R_AXIS, &val); - get_trigger_value(controllerId, CTF_Z_AXIS, CT_Z_AXIS, &val); - get_trigger_value(controllerId, CTF_Y_AXIS, CT_Y_AXIS, &val); - get_trigger_value(controllerId, CTF_X_AXIS, CT_X_AXIS, &val); + get_controller_trigger_value(controllerId, CTF_V_AXIS, CT_V_AXIS, &val); + get_controller_trigger_value(controllerId, CTF_U_AXIS, CT_U_AXIS, &val); + get_controller_trigger_value(controllerId, CTF_R_AXIS, CT_R_AXIS, &val); + get_controller_trigger_value(controllerId, CTF_Z_AXIS, CT_Z_AXIS, &val); + get_controller_trigger_value(controllerId, CTF_Y_AXIS, CT_Y_AXIS, &val); + get_controller_trigger_value(controllerId, CTF_X_AXIS, CT_X_AXIS, &val); } break; case ctMouseAxis: { @@ -407,26 +407,34 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { return val; } -void sdlgameController::get_controller_axis_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val) { +void sdlgameController::get_controller_axis_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, + ct_config_data *val) { - if ((m_ControlList[controllerId].flags & axis_ctf_flag) && !(m_ControlList[controllerId].axis_is_trigger & axis_ctf_flag)) { - float limit = (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.5f) ? 0.95f - : (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.0f) ? 0.80f - : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 2); + if ((m_ControlList[controllerId].flags & axis_ctf_flag) && + !(m_ControlList[controllerId].axis_is_trigger & axis_ctf_flag)) { + float limit = (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.5f) ? 0.95f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.0f) + ? 0.80f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 2); float pos = get_axis_value(controllerId, axis_ct_flag, ctAnalog); if (fabs(pos) > limit) - *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); + *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), + CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); } } -void sdlgameController::get_trigger_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val) { - if ((m_ControlList[controllerId].flags & axis_ctf_flag) && (m_ControlList[controllerId].axis_is_trigger & axis_ctf_flag)) { - float limit = (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.5f) ? 0.5f - : (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.0f) ? 0.3f - : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 4); +void sdlgameController::get_controller_trigger_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, + ct_config_data *val) { + if ((m_ControlList[controllerId].flags & axis_ctf_flag) && + (m_ControlList[controllerId].axis_is_trigger & axis_ctf_flag)) { + float limit = (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.5f) ? 0.5f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] > 1.0f) + ? 0.3f + : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 4); float pos = get_axis_value(controllerId, axis_ct_flag, ctAnalog); if (pos > limit) - *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); + *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), + CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); } } @@ -517,8 +525,9 @@ bool sdlgameController::get_packet(int id, ct_packet *packet, ct_format alt_form case ctMouseAxis: packet->flags |= CTPK_MOUSE; - case ctAxis: case ctAnalogTrigger: + val = get_trigger_value(controller, value, alt_format); + case ctAxis: val = get_axis_value(controller, value, alt_format, (m_ElementList[id].flags[i] & CTFNF_INVERT) ? true : false); if (m_ElementList[id].flags[i] & CTFNF_INVERT) { if (alt_format == ctDigital) { @@ -527,7 +536,7 @@ bool sdlgameController::get_packet(int id, ct_packet *packet, ct_format alt_form val = -val; } } - break; + break; case ctMouseButton: packet->flags |= CTPK_MOUSE; case ctButton: @@ -1091,6 +1100,7 @@ float sdlgameController::get_button_value(int8_t controller, ct_format format, u break; case ctDigital: + case ctAnalog: if (m_ControlList[controller].id == CTID_MOUSE) { if (m_MseState.btnmask & (1 << button)) val = 1.0f; @@ -1270,6 +1280,87 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form return val; } +float sdlgameController::get_trigger_value(int8_t controller, uint8_t axis, ct_format format) { + struct sdlgameController::t_controller *ctldev; + float val = 0.0f; + float normalizer, axisval = 0, nullzone; //, senszone; + + if (controller <= NULL_LNXCONTROLLER || controller >= CT_MAX_CONTROLLERS) { + return 0.0f; + } + + ctldev = &m_ControlList[controller]; + if (ctldev->id == CTID_INVALID) { + return 0.0f; + } + + // verify controller axis + if (!CHECK_FLAG(ctldev->flags, 1 << (axis - 1))) { + return val; + } + + // get raw value + switch (axis) { + case CT_X_AXIS: + axisval = m_ExtCtlStates[ctldev->id].x; + break; + case CT_Y_AXIS: + axisval = m_ExtCtlStates[ctldev->id].y; + break; + case CT_Z_AXIS: + axisval = m_ExtCtlStates[ctldev->id].z; + break; + case CT_R_AXIS: + axisval = (float)m_ExtCtlStates[ctldev->id].r; + break; + case CT_U_AXIS: + axisval = (float)m_ExtCtlStates[ctldev->id].u; + break; + case CT_V_AXIS: + axisval = (float)m_ExtCtlStates[ctldev->id].v; + break; + default: + Int3(); // NOT A VALID AXIS + } + + // create normalizer + axis--; + normalizer = ctldev->normalizer[axis]; + nullzone = (m_ControlList[controller].deadzone < 0.05f) ? 0.05f : m_ControlList[controller].deadzone; + + val = axisval / normalizer; + val = val - ((ctldev->id == CTID_MOUSE) ? 0.0f : 1.0f); // joystick needs to be normalized to -1.0 to 1.0 + + // calculate adjusted value + if (val > nullzone) { + val = (val - nullzone) / (1.0f - nullzone); + } else if (val < -nullzone) { + val = (val + nullzone) / (1.0f - nullzone); + } else { + val = 0.0f; + } + val = ctldev->sensmod[axis] * ctldev->sens[axis] * val; + val = val + 1.0f; + + val = std::clamp(val, 0.0f, 2.0f); + + // determine value based off requested format. + if (format == ctDigital) { + if (val < 0.5f) + val = 0.0f; + else + val = 1.0f; + } else if (format == ctAnalog) { + val = val - 1.0f; + } else { + val = 0.0f; + LOG_WARNING << "unsupported format for function sdlgameController::get_trigger_value."; + } + + LOG_DEBUG << "Axis " << axis << " value is " << val << " raw " << axisval; + + return val; +} // do some pov stuff float sdlgameController::get_pov_value(int8_t controller, ct_format format, uint8_t pov_number, uint8_t pov) { float val = 0.0f; diff --git a/ddio/sdlcontroller.h b/ddio/sdlcontroller.h index f70022e44..a09a816a3 100644 --- a/ddio/sdlcontroller.h +++ b/ddio/sdlcontroller.h @@ -74,7 +74,7 @@ class sdlgameController : public gameController { void get_controller_axis_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val); // fill `val` with the axis and controller values if trigger value is over a threshold - void get_trigger_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val); + void get_controller_trigger_value(int controllerId, unsigned int axis_ctf_flag, uint8_t axis_ct_flag, ct_config_data* val); // sets the configuration of a function (type must be of an array == CTLBINDS_PER_FUNC) void set_controller_function(int id, const ct_type *type, ct_config_data value, const uint8_t *flags) override; @@ -153,6 +153,9 @@ class sdlgameController : public gameController { // note controller is index into ControlList. float get_axis_value(int8_t controller, uint8_t axis, ct_format format, bool invert = false); + // get value of analog button/trigger + float get_trigger_value(int8_t controller, uint8_t axis, ct_format format); + // get value of button in seconds, presses, etc. float get_button_value(int8_t controller, ct_format format, uint8_t button); From 0d848ec0f818e260f3a964571ac78957eb9ac7a3 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 20:34:29 +0200 Subject: [PATCH 07/12] Make button for direction control analog --- Descent3/Controls.cpp | 80 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/Descent3/Controls.cpp b/Descent3/Controls.cpp index d956e13e9..166e1ded0 100644 --- a/Descent3/Controls.cpp +++ b/Descent3/Controls.cpp @@ -1,5 +1,5 @@ /* -* Descent 3 +* Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify @@ -879,25 +879,25 @@ void DoControllerMovement(game_controls *controls) { ct_packet ctl_pub, ctl_pdb, ctl_hlb, ctl_hrb, ctl_blb, ctl_brb; // read controls - Controller->get_packet(ctfFORWARD_THRUSTAXIS, &ctl_z); - Controller->get_packet(ctfUP_THRUSTAXIS, &ctl_y); - Controller->get_packet(ctfRIGHT_THRUSTAXIS, &ctl_x); - Controller->get_packet(ctfPITCH_DOWNAXIS, &ctl_p); - Controller->get_packet(ctfBANK_RIGHTAXIS, &ctl_b); - Controller->get_packet(ctfHEADING_RIGHTAXIS, &ctl_h); - Controller->get_packet(ctfUP_BUTTON, &ctl_povu); - Controller->get_packet(ctfDOWN_BUTTON, &ctl_povd); - Controller->get_packet(ctfRIGHT_BUTTON, &ctl_povr); - Controller->get_packet(ctfLEFT_BUTTON, &ctl_povl); - Controller->get_packet(ctfFORWARD_BUTTON, &ctl_fb); - Controller->get_packet(ctfREVERSE_BUTTON, &ctl_rb); - Controller->get_packet(ctfAFTERBURN_BUTTON, &ctl_afterburn); - Controller->get_packet(ctfHEADING_LEFTBUTTON, &ctl_hlb); - Controller->get_packet(ctfHEADING_RIGHTBUTTON, &ctl_hrb); - Controller->get_packet(ctfPITCH_UPBUTTON, &ctl_pub); - Controller->get_packet(ctfPITCH_DOWNBUTTON, &ctl_pdb); - Controller->get_packet(ctfBANK_LEFTBUTTON, &ctl_blb); - Controller->get_packet(ctfBANK_RIGHTBUTTON, &ctl_brb); + Controller->get_packet(ctfFORWARD_THRUSTAXIS, &ctl_z, ctAnalog); + Controller->get_packet(ctfUP_THRUSTAXIS, &ctl_y, ctAnalog); + Controller->get_packet(ctfRIGHT_THRUSTAXIS, &ctl_x, ctAnalog); + Controller->get_packet(ctfPITCH_DOWNAXIS, &ctl_p, ctAnalog); + Controller->get_packet(ctfBANK_RIGHTAXIS, &ctl_b, ctAnalog); + Controller->get_packet(ctfHEADING_RIGHTAXIS, &ctl_h, ctAnalog); + Controller->get_packet(ctfUP_BUTTON, &ctl_povu, ctAnalog); + Controller->get_packet(ctfDOWN_BUTTON, &ctl_povd, ctAnalog); + Controller->get_packet(ctfRIGHT_BUTTON, &ctl_povr, ctAnalog); + Controller->get_packet(ctfLEFT_BUTTON, &ctl_povl, ctAnalog); + Controller->get_packet(ctfFORWARD_BUTTON, &ctl_fb, ctAnalog); + Controller->get_packet(ctfREVERSE_BUTTON, &ctl_rb, ctAnalog); + Controller->get_packet(ctfAFTERBURN_BUTTON, &ctl_afterburn, ctAnalog); + Controller->get_packet(ctfHEADING_LEFTBUTTON, &ctl_hlb, ctAnalog); + Controller->get_packet(ctfHEADING_RIGHTBUTTON, &ctl_hrb, ctAnalog); + Controller->get_packet(ctfPITCH_UPBUTTON, &ctl_pub, ctAnalog); + Controller->get_packet(ctfPITCH_DOWNBUTTON, &ctl_pdb, ctAnalog); + Controller->get_packet(ctfBANK_LEFTBUTTON, &ctl_blb, ctAnalog); + Controller->get_packet(ctfBANK_RIGHTBUTTON, &ctl_brb, ctAnalog); // do x and y thrust controls->sideways_thrust += ctl_x.value; @@ -935,40 +935,40 @@ void DoControllerMovement(game_controls *controls) { } // do button heading - if (ctl_hlb.value) - controls->heading_thrust += (-1.0f); - if (ctl_hrb.value) - controls->heading_thrust += (1.0f); + if (ctl_hlb.value > 0.0f) + controls->heading_thrust += ctl_hlb.value; + if (ctl_hrb.value > 0.0f) + controls->heading_thrust -= ctl_hlb.value; // do button pitch - if (ctl_pub.value) - controls->pitch_thrust += (-1.0f); - if (ctl_pdb.value) - controls->pitch_thrust += (1.0f); + if (ctl_pub.value > 0.0f) + controls->pitch_thrust -= ctl_pub.value; + if (ctl_pdb.value > 0.0f) + controls->pitch_thrust += ctl_pdb.value; // do forward thrust based off of button values. controls->forward_thrust += ((ctl_fb.value - ctl_rb.value) / Frametime); // do button banking - if (ctl_blb.value) - controls->bank_thrust += (1.0f); - if (ctl_brb.value) - controls->bank_thrust += (-1.0f); + if (ctl_blb.value > 0.0f) + controls->bank_thrust += ctl_blb.value; + if (ctl_brb.value > 0.0f) + controls->bank_thrust -= ctl_blb.value; // do button sliding. use control frametime to set sliding times per frame. // note that vertical and sideways thrusts are dependent on what the keyboard controller // set these values to. so we save our own slidetimes. - if (ctl_povu.value) { - controls->vertical_thrust += (1.0f); + if (ctl_povu.value > 0.0f) { + controls->vertical_thrust += ctl_povu.value; } - if (ctl_povd.value) { - controls->vertical_thrust -= (1.0f); + if (ctl_povd.value > 0.0f) { + controls->vertical_thrust -= ctl_povd.value; } - if (ctl_povr.value) { - controls->sideways_thrust += (1.0f); + if (ctl_povr.value > 0.0f) { + controls->sideways_thrust += ctl_povr.value; } - if (ctl_povl.value) { - controls->sideways_thrust -= (1.0f); + if (ctl_povl.value > 0.0f) { + controls->sideways_thrust -= ctl_povl.value; } } From 09dc2ac59997c72b5d42d4844a05636a611fb10d Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 22 Sep 2024 21:10:11 +0200 Subject: [PATCH 08/12] Read properly trigger analog value --- Descent3/Controls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Descent3/Controls.cpp b/Descent3/Controls.cpp index 166e1ded0..f28ecf83a 100644 --- a/Descent3/Controls.cpp +++ b/Descent3/Controls.cpp @@ -942,7 +942,7 @@ void DoControllerMovement(game_controls *controls) { // do button pitch if (ctl_pub.value > 0.0f) - controls->pitch_thrust -= ctl_pub.value; + controls->pitch_thrust -= ctl_pub.value; if (ctl_pdb.value > 0.0f) controls->pitch_thrust += ctl_pdb.value; From e71e0d401d0558ef55c61ebbddbffe778b150945 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Tue, 15 Oct 2024 21:45:07 +0200 Subject: [PATCH 09/12] Unset default axis mappings that are analog triggers Default axis mappings could map controller triggers to functions that require bi-directional axis to work properly --- ddio/sdlcontroller.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index 983f3445a..b1ef0d4f0 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -609,6 +609,7 @@ void sdlgameController::set_axis_sensitivity(ct_type axis_type, uint8_t axis, fl } } +#include // assigns an individual function int sdlgameController::assign_function(ct_function *func) { // for now this is a straight forward translation (that is, no mapping of needs to controller @@ -627,6 +628,7 @@ int sdlgameController::assign_function(ct_function *func) { elem.ctl[i] = 0; break; case ctAnalogTrigger: + std::cout << "test"; case ctAxis: elem.ctl[i] = get_axis_controller(func->value[i]); break; @@ -985,9 +987,14 @@ int8_t sdlgameController::get_axis_controller(uint8_t axis) { if (axis == NULL_BINDING) return NULL_LNXCONTROLLER; - for (int i = 2; i < m_NumControls; i++) - if ((m_ControlList[i].flags & (1 << (axis - 1))) && m_ControlList[i].id != CTID_INVALID) + int axis_mask = (1 << (axis - 1)); + + for (int i = 2; i < m_NumControls; i++) { + if ((m_ControlList[i].flags & axis_mask) && m_ControlList[i].id != CTID_INVALID && + !(m_ControlList[i].axis_is_trigger & axis_mask)) { return i; + } + } return NULL_LNXCONTROLLER; } @@ -1483,12 +1490,12 @@ int CTLLex(const char *command) { // okay, now search for a '****.ctl' file in the Base_directories void sdlgameController::parse_ctl_file(int devnum, const char *ctlname) { - for (auto base_directories_iterator = Base_directories.rbegin(); - base_directories_iterator != Base_directories.rend(); + for (auto base_directories_iterator = Base_directories.rbegin(); base_directories_iterator != Base_directories.rend(); ++base_directories_iterator) { // parse each file until we find a name match, no name match, just return ddio_DoForeachFile( - *base_directories_iterator, std::regex(".*\\.ctl"), [this, &devnum, &ctlname](const std::filesystem::path &path) { + *base_directories_iterator, std::regex(".*\\.ctl"), + [this, &devnum, &ctlname](const std::filesystem::path &path) { InfFile file; bool found_name = false; From 8879f62f47ca12eba82770842e2132ffe3646fc5 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Tue, 15 Oct 2024 21:54:08 +0200 Subject: [PATCH 10/12] POV: return analog value the same as digital --- ddio/sdlcontroller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index b1ef0d4f0..efe5e754d 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -1402,6 +1402,7 @@ float sdlgameController::get_pov_value(int8_t controller, ct_format format, uint } break; + case ctAnalog: case ctDigital: { if (m_ExtCtlStates[m_ControlList[controller].id].pov[pov_number] == JOYPOV_CENTER) val = 0.0f; From f8a06f73122cc7721a58ffa280397952d20137a3 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Tue, 15 Oct 2024 22:03:09 +0200 Subject: [PATCH 11/12] Remove extra debug --- ddio/sdlcontroller.cpp | 3 --- lib/joystick.h | 1 - 2 files changed, 4 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index efe5e754d..e3c0f4ade 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -628,7 +628,6 @@ int sdlgameController::assign_function(ct_function *func) { elem.ctl[i] = 0; break; case ctAnalogTrigger: - std::cout << "test"; case ctAxis: elem.ctl[i] = get_axis_controller(func->value[i]); break; @@ -1364,8 +1363,6 @@ float sdlgameController::get_trigger_value(int8_t controller, uint8_t axis, ct_f LOG_WARNING << "unsupported format for function sdlgameController::get_trigger_value."; } - LOG_DEBUG << "Axis " << axis << " value is " << val << " raw " << axisval; - return val; } // do some pov stuff diff --git a/lib/joystick.h b/lib/joystick.h index e2558af68..fb87c7c37 100644 --- a/lib/joystick.h +++ b/lib/joystick.h @@ -66,7 +66,6 @@ #define JOYSTICK_H #include -#include // joystick ids. used to initialize a stick and get its position #define MAX_JOYSTICKS 8 From deb9749d1f467f2202603177cb91fb43a270859f Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Mon, 28 Oct 2024 21:39:54 +0100 Subject: [PATCH 12/12] Replace C 'fabs' by 'std::abs' --- ddio/sdlcontroller.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ddio/sdlcontroller.cpp b/ddio/sdlcontroller.cpp index e3c0f4ade..9baa5607d 100644 --- a/ddio/sdlcontroller.cpp +++ b/ddio/sdlcontroller.cpp @@ -335,34 +335,34 @@ ct_config_data sdlgameController::get_controller_value(ct_type type_req) { if (m_ControlList[i].flags & CTF_V_AXIS) { pos = get_axis_value(i, CT_V_AXIS, ctAnalog); - if (fabs(pos) >= 0.50f) + if (std::abs(pos) >= 0.50f) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_V_AXIS, NULL_BINDING)); } if (m_ControlList[i].flags & CTF_U_AXIS) { pos = get_axis_value(i, CT_U_AXIS, ctAnalog); - if (fabs(pos) >= 0.50f) + if (std::abs(pos) >= 0.50f) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_U_AXIS, NULL_BINDING)); } if (m_ControlList[i].flags & CTF_R_AXIS) { pos = get_axis_value(i, CT_R_AXIS, ctAnalog); - if (fabs(pos) >= 0.90f) + if (std::abs(pos) >= 0.90f) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_R_AXIS, NULL_BINDING)); } if (m_ControlList[i].flags & CTF_Z_AXIS) { pos = get_axis_value(i, CT_Z_AXIS, ctAnalog); - if (fabs(pos) >= 0.50f) + if (std::abs(pos) >= 0.50f) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_Z_AXIS, NULL_BINDING)); } if (m_ControlList[i].flags & CTF_Y_AXIS) { pos = get_axis_value(i, CT_Y_AXIS, ctAnalog); // mprintf(0, "y=%.2f ", pos); - if (fabs(pos) >= 0.90f) + if (std::abs(pos) >= 0.90f) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_Y_AXIS, NULL_BINDING)); } if (m_ControlList[i].flags & CTF_X_AXIS) { pos = get_axis_value(i, CT_X_AXIS, ctAnalog); // mprintf(0, "x=%.2f\n", pos); - if (fabs(pos) >= 0.90f) + if (std::abs(pos) >= 0.90f) val = MAKE_CONFIG_DATA(ctl, CONTROLLER_CTL_VALUE(CT_X_AXIS, NULL_BINDING)); } } break; @@ -417,7 +417,7 @@ void sdlgameController::get_controller_axis_value(int controllerId, unsigned int ? 0.80f : (m_ControlList[controllerId].sens[axis_ct_flag - 1] / 2); float pos = get_axis_value(controllerId, axis_ct_flag, ctAnalog); - if (fabs(pos) > limit) + if (std::abs(pos) > limit) *val = MAKE_CONFIG_DATA(CONTROLLER_CTL_INFO(controllerId, NULL_CONTROLLER), CONTROLLER_CTL_VALUE(axis_ct_flag, NULL_BINDING)); }