diff --git a/include/QF/input.h b/include/QF/input.h index c46819981..71f4eac02 100644 --- a/include/QF/input.h +++ b/include/QF/input.h @@ -80,7 +80,41 @@ typedef struct in_device_s { const char *id; } in_device_t; -/*** Current state of the button. +/*** Recipe for converting an axis to a floating point value. + + Recipes apply only to absolute axes. + + \a deadzone applies only to balanced axes, thus it doubles as a flag + for balanced (>= 0) or unbalanced (< 0). + + \a curve is applied after the input has been converted +*/ +typedef struct in_recipe_s { + int minzone; ///< Size of deadzone near axis minimum + int maxzone; ///< Size of deadzone near axis maximum + int deadzone; ///< Size of deadzone near axis center (balanced) + float curve; ///< Power factor for absolute axes +} in_recipe_t; + +typedef enum { + ina_set, ///< write the axis value to the destination + ina_accumulate, ///< add the axis value to the destination +} in_axis_mode; + +/*** Logical axis. + + Logical axes are the inputs defined by the game on which axis inputs + (usually "physical" axes) can act. Depending on the mode, the physical + axis value is either written as-is, or added to the existing value. It is + the responsibility of the code using the axis to clear the value for + accumulated inputs. +*/ +typedef struct in_axis_s { + float value; ///< converted value of the axis + in_axis_mode mode; ///< method used for updating the destination +} in_axis_t; + +/*** Current state of the logical button. Captures the current state and any transitions during the last frame. Not all combinations are valid (inb_edge_up|inb_down and inb_edge_down @@ -94,6 +128,14 @@ typedef enum { inb_edge_up = 1<<2, ///< button released this frame } in_button_state; +/*** Logical button. + + Logical buttons are the inputs defined by the game on which button inputs + (usually "physical" buttons) can act. Up to two button inputs can be + bound to a logical button. The logical button acts as an or gate where + either input will put the logical button in the pressed state, and both + inputs must be inactive for the logical button to be released. +*/ typedef struct in_button_s { int down[2]; ///< button ids holding this button down int state; ///< in_button_state @@ -222,6 +264,8 @@ void IN_ClearStates (void); int IN_RegisterButton (in_button_t *button, const char *name, const char *description); +int IN_RegisterAxis (in_axis_t *axis, const char *name, + const char *description); void IN_Move (void); // FIXME: was cmduser_t? // add additional movement on top of the keyboard move cmd diff --git a/libs/input/Makemodule.am b/libs/input/Makemodule.am index e160f456f..7f9bdfff2 100644 --- a/libs/input/Makemodule.am +++ b/libs/input/Makemodule.am @@ -20,6 +20,7 @@ libs_input_libQFinput_la_DEPENDENCIES= $(input_deps) libs_input_libQFinput_la_SOURCES= \ libs/input/keys.c \ libs/input/old_keys.c \ + libs/input/in_axis.c \ libs/input/in_button.c \ libs/input/in_common.c \ libs/input/in_event.c diff --git a/libs/input/in_axis.c b/libs/input/in_axis.c new file mode 100644 index 000000000..b9e980fda --- /dev/null +++ b/libs/input/in_axis.c @@ -0,0 +1,85 @@ +/* + in_axis.c + + Logical axis support + + Copyright (C) 2021 Bill Currie + + Author: Bill Currie + Date: 2021/10/1 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/cmd.h" +#include "QF/hash.h" +#include "QF/input.h" +#include "QF/sys.h" + +typedef struct regaxis_s { + const char *name; + const char *description; + in_axis_t *axis; +} regaxis_t; + +static hashtab_t *axis_tab; + +static const char * +axis_get_key (const void *b, void *data) +{ + __auto_type regaxis = (const regaxis_t *) b; + return regaxis->name; +} + +static void +axis_free (void *b, void *data) +{ + free (b); +} + +VISIBLE int +IN_RegisterAxis (in_axis_t *axis, const char *name, const char *description) +{ + if (Hash_Find (axis_tab, name)) { + return 0; + } + regaxis_t *regaxis = malloc (sizeof (regaxis_t)); + regaxis->name = name; + regaxis->description = description; + regaxis->axis = axis; + + return 1; +} + +static void __attribute__((constructor)) +in_axis_init (void) +{ + axis_tab = Hash_NewTable (127, axis_get_key, axis_free, 0, 0); +}