mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[input] Make a start on the new binding system
Input Mapping Tables are still at the core as they are a good concept, however they include both axis and button mappings, and the size is not hard-coded, but dependent on the known devices. Not much actually works yet (nq segfaults when a key is pressed).
This commit is contained in:
parent
14a5ec7b41
commit
825d8b7a49
14 changed files with 629 additions and 81 deletions
|
@ -114,6 +114,8 @@ include_qf_glsl = \
|
||||||
include_qf_input = \
|
include_qf_input = \
|
||||||
include/QF/binding.h \
|
include/QF/binding.h \
|
||||||
include/QF/event.h
|
include/QF/event.h
|
||||||
|
include/QF/imt.h
|
||||||
|
|
||||||
include_qf_math = \
|
include_qf_math = \
|
||||||
include/QF/math/dual.h \
|
include/QF/math/dual.h \
|
||||||
include/QF/math/half.h \
|
include/QF/math/half.h \
|
||||||
|
|
|
@ -45,6 +45,7 @@ typedef struct in_buttoninfo_s {
|
||||||
} in_buttoninfo_t;
|
} in_buttoninfo_t;
|
||||||
|
|
||||||
#include "QF/input/binding.h"
|
#include "QF/input/binding.h"
|
||||||
|
#include "QF/input/imt.h"
|
||||||
|
|
||||||
#ifndef __QFCC__
|
#ifndef __QFCC__
|
||||||
|
|
||||||
|
@ -104,15 +105,17 @@ typedef struct in_device_s {
|
||||||
\a button_info holds the current raw state of the button
|
\a button_info holds the current raw state of the button
|
||||||
|
|
||||||
\a axis_imt_id is 0 if the device has no axis bindings, otherwise it is
|
\a axis_imt_id is 0 if the device has no axis bindings, otherwise it is
|
||||||
the based index into the imt array for the imt group.
|
the index into the imt array for the imt group.
|
||||||
|
|
||||||
\a button_imt_i is 0 if the device has no button bindings, otherwise it
|
\a button_imt_id is 0 if the device has no button bindings, otherwise it
|
||||||
is the index into the imt array for the imt group.
|
is the index into the imt array for the imt group.
|
||||||
*/
|
*/
|
||||||
typedef struct in_devbindings_s {
|
typedef struct in_devbindings_s {
|
||||||
const char *name; ///< name used when binding inputs
|
const char *name; ///< name used when binding inputs
|
||||||
const char *id; ///< physical device name or id (preferred)
|
const char *id; ///< physical device name or id (preferred)
|
||||||
in_device_t *device; ///< device associated with these bindings
|
int devid; ///< id of device associated with these bindings
|
||||||
|
int num_axes;
|
||||||
|
int num_buttons;
|
||||||
in_axisinfo_t *axis_info; ///< axis range info and raw state
|
in_axisinfo_t *axis_info; ///< axis range info and raw state
|
||||||
in_buttoninfo_t *button_info; ///< button raw state
|
in_buttoninfo_t *button_info; ///< button raw state
|
||||||
int axis_imt_id; ///< index into array of imt axis bindings
|
int axis_imt_id; ///< index into array of imt axis bindings
|
||||||
|
|
|
@ -217,6 +217,8 @@ int IN_RegisterAxis (in_axis_t *axis, const char *name,
|
||||||
const char *description);
|
const char *description);
|
||||||
in_button_t *IN_FindButton (const char *name);
|
in_button_t *IN_FindButton (const char *name);
|
||||||
|
|
||||||
|
void IN_Binding_Init (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif//__QF_input_binding_h
|
#endif//__QF_input_binding_h
|
||||||
|
|
87
include/QF/input/imt.h
Normal file
87
include/QF/input/imt.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
imt.h
|
||||||
|
|
||||||
|
Input Mapping Table management
|
||||||
|
|
||||||
|
Copyright (C) 2001 Zephaniah E. Hull <warp@babylon.d2dc.net>
|
||||||
|
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __QF_input_imt_h
|
||||||
|
#define __QF_input_imt_h
|
||||||
|
|
||||||
|
#ifndef __QFCC__
|
||||||
|
|
||||||
|
#include "QF/darray.h"
|
||||||
|
|
||||||
|
#include "QF/input/binding.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
imt_button,
|
||||||
|
imt_axis,
|
||||||
|
} imt_type;
|
||||||
|
|
||||||
|
/** Describe a region of imt bindings (axis or button)
|
||||||
|
|
||||||
|
Each device may have a block of axis bindings and a block of button
|
||||||
|
bindings (some devices will have only the one block). The device name is
|
||||||
|
used instead of a pointer to the device descriptor so configs can be
|
||||||
|
preserved even if the device is not present.
|
||||||
|
|
||||||
|
Bindings are allocated to a device in contiguous blocks.
|
||||||
|
*/
|
||||||
|
typedef struct imt_block_s {
|
||||||
|
const char *device; ///< name of the owning device
|
||||||
|
int base; ///< index of first binding
|
||||||
|
int count; ///< number of bindings
|
||||||
|
} imt_block_t;
|
||||||
|
|
||||||
|
/** Input Mapping Table
|
||||||
|
*/
|
||||||
|
typedef struct imt_s {
|
||||||
|
struct imt_s *next; ///< list of tables attached to key_dest
|
||||||
|
struct imt_s *chain; ///< fallback table if input not bound
|
||||||
|
const char *name; ///< for user interaction
|
||||||
|
int written;
|
||||||
|
struct DARRAY_TYPE (in_axisbinding_t *) axis_bindings;
|
||||||
|
struct DARRAY_TYPE (in_buttonbinding_t *) button_bindings;
|
||||||
|
} imt_t;
|
||||||
|
|
||||||
|
typedef struct in_context_s {
|
||||||
|
imt_t *imts;
|
||||||
|
imt_t **imt_tail;
|
||||||
|
imt_t *active_imt;
|
||||||
|
imt_t *default_imt;
|
||||||
|
} in_context_t;
|
||||||
|
|
||||||
|
int IMT_GetAxisBlock (const char *device, int num_axes);
|
||||||
|
int IMT_GetButtonBlock (const char *device, int num_buttons);
|
||||||
|
int IMT_CreateContext (void);
|
||||||
|
imt_t *IMT_FindIMT (const char *name);
|
||||||
|
int IMT_CreateIMT (int context, const char *imt_name,
|
||||||
|
const char *chain_imt_name);
|
||||||
|
void IMT_ProcessAxis (int axis, int value);
|
||||||
|
void IMT_ProcessButton (int button, int state);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif//__QF_input_imt_h
|
|
@ -534,26 +534,12 @@ typedef enum {
|
||||||
#ifndef __QFCC__
|
#ifndef __QFCC__
|
||||||
extern knum_t key_toggleconsole;
|
extern knum_t key_toggleconsole;
|
||||||
|
|
||||||
typedef struct keybind_s {
|
|
||||||
char *str;
|
|
||||||
} keybind_t;
|
|
||||||
|
|
||||||
/** Input Mapping Table
|
|
||||||
*/
|
|
||||||
typedef struct imt_s {
|
|
||||||
struct imt_s *next; ///< list of tables attached to key_dest
|
|
||||||
struct imt_s *chain; ///< fallback table if key not bound
|
|
||||||
const char *name; ///< for user interaction
|
|
||||||
keybind_t bindings[QFK_LAST];
|
|
||||||
int written; ///< avoid duplicate config file writes
|
|
||||||
} imt_t;
|
|
||||||
|
|
||||||
/** Chain of input mapping tables ascociated with a keydest sub-system (game,
|
/** Chain of input mapping tables ascociated with a keydest sub-system (game,
|
||||||
menu, etc).
|
menu, etc).
|
||||||
*/
|
*/
|
||||||
typedef struct keytarget_s {
|
typedef struct keytarget_s {
|
||||||
imt_t *imts; ///< list of tables attached to this target
|
struct imt_s *imts; ///< list of tables attached to this target
|
||||||
imt_t *active; ///< currently active table in this target
|
struct imt_s *active; ///< currently active table in this target
|
||||||
} keytarget_t;
|
} keytarget_t;
|
||||||
|
|
||||||
extern int keydown[QFK_LAST];
|
extern int keydown[QFK_LAST];
|
||||||
|
@ -612,7 +598,7 @@ void Key_Init_Cvars (void);
|
||||||
\param imt_name The name of the imt to find. Case insensitive.
|
\param imt_name The name of the imt to find. Case insensitive.
|
||||||
\return The named imt, or null if not found.
|
\return The named imt, or null if not found.
|
||||||
*/
|
*/
|
||||||
imt_t *Key_FindIMT (const char *imt_name) __attribute__((pure));
|
struct imt_s *Key_FindIMT (const char *imt_name) __attribute__((pure));
|
||||||
|
|
||||||
/** Create a new imt and attach it to the specified keydest target.
|
/** Create a new imt and attach it to the specified keydest target.
|
||||||
|
|
||||||
|
@ -667,7 +653,7 @@ void Key_ClearStates (void);
|
||||||
\param key The key for which to get the binding.
|
\param key The key for which to get the binding.
|
||||||
\return The command string bound to the key, or null if unbound.
|
\return The command string bound to the key, or null if unbound.
|
||||||
*/
|
*/
|
||||||
const char *Key_GetBinding (imt_t *imt, knum_t key) __attribute__((pure));
|
const char *Key_GetBinding (struct imt_s *imt, knum_t key) __attribute__((pure));
|
||||||
|
|
||||||
/** Bind a command string to a key in the specified input mapping table.
|
/** Bind a command string to a key in the specified input mapping table.
|
||||||
|
|
||||||
|
@ -678,7 +664,7 @@ const char *Key_GetBinding (imt_t *imt, knum_t key) __attribute__((pure));
|
||||||
\param keynum The key to which the command string will be bound.
|
\param keynum The key to which the command string will be bound.
|
||||||
\param binding The command string that will be bound.
|
\param binding The command string that will be bound.
|
||||||
*/
|
*/
|
||||||
void Key_SetBinding (imt_t *imt, knum_t keynum, const char *binding);
|
void Key_SetBinding (struct imt_s *imt, knum_t keynum, const char *binding);
|
||||||
|
|
||||||
/** Set the current keydest target.
|
/** Set the current keydest target.
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#include "QF/cbuf.h"
|
#include "QF/cbuf.h"
|
||||||
#include "QF/cmd.h"
|
#include "QF/cmd.h"
|
||||||
#include "QF/keys.h"
|
#include "QF/input.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/gib.h"
|
#include "QF/gib.h"
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,11 @@ libs_input_libQFinput_la_SOURCES= \
|
||||||
libs/input/keys.c \
|
libs/input/keys.c \
|
||||||
libs/input/old_keys.c \
|
libs/input/old_keys.c \
|
||||||
libs/input/in_axis.c \
|
libs/input/in_axis.c \
|
||||||
|
libs/input/in_binding.c \
|
||||||
libs/input/in_button.c \
|
libs/input/in_button.c \
|
||||||
libs/input/in_common.c \
|
libs/input/in_common.c \
|
||||||
libs/input/in_event.c
|
libs/input/in_event.c \
|
||||||
|
libs/input/in_imt.c
|
||||||
|
|
||||||
EXTRA_LTLIBRARIES += \
|
EXTRA_LTLIBRARIES += \
|
||||||
libs/input/libinput_evdev.la
|
libs/input/libinput_evdev.la
|
||||||
|
|
154
libs/input/in_binding.c
Normal file
154
libs/input/in_binding.c
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
in_binding.c
|
||||||
|
|
||||||
|
Input binding management
|
||||||
|
|
||||||
|
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2021/11/2
|
||||||
|
|
||||||
|
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 <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "QF/cmd.h"
|
||||||
|
#include "QF/hash.h"
|
||||||
|
#include "QF/input.h"
|
||||||
|
#include "QF/sys.h"
|
||||||
|
|
||||||
|
#include "QF/input/imt.h"
|
||||||
|
|
||||||
|
#include "QF/input/binding.h"
|
||||||
|
#include "QF/input/event.h"
|
||||||
|
#include "QF/input/imt.h"
|
||||||
|
|
||||||
|
typedef struct DARRAY_TYPE (in_devbindings_t) in_devbindingset_t;
|
||||||
|
|
||||||
|
static in_devbindingset_t devbindings = DARRAY_STATIC_INIT (8);
|
||||||
|
|
||||||
|
static void
|
||||||
|
in_binding_add_device (const IE_event_t *ie_event)
|
||||||
|
{
|
||||||
|
size_t devid = ie_event->device.devid;
|
||||||
|
if (devid >= devbindings.size) {
|
||||||
|
DARRAY_RESIZE (&devbindings, devid + 1);
|
||||||
|
memset (&devbindings.a[devid], 0, sizeof (in_devbindings_t));
|
||||||
|
}
|
||||||
|
in_devbindings_t *db = &devbindings.a[devid];
|
||||||
|
if (db->id) {
|
||||||
|
if (db->id != IN_GetDeviceId (devid)) {
|
||||||
|
Sys_Error ("in_binding_add_device: devid conflict: %zd", devid);
|
||||||
|
}
|
||||||
|
Sys_Printf ("in_binding_add_device: readd %s\n", db->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
db->id = IN_GetDeviceId (devid);
|
||||||
|
db->devid = devid;
|
||||||
|
IN_AxisInfo (devid, 0, &db->num_axes);
|
||||||
|
IN_ButtonInfo (devid, 0, &db->num_buttons);
|
||||||
|
db->axis_info = malloc (db->num_axes * sizeof (in_axisinfo_t)
|
||||||
|
+ db->num_buttons * sizeof (in_buttoninfo_t));
|
||||||
|
db->button_info = (in_buttoninfo_t *) &db->axis_info[db->num_axes];
|
||||||
|
IN_AxisInfo (devid, db->axis_info, &db->num_axes);
|
||||||
|
IN_ButtonInfo (devid, db->button_info, &db->num_buttons);
|
||||||
|
Sys_Printf ("in_binding_add_device: %s %d %d\n", db->id, db->num_axes,
|
||||||
|
db->num_buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
in_binding_remove_device (const IE_event_t *ie_event)
|
||||||
|
{
|
||||||
|
size_t devid = ie_event->device.devid;
|
||||||
|
in_devbindings_t *db = &devbindings.a[devid];
|
||||||
|
|
||||||
|
if (devid >= devbindings.size) {
|
||||||
|
Sys_Error ("in_binding_remove_device: invalid devid: %zd", devid);
|
||||||
|
}
|
||||||
|
if (!db->id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free (db->axis_info); // axis and button info in same block
|
||||||
|
memset (db, 0, sizeof (*db));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
in_binding_axis (const IE_event_t *ie_event)
|
||||||
|
{
|
||||||
|
size_t devid = ie_event->axis.devid;
|
||||||
|
int axis = ie_event->axis.axis;
|
||||||
|
int value = ie_event->axis.value;
|
||||||
|
in_devbindings_t *db = &devbindings.a[devid];
|
||||||
|
|
||||||
|
if (devid < devbindings.size && axis < db->num_axes) {
|
||||||
|
db->axis_info[axis].value = value;
|
||||||
|
if (db->axis_imt_id) {
|
||||||
|
IMT_ProcessAxis (db->axis_imt_id + axis, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
in_binding_button (const IE_event_t *ie_event)
|
||||||
|
{
|
||||||
|
size_t devid = ie_event->button.devid;
|
||||||
|
int button = ie_event->button.button;
|
||||||
|
int state = ie_event->button.state;
|
||||||
|
in_devbindings_t *db = &devbindings.a[devid];
|
||||||
|
|
||||||
|
if (devid < devbindings.size && button < db->num_buttons) {
|
||||||
|
db->button_info[button].state = state;
|
||||||
|
if (db->button_imt_id) {
|
||||||
|
IMT_ProcessButton (db->button_imt_id + button, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
in_binding_event_handler (const IE_event_t *ie_event, void *unused)
|
||||||
|
{
|
||||||
|
static void (*handlers[]) (const IE_event_t *ie_event) = {
|
||||||
|
[ie_add_device] = in_binding_add_device,
|
||||||
|
[ie_remove_device] = in_binding_remove_device,
|
||||||
|
[ie_axis] = in_binding_axis,
|
||||||
|
[ie_button] = in_binding_button,
|
||||||
|
};
|
||||||
|
if (ie_event->type < 0 || ie_event->type > ie_button
|
||||||
|
|| !handlers[ie_event->type]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
handlers[ie_event->type] (ie_event);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IN_Binding_Init (void)
|
||||||
|
{
|
||||||
|
IE_Add_Handler (in_binding_event_handler, 0);
|
||||||
|
}
|
|
@ -102,7 +102,7 @@ IN_DriverData (int handle, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
in_add_device (int driver, in_device_t *device, const char *name,
|
in_add_device (int driver, void *device, const char *name,
|
||||||
const char *id)
|
const char *id)
|
||||||
{
|
{
|
||||||
size_t devid;
|
size_t devid;
|
||||||
|
@ -353,7 +353,8 @@ IN_Init (cbuf_t *cbuf)
|
||||||
in_regdriver_t *rd = &in_drivers.a[i];
|
in_regdriver_t *rd = &in_drivers.a[i];
|
||||||
rd->driver.init (rd->data);
|
rd->driver.init (rd->data);
|
||||||
}
|
}
|
||||||
Key_Init (cbuf);
|
IN_Binding_Init ();
|
||||||
|
//Key_Init (cbuf);
|
||||||
//JOY_Init ();
|
//JOY_Init ();
|
||||||
|
|
||||||
in_mouse_x = in_mouse_y = 0.0;
|
in_mouse_x = in_mouse_y = 0.0;
|
||||||
|
@ -362,7 +363,7 @@ IN_Init (cbuf_t *cbuf)
|
||||||
void
|
void
|
||||||
IN_Init_Cvars (void)
|
IN_Init_Cvars (void)
|
||||||
{
|
{
|
||||||
Key_Init_Cvars ();
|
//Key_Init_Cvars ();
|
||||||
//JOY_Init_Cvars ();
|
//JOY_Init_Cvars ();
|
||||||
in_grab = Cvar_Get ("in_grab", "0", CVAR_ARCHIVE, IN_UpdateGrab,
|
in_grab = Cvar_Get ("in_grab", "0", CVAR_ARCHIVE, IN_UpdateGrab,
|
||||||
"With this set to 1, quake will grab the mouse, "
|
"With this set to 1, quake will grab the mouse, "
|
||||||
|
@ -392,7 +393,7 @@ IN_ClearStates (void)
|
||||||
rd->driver.clear_states (rd->data);
|
rd->driver.clear_states (rd->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Key_ClearStates ();
|
//Key_ClearStates ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_EVDEV
|
#ifdef HAVE_EVDEV
|
||||||
|
|
|
@ -58,11 +58,6 @@ static int evdev_driver_handle = -1;
|
||||||
static PR_RESMAP (devmap_t) devmap;
|
static PR_RESMAP (devmap_t) devmap;
|
||||||
static devmap_t *devmap_list;
|
static devmap_t *devmap_list;
|
||||||
|
|
||||||
static void
|
|
||||||
in_evdev_keydest_callback (keydest_t key_dest, void *data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
in_evdev_add_select (qf_fd_set *fdset, int *maxfd, void *data)
|
in_evdev_add_select (qf_fd_set *fdset, int *maxfd, void *data)
|
||||||
{
|
{
|
||||||
|
@ -179,8 +174,6 @@ device_remove (device_t *dev)
|
||||||
static void
|
static void
|
||||||
in_evdev_init (void *data)
|
in_evdev_init (void *data)
|
||||||
{
|
{
|
||||||
Key_KeydestCallback (in_evdev_keydest_callback, 0);
|
|
||||||
|
|
||||||
inputlib_init (device_add, device_remove);
|
inputlib_init (device_add, device_remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
238
libs/input/in_imt.c
Normal file
238
libs/input/in_imt.c
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
in_imt.c
|
||||||
|
|
||||||
|
Input Mapping Table management
|
||||||
|
|
||||||
|
Copyright (C) 1996-1997 Id Software, Inc.
|
||||||
|
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2021/10/30
|
||||||
|
|
||||||
|
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 <string.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "QF/cmd.h"
|
||||||
|
#include "QF/hash.h"
|
||||||
|
#include "QF/sys.h"
|
||||||
|
|
||||||
|
#include "QF/input/imt.h"
|
||||||
|
|
||||||
|
#include "QF/input/binding.h"
|
||||||
|
#include "QF/input/imt.h"
|
||||||
|
|
||||||
|
typedef struct DARRAY_TYPE (in_context_t) in_contextset_t;
|
||||||
|
typedef struct DARRAY_TYPE (imt_block_t) imt_blockset_t;
|
||||||
|
/** Binding blocks are allocated across all imts
|
||||||
|
*/
|
||||||
|
static imt_blockset_t axis_blocks = DARRAY_STATIC_INIT (8);
|
||||||
|
static imt_blockset_t button_blocks = DARRAY_STATIC_INIT (8);
|
||||||
|
|
||||||
|
static in_contextset_t in_contexts = DARRAY_STATIC_INIT (8);
|
||||||
|
|
||||||
|
static imt_block_t * __attribute__((pure))
|
||||||
|
imt_find_block (imt_blockset_t *blockset, const char *device)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < blockset->size; i++) {
|
||||||
|
if (strcmp (blockset->a[i].device, device) == 0) {
|
||||||
|
return &blockset->a[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static imt_block_t *
|
||||||
|
imt_get_block (imt_blockset_t *blockset)
|
||||||
|
{
|
||||||
|
return DARRAY_OPEN_AT (blockset, blockset->size, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
imt_get_next_base (imt_blockset_t *blockset)
|
||||||
|
{
|
||||||
|
if (!blockset->size) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
imt_block_t *b = &blockset->a[blockset->size - 1];
|
||||||
|
return b->base + b->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
imt_get_axis_block (int count)
|
||||||
|
{
|
||||||
|
int base = imt_get_next_base (&axis_blocks);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < in_contexts.size; i++) {
|
||||||
|
for (imt_t *imt = in_contexts.a[i].imts; imt; imt = imt->next) {
|
||||||
|
in_axisbinding_t **binding;
|
||||||
|
binding = DARRAY_OPEN_AT (&imt->axis_bindings, base, count);
|
||||||
|
memset (binding, 0, count * sizeof (binding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
imt_get_button_block (int count)
|
||||||
|
{
|
||||||
|
int base = imt_get_next_base (&button_blocks);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < in_contexts.size; i++) {
|
||||||
|
for (imt_t *imt = in_contexts.a[i].imts; imt; imt = imt->next) {
|
||||||
|
in_buttonbinding_t **binding;
|
||||||
|
binding = DARRAY_OPEN_AT (&imt->button_bindings, base, count);
|
||||||
|
memset (binding, 0, count * sizeof (binding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IMT_GetAxisBlock (const char *device, int num_axes)
|
||||||
|
{
|
||||||
|
imt_block_t *block;
|
||||||
|
if (!(block = imt_find_block (&axis_blocks, device))) {
|
||||||
|
block = imt_get_block (&axis_blocks);
|
||||||
|
block->device = device;
|
||||||
|
block->base = imt_get_axis_block (num_axes);
|
||||||
|
block->count = num_axes;
|
||||||
|
}
|
||||||
|
return block - axis_blocks.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IMT_GetButtonBlock (const char *device, int num_buttons)
|
||||||
|
{
|
||||||
|
imt_block_t *block;
|
||||||
|
if (!(block = imt_find_block (&button_blocks, device))) {
|
||||||
|
block = imt_get_block (&button_blocks);
|
||||||
|
block->device = device;
|
||||||
|
block->base = imt_get_button_block (num_buttons);
|
||||||
|
block->count = num_buttons;
|
||||||
|
}
|
||||||
|
return block - button_blocks.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IMT_CreateContext (void)
|
||||||
|
{
|
||||||
|
in_context_t *ctx = DARRAY_OPEN_AT (&in_contexts, in_contexts.size, 1);
|
||||||
|
memset (ctx, 0, sizeof (*ctx));
|
||||||
|
ctx->imt_tail = &ctx->imts;
|
||||||
|
return ctx - in_contexts.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static imt_t * __attribute__ ((pure))
|
||||||
|
imt_find_imt (in_context_t *ctx, const char *name)
|
||||||
|
{
|
||||||
|
for (imt_t *imt = ctx->imts; imt; imt = imt->next) {
|
||||||
|
if (strcasecmp (imt->name, name) == 0) {
|
||||||
|
return imt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
imt_t * __attribute__ ((pure))
|
||||||
|
IMT_FindIMT (const char *name)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < in_contexts.size; i++) {
|
||||||
|
in_context_t *ctx = &in_contexts.a[i];
|
||||||
|
imt_t *imt = imt_find_imt (ctx, name);
|
||||||
|
if (imt) {
|
||||||
|
return imt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
IMT_CreateIMT (int context, const char *imt_name, const char *chain_imt_name)
|
||||||
|
{
|
||||||
|
in_context_t *ctx = &in_contexts.a[context];
|
||||||
|
imt_t *imt;
|
||||||
|
imt_t *chain_imt = 0;
|
||||||
|
|
||||||
|
if ((size_t) context >= in_contexts.size) {
|
||||||
|
Sys_Printf ("invalid imt context %d\n", context);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IMT_FindIMT (imt_name)) {
|
||||||
|
Sys_Printf ("imt %s already exists\n", imt_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (chain_imt_name) {
|
||||||
|
chain_imt = IMT_FindIMT (chain_imt_name);
|
||||||
|
if (!chain_imt) {
|
||||||
|
Sys_Printf ("chain imt %s does not exist\n", chain_imt_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
chain_imt = imt_find_imt (ctx, chain_imt_name);
|
||||||
|
if (!chain_imt) {
|
||||||
|
Sys_Printf ("chain imt %s not in target context\n",
|
||||||
|
chain_imt_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imt = malloc (sizeof (imt_t));
|
||||||
|
*ctx->imt_tail = imt;
|
||||||
|
ctx->imt_tail = &imt->next;
|
||||||
|
|
||||||
|
imt->next = 0;
|
||||||
|
imt->chain = chain_imt;
|
||||||
|
imt->name = strdup (imt_name);
|
||||||
|
imt->written = 0;
|
||||||
|
DARRAY_INIT (&imt->axis_bindings, 8);
|
||||||
|
DARRAY_INIT (&imt->button_bindings, 8);
|
||||||
|
int num_axes = imt_get_next_base (&axis_blocks);
|
||||||
|
int num_buttons = imt_get_next_base (&button_blocks);
|
||||||
|
DARRAY_RESIZE (&imt->axis_bindings, num_axes);
|
||||||
|
DARRAY_RESIZE (&imt->button_bindings, num_buttons);
|
||||||
|
if (num_axes) {
|
||||||
|
memset (imt->axis_bindings.a, 0,
|
||||||
|
num_axes * sizeof (in_axisbinding_t *));
|
||||||
|
}
|
||||||
|
if (num_buttons) {
|
||||||
|
memset (imt->axis_bindings.a, 0,
|
||||||
|
num_buttons * sizeof (in_buttonbinding_t *));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IMT_ProcessAxis (int axis, int value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IMT_ProcessButton (int button, int state)
|
||||||
|
{
|
||||||
|
}
|
|
@ -41,15 +41,44 @@
|
||||||
|
|
||||||
#include "QF/cbuf.h"
|
#include "QF/cbuf.h"
|
||||||
#include "QF/cmd.h"
|
#include "QF/cmd.h"
|
||||||
|
#include "QF/cmem.h"
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/darray.h"
|
#include "QF/darray.h"
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
#include "QF/keys.h"
|
#include "QF/keys.h"
|
||||||
|
#include "QF/input.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
|
#include "QF/va.h"
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "old_keys.h"
|
#include "old_keys.h"
|
||||||
|
|
||||||
|
static memsuper_t *binding_mem;
|
||||||
|
/*
|
||||||
|
static in_axisbinding_t *
|
||||||
|
alloc_axis_binding (void)
|
||||||
|
{
|
||||||
|
return cmemalloc (binding_mem, sizeof (in_axisbinding_t));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
free_axis_binding (in_axisbinding_t *binding)
|
||||||
|
{
|
||||||
|
cmemfree (binding_mem, binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static in_buttonbinding_t *
|
||||||
|
alloc_button_binding (void)
|
||||||
|
{
|
||||||
|
return cmemalloc (binding_mem, sizeof (in_buttonbinding_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_button_binding (in_buttonbinding_t *binding)
|
||||||
|
{
|
||||||
|
cmemfree (binding_mem, binding);
|
||||||
|
}
|
||||||
|
|
||||||
/* key up events are sent even if in console mode */
|
/* key up events are sent even if in console mode */
|
||||||
|
|
||||||
static keydest_t key_dest = key_console;
|
static keydest_t key_dest = key_console;
|
||||||
|
@ -90,12 +119,6 @@ static const char *keydest_names[] = {
|
||||||
"key_last"
|
"key_last"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *name;
|
|
||||||
imt_t imtnum;
|
|
||||||
} imtname_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
knum_t keynum;
|
knum_t keynum;
|
||||||
|
@ -615,12 +638,25 @@ Key_SetBinding (imt_t *imt, knum_t keynum, const char *binding)
|
||||||
if (keynum == (knum_t) -1)
|
if (keynum == (knum_t) -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (imt->bindings[keynum].str) {
|
if (imt->button_bindings.a[keynum]) {
|
||||||
free (imt->bindings[keynum].str);
|
if (imt->button_bindings.a[keynum]->type == inb_command) {
|
||||||
imt->bindings[keynum].str = NULL;
|
free (imt->button_bindings.a[keynum]->command);
|
||||||
|
}
|
||||||
|
free_button_binding (imt->button_bindings.a[keynum]);
|
||||||
|
imt->button_bindings.a[keynum] = 0;
|
||||||
}
|
}
|
||||||
if (binding) {
|
if (binding) {
|
||||||
imt->bindings[keynum].str = strdup(binding);
|
in_buttonbinding_t *b = alloc_button_binding ();
|
||||||
|
imt->button_bindings.a[keynum] = b;
|
||||||
|
in_button_t *button;
|
||||||
|
if (binding[0] == '+' && (button = IN_FindButton (binding + 1))) {
|
||||||
|
b->type = inb_button;
|
||||||
|
b->bind_id = keynum; //FIXME alloc?
|
||||||
|
b->button = button;
|
||||||
|
} else {
|
||||||
|
b->type = inb_command;
|
||||||
|
b->command = strdup(binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,14 +695,23 @@ process_binding (knum_t key, const char *kb)
|
||||||
static qboolean
|
static qboolean
|
||||||
Key_Game (knum_t key, short unicode)
|
Key_Game (knum_t key, short unicode)
|
||||||
{
|
{
|
||||||
const char *kb;
|
|
||||||
imt_t *imt = key_targets[key_dest].active;
|
imt_t *imt = key_targets[key_dest].active;
|
||||||
|
|
||||||
while (imt) {
|
while (imt) {
|
||||||
kb = imt->bindings[key].str;
|
in_buttonbinding_t *b = imt->button_bindings.a[key];
|
||||||
if (kb) {
|
if (b) {
|
||||||
if (keydown[key] <= 1)
|
switch (b->type) {
|
||||||
process_binding (key, kb);
|
case inb_button:
|
||||||
|
if (keydown[key] <= 1) {
|
||||||
|
IN_ButtonAction (b->button, key, keydown[key]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case inb_command:
|
||||||
|
if (keydown[key] <= 1) {
|
||||||
|
process_binding (key, b->command);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
imt = imt->chain;
|
imt = imt->chain;
|
||||||
|
@ -830,9 +875,20 @@ Key_IMT_Drop_All_f (void)
|
||||||
while (key_targets[kd].imts) {
|
while (key_targets[kd].imts) {
|
||||||
imt = key_targets[kd].imts;
|
imt = key_targets[kd].imts;
|
||||||
key_targets[kd].imts = imt->next;
|
key_targets[kd].imts = imt->next;
|
||||||
for (int i = 0; i < QFK_LAST; i++) {
|
for (size_t i = 0; i < imt->axis_bindings.size; i++) {
|
||||||
if (imt->bindings[i].str) {
|
free_axis_binding (imt->axis_bindings.a[i]);
|
||||||
free (imt->bindings[i].str);
|
}
|
||||||
|
for (size_t i = 0; i < imt->button_bindings.size; i++) {
|
||||||
|
in_buttonbinding_t *b = imt->button_bindings.a[i];
|
||||||
|
if (b) {
|
||||||
|
switch (b->type) {
|
||||||
|
case inb_button:
|
||||||
|
break;
|
||||||
|
case inb_command:
|
||||||
|
free (b->command);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free_button_binding (b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free ((char *) imt->name);
|
free ((char *) imt->name);
|
||||||
|
@ -843,7 +899,7 @@ Key_IMT_Drop_All_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Key_In_Bind (const char *imt_name, const char *key_name, const char *cmd)
|
Key_In_BindButton (const char *imt_name, const char *key_name, const char *cmd)
|
||||||
{
|
{
|
||||||
imt_t *imt;
|
imt_t *imt;
|
||||||
int key;
|
int key;
|
||||||
|
@ -861,11 +917,21 @@ Key_In_Bind (const char *imt_name, const char *key_name, const char *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
if (imt->bindings[key].str)
|
in_buttonbinding_t *b = imt->button_bindings.a[key];
|
||||||
Sys_Printf ("%s %s \"%s\"\n", imt_name, key_name,
|
if (b) {
|
||||||
imt->bindings[key].str);
|
switch (b->type) {
|
||||||
else
|
case inb_button:
|
||||||
|
Sys_Printf ("%s %s \"+%s\"\n", imt_name, key_name,
|
||||||
|
b->button->name);
|
||||||
|
break;
|
||||||
|
case inb_command:
|
||||||
|
Sys_Printf ("%s %s \"%s\"\n", imt_name, key_name,
|
||||||
|
b->command);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Sys_Printf ("%s %s is not bound\n", imt_name, key_name);
|
Sys_Printf ("%s %s is not bound\n", imt_name, key_name);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Key_SetBinding (imt, key, cmd);
|
Key_SetBinding (imt, key, cmd);
|
||||||
|
@ -880,25 +946,25 @@ Key_In_Bind_f (void)
|
||||||
|
|
||||||
c = Cmd_Argc ();
|
c = Cmd_Argc ();
|
||||||
|
|
||||||
if (c < 3) {
|
if (c < 4 || strcmp (Cmd_Argv (2), "button") != 0) {
|
||||||
Sys_Printf ("in_bind <imt> <key> [command] : attach a command to a "
|
Sys_Printf ("in_bind <imt> button <key> [command]\n"
|
||||||
"key\n");
|
" attach a command to a key\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
imt = Cmd_Argv (1);
|
imt = Cmd_Argv (1);
|
||||||
|
|
||||||
key = Cmd_Argv (2);
|
key = Cmd_Argv (3);
|
||||||
|
|
||||||
if (c >= 4) {
|
if (c >= 5) {
|
||||||
cmd_buf = dstring_newstr ();
|
cmd_buf = dstring_newstr ();
|
||||||
for (i = 3; i < c; i++) {
|
for (i = 4; i < c; i++) {
|
||||||
dasprintf (cmd_buf, "%s%s", i > 3 ? " " : "", Cmd_Argv (i));
|
dasprintf (cmd_buf, "%s%s", i > 3 ? " " : "", Cmd_Argv (i));
|
||||||
}
|
}
|
||||||
cmd = cmd_buf->str;
|
cmd = cmd_buf->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key_In_Bind (imt, key, cmd);
|
Key_In_BindButton (imt, key, cmd);
|
||||||
if (cmd_buf) {
|
if (cmd_buf) {
|
||||||
dstring_delete (cmd_buf);
|
dstring_delete (cmd_buf);
|
||||||
}
|
}
|
||||||
|
@ -941,7 +1007,7 @@ Key_Bind_f (void)
|
||||||
cmd = cmd_buf->str;
|
cmd = cmd_buf->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key_In_Bind ("imt_mod", key, cmd);
|
Key_In_BindButton ("imt_mod", key, cmd);
|
||||||
if (cmd_buf) {
|
if (cmd_buf) {
|
||||||
dstring_delete (cmd_buf);
|
dstring_delete (cmd_buf);
|
||||||
}
|
}
|
||||||
|
@ -1054,9 +1120,6 @@ key_printf (QFile *f, const char *fmt, ...)
|
||||||
static void
|
static void
|
||||||
key_write_imt (QFile *f, keydest_t kd, imt_t *imt)
|
key_write_imt (QFile *f, keydest_t kd, imt_t *imt)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
const char *bind;
|
|
||||||
|
|
||||||
if (!imt || imt->written) {
|
if (!imt || imt->written) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1068,11 +1131,19 @@ key_write_imt (QFile *f, keydest_t kd, imt_t *imt)
|
||||||
} else {
|
} else {
|
||||||
key_printf (f, "imt_create %s %s\n", keydest_names[kd], imt->name);
|
key_printf (f, "imt_create %s %s\n", keydest_names[kd], imt->name);
|
||||||
}
|
}
|
||||||
for (i = 0; i < QFK_LAST; i++) {
|
for (size_t i = 0; i < imt->button_bindings.size; i++) {
|
||||||
bind = imt->bindings[i].str;
|
in_buttonbinding_t *b = imt->button_bindings.a[i];
|
||||||
if (bind) {
|
if (b) {
|
||||||
key_printf (f, "in_bind %s %s \"%s\"\n", imt->name,
|
switch (b->type) {
|
||||||
Key_KeynumToString (i), bind);
|
case inb_button:
|
||||||
|
key_printf (f, "in_bind %s button %s \"+%s\"\n", imt->name,
|
||||||
|
Key_KeynumToString (i), b->button->name);
|
||||||
|
break;
|
||||||
|
case inb_command:
|
||||||
|
key_printf (f, "in_bind %s button %s \"%s\"\n", imt->name,
|
||||||
|
Key_KeynumToString (i), b->command);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1161,7 +1232,7 @@ Key_Event (knum_t key, short unicode, qboolean down)
|
||||||
//FIXME maybe still a tad over-coupled. Use callbacks for menu and console
|
//FIXME maybe still a tad over-coupled. Use callbacks for menu and console
|
||||||
//toggles? Should keys know anything about menu and console?
|
//toggles? Should keys know anything about menu and console?
|
||||||
if (key_dest != key_console && key == key_toggleconsole
|
if (key_dest != key_console && key == key_toggleconsole
|
||||||
&& keydown[key] == 1) {
|
&& keydown[key] == 1) {
|
||||||
Cbuf_AddText (cbuf, "toggleconsole");
|
Cbuf_AddText (cbuf, "toggleconsole");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1258,8 +1329,8 @@ Key_CreateDefaultIMTs (void)
|
||||||
default_imts[i].chain_imt_name);
|
default_imts[i].chain_imt_name);
|
||||||
}
|
}
|
||||||
for (i = 0; default_bindings[i].imt; i++) {
|
for (i = 0; default_bindings[i].imt; i++) {
|
||||||
Key_In_Bind (default_bindings[i].imt, default_bindings[i].key,
|
Key_In_BindButton (default_bindings[i].imt, default_bindings[i].key,
|
||||||
default_bindings[i].command);
|
default_bindings[i].command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1320,7 +1391,15 @@ const char *
|
||||||
Key_GetBinding (imt_t *imt, knum_t key)
|
Key_GetBinding (imt_t *imt, knum_t key)
|
||||||
{
|
{
|
||||||
if (imt) {
|
if (imt) {
|
||||||
return imt->bindings[key].str;
|
in_buttonbinding_t *b = imt->button_bindings.a[key];
|
||||||
|
if (b) {
|
||||||
|
switch (b->type) {
|
||||||
|
case inb_button:
|
||||||
|
return va (0, "+%s", b->button->name);
|
||||||
|
case inb_command:
|
||||||
|
return b->command;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "QF/csqc.h"
|
#include "QF/csqc.h"
|
||||||
#include "QF/keys.h"
|
#include "QF/input.h"
|
||||||
#include "QF/progs.h"
|
#include "QF/progs.h"
|
||||||
#include "QF/zone.h"
|
#include "QF/zone.h"
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ bi_Key_LookupBinding (progs_t *pr)
|
||||||
imt = Key_FindIMT (imt_name);
|
imt = Key_FindIMT (imt_name);
|
||||||
if (imt) {
|
if (imt) {
|
||||||
for (i = 0; i < QFK_LAST; i++) {
|
for (i = 0; i < QFK_LAST; i++) {
|
||||||
keybind = imt->bindings[i].str;
|
//XXX keybind = imt->button_bindings.a[i].str;
|
||||||
if (keybind == NULL) {
|
if (keybind == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ bi_Key_CountBinding (progs_t *pr)
|
||||||
imt = Key_FindIMT (imt_name);
|
imt = Key_FindIMT (imt_name);
|
||||||
if (imt) {
|
if (imt) {
|
||||||
for (i = 0; i < QFK_LAST; i++) {
|
for (i = 0; i < QFK_LAST; i++) {
|
||||||
keybind = imt->bindings[i].str;
|
//XXX keybind = imt->button_bindings.a[i].str;
|
||||||
if (keybind == NULL) {
|
if (keybind == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -563,6 +563,7 @@ static void
|
||||||
qwaq_input_init (qwaq_input_resources_t *res)
|
qwaq_input_init (qwaq_input_resources_t *res)
|
||||||
{
|
{
|
||||||
res->input_event_handler = IE_Add_Handler (qwaq_input_event_handler, res);
|
res->input_event_handler = IE_Add_Handler (qwaq_input_event_handler, res);
|
||||||
|
IE_Set_Focus (res->input_event_handler);
|
||||||
IN_DriverData (term_driver_handle, res);
|
IN_DriverData (term_driver_handle, res);
|
||||||
|
|
||||||
if (res->key_sequences) {
|
if (res->key_sequences) {
|
||||||
|
|
Loading…
Reference in a new issue