Generate kconfig udlr relations at build time

This commit is contained in:
Kp 2017-12-24 00:28:35 +00:00
parent 0106833538
commit f73b783095
4 changed files with 554 additions and 260 deletions

View file

@ -2558,8 +2558,14 @@ class cached_property(object):
return r
class LazyObjectConstructor(object):
def __get_wrapped_object(s,self,env,StaticObject):
wrapper = s.get('transform_object', None)
if wrapper is None:
return StaticObject
return wrapper(self, env, StaticObject)
def __lazy_objects(self,source,
cache={},
__get_wrapped_object=__get_wrapped_object,
__strip_extension=lambda _, name, _splitext=os.path.splitext: _splitext(name)[0]
):
env = self.env
@ -2574,7 +2580,7 @@ class LazyObjectConstructor(object):
# Convert to a tuple so that attempting to modify a cached
# result raises an error.
value = tuple([
StaticObject(target='%s%s%s' % (builddir, transform_target(self, srcname), OBJSUFFIX), source=srcname,
wrapped_StaticObject(target='%s%s%s' % (builddir, transform_target(self, srcname), OBJSUFFIX), source=srcname,
**({} if transform_env is None else transform_env(self, env))
) \
for s in source \
@ -2583,16 +2589,18 @@ class LazyObjectConstructor(object):
# normal comprehension. It iterates over one of two
# single element tuples. The choice of tuple is
# controlled by the isinstance check. Each single
# element tuple consists of (F, T, L) where F is the
# element tuple consists of (F, T, O, L) where F is the
# function to bind as `transform_target`, T is the
# function to bind as `transform_env` (or None), and L
# function to bind as `transform_env` (or None), O is
# the function to create the StaticObject, and L
# is an iterable to bind as `t`.
for transform_target, transform_env, t in ( \
((__strip_extension, None, (s,)),) \
for transform_target, transform_env, wrapped_StaticObject, t in ( \
((__strip_extension, None, StaticObject, (s,)),) \
if isinstance(s, str) \
else (( \
s.get('transform_target', __strip_extension), \
s.get('transform_env', None), \
__get_wrapped_object(s, self, env, StaticObject), \
s['source'], \
),) \
) \
@ -4107,6 +4115,25 @@ class DXXArchive(DXXCommon):
env.MergeFlags(add_flags)
class DXXProgram(DXXCommon):
class WrapKConfigStaticObject:
def __init__(self,program,env,StaticObject):
self.program = program
self.env = env
self.StaticObject = StaticObject
def __call__(self,target,source,*args,**kwargs):
env = self.env
kconfig_static_object = self.StaticObject(target=target, source=source, *args, **kwargs)
program = self.program
builddir = '%s%s' % (program.user_settings.builddir, program.target)
# Bypass ccache, if any, since this is a preprocess only
# call.
kwargs['CXXFLAGS'] = (kwargs.get('CXXFLAGS', None) or env['CXXFLAGS'] or []) + ['-E']
cpp_kconfig_udlr = self.StaticObject(target=target[:-1] + 'ui-table.i', source=source[:-3] + 'ui-table.cpp', CXXCOM=env._dxx_cxxcom_no_ccache_prefix, *args, **kwargs)
generated_udlr_header = env.File('%s/kconfig.udlr.h' % builddir)
generate_kconfig_udlr = env.File('similar/main/generate-kconfig-udlr.py')
env.Command(generated_udlr_header, [cpp_kconfig_udlr, generate_kconfig_udlr], [[sys.executable, generate_kconfig_udlr, '$SOURCE', '$TARGET']])
env.Depends(kconfig_static_object, generated_udlr_header)
return kconfig_static_object
static_archive_construction = {}
def _apply_target_name(self,name):
return os.path.join(os.path.dirname(name), '.%s.%s' % (self.target, os.path.splitext(os.path.basename(name))[0]))
@ -4172,7 +4199,6 @@ class DXXProgram(DXXCommon):
'main/hostage.cpp',
'main/hud.cpp',
'main/iff.cpp',
'main/kconfig.cpp',
'main/kmatrix.cpp',
'main/laser.cpp',
'main/lighting.cpp',
@ -4218,6 +4244,12 @@ class DXXProgram(DXXCommon):
'transform_target':_apply_target_name,
}, {
'source': (
'similar/main/kconfig.cpp',
),
'transform_object':WrapKConfigStaticObject,
'transform_target':_apply_target_name,
}, {
'source': (
'similar/misc/physfsx.cpp',
),
'transform_env': lambda self, env: {'CPPDEFINES' : env['CPPDEFINES'] + env.__dxx_CPPDEFINE_SHAREPATH},

View file

@ -0,0 +1,299 @@
#!/usr/bin/python
import ast, os, re, sys
# Storage for the relevant fields from an initializer for a single
# element of a kc_item array. Fields not required for sorting or
# generating the output header are not captured or saved.
class ArrayInitializationLine:
def __init__(self,xinput,y,name,idx):
# xinput, y are fields in the kc_item structure
self.xinput = xinput
self.y = y
# name is the token that will be preprocessor-defined to the
# appropriate udlr values
self.name = name
# index in the kc_item array at which this initializer was found
self.idx = idx
# For horizontal sorting, group elements by their vertical
# coordinate, then break ties using the horizontal coordinate. This
# causes elements from a single row to be contiguous in the sorted
# output, and places visually adjacent rows adjacent in the sorted
# output.
def key_horizontal(self):
return (self.y, self.xinput)
# For vertical sorting, group elements by their horizontal
# coordinate, then break ties using the vertical coordinate.
def key_vertical(self):
return (self.xinput, self.y)
# InputException is raised when the post-processed C++ table cannot be
# parsed using the regular expressions in this script. The table may or
# may not be valid C++ when this script rejects it.
class InputException(Exception):
pass
# NodeVisitor handles walking a Python Abstract Syntax Tree (AST) to
# emulate a few supported operations, and raise an error on anything
# unsupported. This is used to implement primitive support for
# evaluating arithmetic expressions in the table. This support covers
# only what is likely to be used and assumes Python syntax (which should
# usually match C++ syntax closely enough, for the limited forms
# supported).
class NodeVisitor(ast.NodeVisitor):
def __init__(self,source,lno,name,expr,constants):
self.source = source
self.lno = lno
self.name = name
self.expr = expr
self.constants = constants
def generic_visit(self,node):
raise InputException('%s:%u: %r expression %r uses unsupported node type %s' % (self.source, self.lno, self.name, self.expr, node.__class__.__name__))
def visit_BinOp(self,node):
left = self.visit(node.left)
right = self.visit(node.right)
op = node.op
if isinstance(op, ast.Add):
return left + right
elif isinstance(op, ast.Sub):
return left - right
elif isinstance(op, ast.Mult):
return left * right
elif isinstance(op, ast.Div):
return left / right
else:
raise InputException('%s:%u: %r expression %r uses unsupported BinOp node type %s' % (self.source, self.lno, self.name, self.expr, op.__class__.__name__))
# Resolve expressions by expanding them.
def visit_Expression(self,node):
return self.visit(node.body)
# Resolve names by searching the dictionary `constants`, which is
# initialized from C++ constexpr declarations found while scanning
# the file.
def visit_Name(self,node):
try:
return self.constants[node.id]
except KeyError as e:
raise InputException('%s:%u: %r expression %r uses undefined name %s' % (self.source, self.lno, self.name, self.expr, node.id))
# Resolve numbers by returning the value as-is.
@staticmethod
def visit_Num(node):
return node.n
class Main:
def __init__(self):
# Initially, no constants are known. Elements will be added by
# prepare_text.
self.constants = {}
# Resolve an expression by parsing it into an AST, then visiting
# the nodes and emulating the permitted operations. Any
# disallowed operations will cause an exception, which will
# propagate through resolve_expr into the caller.
def resolve_expr(self,source,lno,name,expr):
expr = expr.strip()
return NodeVisitor(source, lno, name, expr, self.constants).visit(ast.parse(expr, mode='eval'))
# Given a list of C++ initializer lines, extract from those lines
# the position of each initialized cell, compute the u/d/l/r
# relations among the cells, and return a multiline string
# containing CPP #define statements appropriate to the cells. Each
# C++ initializer must be entirely contained within a single element
# in `lines`.
#
# array_name - C++ identifier for the array, only used in a C
# comment
#
# source - name of the file from which the lines were read
#
# lines - iterable of initializer lines
#
# _re_match_init_element - bound method for a regular expression to
# extract the required fields
def generate_defines(self,array_name,source,lines,_re_match_init_element=re.compile(r'{'
r'(?:[^,]+),' # x
r'(?P<y>[^,]+),'
r'(?P<xinput>[^,]+),'
r'(?:[^,]+),' # w2
r'\s*(?P<udlr>\w+),'
r'\s*(?:[^,]+,' # type
r'[^,]+,' # state_bit
r'[^,]+)' # state_ptr
r'},').match):
result = '\n/* %s */\n' % array_name
template = '#define {0}\t/* {1:2d} */\t{2:2d},{3:3d},{4:3d},{5:3d}\n'.format
a = ArrayInitializationLine
array = []
idx = 0
# Iterate over the initializer lines and populate `array` with
# the extracted data.
for lno, line in lines:
m = _re_match_init_element(line)
if m is None:
raise InputException('warning: %s:%u: failed to match regex\n' % (source, lno))
m = m.group
array.append(a(
self.resolve_expr(source, lno, 'xinput', m('xinput')),
self.resolve_expr(source, lno, 'y', m('y')),
m('udlr'), idx))
idx = idx + 1
# Generate a temporary list with the elements sorted for u/d
# navigation. Walk the temporary and assign appropriate u/d
# references.
s = sorted(array, key=a.key_vertical)
p = s[-1]
for i in s:
i.next_u = p
p.next_d = i
p = i
# As above, but sorted for l/r navigation.
s = sorted(array, key=a.key_horizontal)
p = s[-1]
for i in s:
i.next_l = p
p.next_r = i
p = i
# Generate the #define lines using the relations computed by the
# preceding loops. Both loops must execute completely before
# the data required by this loop is available. This loop cannot
# be folded into the loop above.
for i in array:
result += template(i.name, i.idx, i.next_u.idx, i.next_d.idx, i.next_l.idx, i.next_r.idx)
return result
# Given an iterable over a CPP-processed C++ file, find each kc_item
# array in the file, generate appropriate #define statements, and
# return the statements as a multiline string.
#
# script - path to this script
#
# fi - iterable over the CPP-processed C++ file
#
# _re_match_defn_const - bound match method for a regular expression
# to extract a C++ expression from the initializer of a
# std::integral_constant.
#
# _re_match_defn_array - bound match method for a regular expression
# to match the opening definition of a C++ kc_item array.
def prepare_text(self,script,fi,
_re_match_defn_const=re.compile(r'constexpr\s+std::integral_constant<\w+\s*,\s*((?:\w+\s*\+\s*)*\w+)>\s*(\w+){};').match,
_re_match_defn_array=re.compile(r'constexpr\s+kc_item\s+(\w+)\s*\[\]\s*=\s*{').match
):
source = fi.name
result = '''/* This is a generated file. Do not edit.
* This file was generated by %s
* This file was generated from %s
*/
''' % (script, source)
lines = []
# Simple line reassembly is done automatically, based on the
# requirement that braces be balanced to complete an
# initializer. This is required to handle cases where the
# initializer split onto multiple lines due to an embedded
# preprocessor directive.
unbalanced_open_brace = 0
array_name = None
partial_line = None
for lno, line in enumerate(fi, 1):
if line.startswith('#'):
# Ignore line/column position information
continue
line = line.strip()
if not line:
# Ignore blank lines
continue
if line == '};':
# End of array found. Check for context errors.
# Compute #define statements for this array. Reset for
# the next array.
if array_name is None:
raise InputException('%s:%u: end of array definition while no array open' % (source, lno))
if unbalanced_open_brace:
raise InputException('%s:%u: end of array definition while reading array initialization' % (source, lno))
result += self.generate_defines(array_name, source, lines)
lines = []
array_name = None
continue
if array_name is None:
# These expressions should never match outside an array
# definition, so apply them only when an array is open.
m = _re_match_defn_const(line)
if m is not None:
# Record a C++ std::integral_constant for later use
# evaluating table cells.
g = m.group
self.constants[g(2)] = self.resolve_expr(source, lno, 'constant', g(1))
continue
m = _re_match_defn_array(line)
if m is not None:
# Array definition found.
array_name = m.group(1)
continue
count = line.count
unbalanced_open_brace += count('{') - count('}')
if unbalanced_open_brace < 0:
raise InputException('%s:%u: brace count becomes negative' % (source, lno))
if partial_line is not None:
# Insert a fake whitespace to avoid combining a token at
# the end of one line with a token at the beginning of
# the next.
line = partial_line + ' ' + line
if unbalanced_open_brace:
# If braces are unbalanced, assume that this line is
# incomplete, save it for later, and proceed to the next
# line.
partial_line = line
continue
partial_line = None
lines.append((lno, line))
# Check for context error.
if array_name is not None:
raise InputException('%s: end of file while array definition open' % source)
return result
@staticmethod
def write_generated_text(target,generated_text):
if not target:
# As a special case, allow this script to be used as a
# filter.
sys.stdout.write(generated_text)
return
from tempfile import mkstemp
os_path = os.path
fd, path = mkstemp(suffix='', prefix='%s.' % os_path.basename(target), dir=os_path.dirname(target), text=True)
os.write(fd, generated_text)
os.close(fd)
os.rename(path, target)
def main(self,script,source,target):
# Read the entire file and prepare the output text before
# opening the output file.
try:
with (open(source, 'r') if source else sys.stdin) as fi:
generated_text = self.prepare_text(script,fi)
except InputException as e:
# Normally, input exceptions are presented as a simple
# error message. If this environment variable is set,
# show the full traceback.
if os.getenv('DXX_KCONFIG_UDLR_TRACEBACK') is not None:
raise
sys.stderr.write('error: %s\n' % e.message)
sys.exit(1)
self.write_generated_text(target,generated_text)
if __name__ == '__main__':
a = sys.argv
# As a convenience feature, if no input filename is given, read
# stdin. If no output filename is given, write to stdout.
l = len(a)
if l < 2:
a.append(None)
if l < 3:
a.append(None)
Main().main(*a[0:3])

View file

@ -375,6 +375,11 @@ constexpr const char *kcl_rebirth =
WEAPON_STRING_MEGA "\0"
;
#if defined(DXX_BUILD_DESCENT_I)
#include "d1x-rebirth/kconfig.udlr.h"
#elif defined(DXX_BUILD_DESCENT_II)
#include "d2x-rebirth/kconfig.udlr.h"
#endif
#include "kconfig.ui-table.cpp"
static array<kc_mitem, lengthof(kc_keyboard)> kcm_keyboard;

View file

@ -7,290 +7,248 @@
#include "dxxsconf.h"
#define DXX_KCONFIG_UI_UDLR3(I) DXX_KCONFIG_UI_UDLR_ ## I
#define DXX_KCONFIG_UI_UDLR2(I) DXX_KCONFIG_UI_UDLR3(I)
#define DXX_KCONFIG_UI_UDLR() DXX_KCONFIG_UI_UDLR2(__LINE__)
// x, y, xi, w2, u, d, l, r, type, state_bit, state_ptr
constexpr kc_item kc_keyboard[] = {
{ 15, 49, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_pitch_forward} },
{ 15, 49,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_pitch_forward} },
{ 15, 57, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_pitch_backward} },
{ 15, 57,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_pitch_backward} },
{ 15, 65, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_heading_left} },
{ 15, 65,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_heading_left} },
{ 15, 73, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_heading_right} },
{ 15, 73,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_heading_right} },
{ 15, 85, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::slide_on} },
{ 15, 85,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::slide_on} },
{ 15, 93, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_left} },
{ 15, 93,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_left} },
{ 15,101, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_right} },
{ 15,101,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_right} },
{ 15,109, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_up} },
{ 15,109,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_up} },
{ 15,117, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_down} },
{ 15,117,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_down} },
{ 15,129, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::bank_on} },
{ 15,129,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::bank_on} },
{ 15,137, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_bank_left} },
{ 15,137,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_bank_left} },
{ 15,145, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_bank_right} },
{ 15,145,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_bank_right} },
{158, 49,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::fire_primary} },
{158, 49,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::fire_primary} },
{158, 57,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::fire_secondary} },
{158, 57,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::fire_secondary} },
{158, 65,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::fire_flare} },
{158, 65,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::fire_flare} },
{158,105,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::accelerate} },
{158,105,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::accelerate} },
{158,113,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::reverse} },
{158,113,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::reverse} },
{158, 73,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::drop_bomb} },
{158, 73,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::drop_bomb} },
{158, 85,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::rear_view} },
{158, 85,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::rear_view} },
#if defined(DXX_BUILD_DESCENT_I)
{ 15, 49, 86, 26, 43, 2, 49, 1, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_pitch_forward} },
{ 15, 49,115, 26, 48, 3, 0, 24, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_pitch_forward} },
{158,125,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_plus} },
{158,125,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_plus} },
{158,133,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_minus} },
{158,133,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_minus} },
{158,141,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
{158,141,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
#elif defined(DXX_BUILD_DESCENT_II)
{ 15, 49, 86, 26, 55, 2, 56, 1, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_pitch_forward} },
{ 15, 49,115, 26, 50, 3, 0, 24, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_pitch_forward} },
{158,133,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_plus} },
{158,133,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_plus} },
{158,141,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_minus} },
{158,141,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_minus} },
{158,149,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
{158,149,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
#endif
{ 15, 57, 86, 26, 0, 4, 25, 3, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_pitch_backward} },
{ 15, 57,115, 26, 1, 5, 2, 26, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_pitch_backward} },
{ 15, 65, 86, 26, 2, 6, 27, 5, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_heading_left} },
{ 15, 65,115, 26, 3, 7, 4, 28, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_heading_left} },
{ 15, 73, 86, 26, 4, 8, 29, 7, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_heading_right} },
{ 15, 73,115, 26, 5, 9, 6, 34, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_heading_right} },
{ 15, 85, 86, 26, 6, 10, 35, 9, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::slide_on} },
{ 15, 85,115, 26, 7, 11, 8, 36, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::slide_on} },
{ 15, 93, 86, 26, 8, 12, 37, 11, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_left} },
{ 15, 93,115, 26, 9, 13, 10, 44, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_left} },
{ 15,101, 86, 26, 10, 14, 45, 13, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_right} },
{ 15,101,115, 26, 11, 15, 12, 30, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_right} },
{ 15,109, 86, 26, 12, 16, 31, 15, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_up} },
{ 15,109,115, 26, 13, 17, 14, 32, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_up} },
{ 15,117, 86, 26, 14, 18, 33, 17, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_slide_down} },
{158, 93,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::automap} },
{158, 93,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::automap} },
#if defined(DXX_BUILD_DESCENT_I)
{ 15,117,115, 26, 15, 19, 16, 38, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_down} },
{ 15,129, 86, 26, 16, 20, 39, 19, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::bank_on} },
{ 15,129,115, 26, 17, 21, 18, 40, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::bank_on} },
{ 15,137, 86, 26, 18, 22, 41, 21, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_bank_left} },
{ 15,137,115, 26, 19, 23, 20, 42, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_bank_left} },
{ 15,145, 86, 26, 20, 46, 43, 23, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_bank_right} },
{ 15,145,115, 26, 21, 47, 22, 46, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_bank_right} },
{158, 49,241, 26, 49, 26, 1, 25, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::fire_primary} },
{158, 49,270, 26, 42, 27, 24, 2, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::fire_primary} },
{ 15,157, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,157,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,165, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 15,165,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
#elif defined(DXX_BUILD_DESCENT_II)
{ 15,117,115, 26, 15, 19, 16, 46, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_slide_down} },
{ 15,129, 86, 26, 16, 20, 47, 19, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::bank_on} },
{ 15,129,115, 26, 17, 21, 18, 38, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::bank_on} },
{ 15,137, 86, 26, 18, 22, 39, 21, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_bank_left} },
{ 15,137,115, 26, 19, 23, 20, 40, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_bank_left} },
{ 15,145, 86, 26, 20, 48, 41, 23, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::key_bank_right} },
{ 15,145,115, 26, 21, 49, 22, 42, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::key_bank_right} },
{158, 49,241, 26, 51, 26, 1, 25, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::fire_primary} },
{158, 49,270, 26, 56, 27, 24, 2, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::fire_primary} },
#endif
{158, 57,241, 26, 24, 28, 3, 27, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::fire_secondary} },
{158, 57,270, 26, 25, 29, 26, 4, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::fire_secondary} },
{158, 65,241, 26, 26, 34, 5, 29, BT_KEY, 0, {&control_info::state_controls_t::fire_flare} },
{158, 65,270, 26, 27, 35, 28, 6, BT_KEY, 0, {&control_info::state_controls_t::fire_flare} },
{158,105,241, 26, 44, 32, 13, 31, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::accelerate} },
{158,105,270, 26, 45, 33, 30, 14, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::accelerate} },
#if defined(DXX_BUILD_DESCENT_I)
{158,113,241, 26, 30, 38, 15, 33, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::reverse} },
{158,113,270, 26, 31, 39, 32, 16, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::reverse} },
#elif defined(DXX_BUILD_DESCENT_II)
{158,113,241, 26, 30, 46, 15, 33, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::reverse} },
{158,113,270, 26, 31, 47, 32, 16, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::reverse} },
#endif
{158, 73,241, 26, 28, 36, 7, 35, BT_KEY, 0, {&control_info::state_controls_t::drop_bomb} },
{158, 73,270, 26, 29, 37, 34, 8, BT_KEY, 0, {&control_info::state_controls_t::drop_bomb} },
{158, 85,241, 26, 34, 44, 9, 37, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::rear_view} },
{158, 85,270, 26, 35, 45, 36, 10, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::rear_view} },
#if defined(DXX_BUILD_DESCENT_I)
{158,125,241, 26, 32, 40, 17, 39, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_plus} },
{158,125,270, 26, 33, 41, 38, 18, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_plus} },
{158,133,241, 26, 38, 42, 19, 41, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_minus} },
{158,133,270, 26, 39, 43, 40, 20, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_minus} },
{158,141,241, 26, 40, 25, 21, 43, BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
{158,141,270, 26, 41, 0, 42, 22, BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
#elif defined(DXX_BUILD_DESCENT_II)
{158,133,241, 26, 46, 40, 19, 39, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_plus} },
{158,133,270, 26, 47, 41, 38, 20, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_plus} },
{158,141,241, 26, 38, 42, 21, 41, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::cruise_minus} },
{158,141,270, 26, 39, 43, 40, 22, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::cruise_minus} },
{158,149,241, 26, 40, 52, 23, 43, BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
{158,149,270, 26, 41, 53, 42, 48, BT_KEY, 0, {&control_info::state_controls_t::cruise_off} },
#endif
{158, 93,241, 26, 36, 30, 11, 45, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::automap} },
{158, 93,270, 26, 37, 31, 44, 12, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::automap} },
#if defined(DXX_BUILD_DESCENT_I)
{ 15,157, 86, 26, 22, 48, 23, 47, BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,157,115, 26, 23, 49, 46, 48, BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,165, 86, 26, 46, 1, 47, 49, BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 15,165,115, 26, 47, 24, 48, 0, BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
#elif defined(DXX_BUILD_DESCENT_II)
{158,121,241, 26, 32, 38, 17, 47, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::afterburner} },
{158,121,270, 26, 33, 39, 46, 18, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::afterburner} },
{ 15,161, 86, 26, 22, 50, 43, 49, BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,161,115, 26, 23, 51, 48, 52, BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,169, 86, 26, 48, 1, 53, 51, BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 15,169,115, 26, 49, 24, 50, 54, BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
{158,163,241, 26, 42, 54, 49, 53, BT_KEY, 0, {&control_info::state_controls_t::headlight} },
{158,163,270, 26, 43, 55, 52, 50, BT_KEY, 0, {&control_info::state_controls_t::headlight} },
{158,171,241, 26, 52, 56, 51, 55, BT_KEY, STATE_BIT1, {&control_info::state_controls_t::energy_to_shield} },
{158,171,270, 26, 53, 0, 54, 56, BT_KEY, STATE_BIT2, {&control_info::state_controls_t::energy_to_shield} },
{158,179,241, 26, 54, 25, 55, 0, BT_KEY, 0, {&control_info::state_controls_t::toggle_bomb} },
{158,121,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::afterburner} },
{158,121,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::afterburner} },
{ 15,161, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,161,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_primary} },
{ 15,169, 86, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 15,169,115, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::cycle_secondary} },
{158,163,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::headlight} },
{158,163,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::headlight} },
{158,171,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT1, {&control_info::state_controls_t::energy_to_shield} },
{158,171,270, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, STATE_BIT2, {&control_info::state_controls_t::energy_to_shield} },
{158,179,241, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::toggle_bomb} },
#endif
};
#if DXX_MAX_JOYSTICKS
constexpr kc_item kc_joystick[] = {
#if defined(DXX_BUILD_DESCENT_I)
{ 22, 46,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 15, 1, 24, 29, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 0, 4, 34, 30, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 26, 3, 37, 31, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::accelerate} },
{ 22, 86,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 2, 25, 38, 32, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::reverse} },
{ 22, 62,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 1, 26, 35, 33, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
{174, 46,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 23, 6, 29, 34, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::slide_on} },
{174, 54,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 5, 7, 30, 35, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_left} },
{174, 62,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 6, 8, 33, 36, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_right} },
{174, 70,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 7, 9, 43, 37, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_up} },
{174, 78,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 8, 10, 31, 38, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_down} },
{174, 86,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 9, 11, 32, 39, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::bank_on} },
{174, 94,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 10, 12, 42, 40, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_bank_left} },
{174,102,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 11, 44, 28, 41, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_bank_right} },
{ 22,154, 73, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 47, 15, 47, 14, BT_JOY_AXIS, 0, {NULL} },
{ 22,154,121, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 27, 16, 13, 17, BT_INVERT, 0, {NULL} },
{ 22, 46,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::accelerate} },
{ 22, 86,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::reverse} },
{ 22, 62,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
#elif defined(DXX_BUILD_DESCENT_II)
{ 22, 46,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 15, 1, 24, 31, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 0, 4, 36, 32, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 26, 3, 39, 33, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::accelerate} },
{ 22, 86,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 2, 25, 40, 34, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::reverse} },
{ 22, 62,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 1, 26, 37, 35, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
{174, 46,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 23, 6, 31, 36, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::slide_on} },
{174, 54,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 5, 7, 32, 37, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_left} },
{174, 62,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 6, 8, 35, 38, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_right} },
{174, 70,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 7, 9, 45, 39, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_up} },
{174, 78,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 8, 10, 33, 40, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_down} },
{174, 86,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 9, 11, 34, 41, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::bank_on} },
{174, 94,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 10, 12, 44, 42, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_bank_left} },
{174,102,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 11, 28, 46, 43, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_bank_right} },
{ 22,154, 73, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 55, 15, 55, 14, BT_JOY_AXIS, 0, {NULL} },
{ 22,154,121, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 50, 16, 13, 17, BT_INVERT, 0, {NULL} },
{ 22, 46,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::accelerate} },
{ 22, 86,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::reverse} },
{ 22, 62,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
#endif
{ 22,162, 73, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 13, 0, 18, 16, BT_JOY_AXIS, 0, {NULL} },
{174, 46,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::slide_on} },
{174, 54,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_left} },
{174, 62,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_right} },
{174, 70,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_up} },
{174, 78,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_slide_down} },
{174, 86,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::bank_on} },
{174, 94,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_bank_left} },
{174,102,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::btn_bank_right} },
{ 22,154, 73, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_AXIS, 0, {NULL} },
{ 22,154,121, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{ 22,162, 73, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_AXIS, 0, {NULL} },
{ 22,162,121, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{164,154,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_AXIS, 0, {NULL} },
{164,154,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{164,162,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_AXIS, 0, {NULL} },
{164,162,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{164,170,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_AXIS, 0, {NULL} },
{164,170,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{164,178,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_AXIS, 0, {NULL} },
{164,178,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
#if defined(DXX_BUILD_DESCENT_I)
{ 22,162,121, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 14, 29, 15, 19, BT_INVERT, 0, {NULL} },
{164,154,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 28, 19, 14, 18, BT_JOY_AXIS, 0, {NULL} },
{164,154,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 45, 20, 17, 15, BT_INVERT, 0, {NULL} },
{ 22, 94,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::rear_view} },
{ 22, 70,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{ 22,102,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::automap} },
{ 22,102,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::automap} },
{ 22, 46,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::accelerate} },
{ 22, 86,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::reverse} },
{ 22, 62,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
#elif defined(DXX_BUILD_DESCENT_II)
{ 22,162,121, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 14, 31, 15, 19, BT_INVERT, 0, {NULL} },
{164,154,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 51, 19, 14, 18, BT_JOY_AXIS, 0, {NULL} },
{164,154,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 54, 20, 17, 15, BT_INVERT, 0, {NULL} },
{ 22, 94,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::rear_view} },
{ 22, 70,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{ 22,102,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::afterburner} },
{174,110,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 22,110,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::headlight} },
{ 22, 46,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::accelerate} },
{ 22, 86,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::reverse} },
{ 22, 62,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
#endif
{164,162,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 17, 21, 16, 20, BT_JOY_AXIS, 0, {NULL} },
{164,162,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 18, 22, 19, 21, BT_INVERT, 0, {NULL} },
{164,170,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 19, 23, 20, 22, BT_JOY_AXIS, 0, {NULL} },
{164,170,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 20, 24, 21, 23, BT_INVERT, 0, {NULL} },
{164,178,222, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH(26), 21, 5, 22, 24, BT_JOY_AXIS, 0, {NULL} },
{174, 46,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::slide_on} },
{174, 54,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_left} },
{174, 62,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_right} },
{174, 70,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_up} },
{174, 78,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_down} },
{174, 86,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::bank_on} },
{174, 94,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_bank_left} },
{174,102,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_bank_right} },
#if defined(DXX_BUILD_DESCENT_I)
{164,178,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 22, 34, 23, 0, BT_INVERT, 0, {NULL} },
{ 22, 94,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 3, 27, 39, 42, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::rear_view} },
{ 22, 70,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 4, 2, 36, 43, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{ 22,102,104, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 25, 14, 40, 28, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::automap} },
{ 22,102,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 42, 17, 27, 12, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::automap} },
{ 22, 46,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 16, 30, 0, 5, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 29, 33, 1, 6, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 43, 32, 2, 9, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::accelerate} },
{ 22, 86,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 31, 42, 3, 10, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::reverse} },
{ 22, 62,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 30, 43, 4, 7, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
{174, 46,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 24, 35, 5, 1, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::slide_on} },
{174, 54,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 34, 36, 6, 4, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_left} },
{174, 62,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 35, 37, 7, 26, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_right} },
{174, 70,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 36, 38, 8, 2, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_up} },
{174, 78,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 37, 39, 9, 3, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_down} },
{174, 86,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 38, 40, 10, 25, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::bank_on} },
{174, 94,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 39, 41, 11, 27, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_bank_left} },
{174,102,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 40, 46, 12, 44, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_bank_right} },
{ 22, 94,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 32, 28, 25, 11, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::rear_view} },
{ 22, 70,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 33, 31, 26, 8, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{174,110,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 12, 45, 41, 46, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 44, 18, 46, 47, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
{174,110,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 41, 47, 44, 45, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 46, 13, 45, 13, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 22, 94,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::rear_view} },
{ 22, 70,133, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{174,110,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
#elif defined(DXX_BUILD_DESCENT_II)
{164,178,270, DXX_KCONFIG_ITEM_JOY_AXIS_WIDTH( 8), 22, 36, 23, 0, BT_INVERT, 0, {NULL} },
{ 22, 94,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 3, 27, 41, 44, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::rear_view} },
{ 22, 70,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 4, 2, 38, 45, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{ 22,102,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 25, 30, 42, 46, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::afterburner} },
{174,110,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 12, 29, 49, 47, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 28, 54, 53, 48, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 22,110,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 27, 52, 43, 49, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::headlight} },
{ 22, 46,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 16, 32, 0, 5, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_primary} },
{ 22, 54,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 31, 35, 1, 6, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::fire_secondary} },
{ 22, 78,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 45, 34, 2, 9, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::accelerate} },
{ 22, 86,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 33, 44, 3, 10, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::reverse} },
{ 22, 62,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 32, 45, 4, 7, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
{174, 46,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 24, 37, 5, 1, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::slide_on} },
{174, 54,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 36, 38, 6, 4, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_left} },
{174, 62,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 37, 39, 7, 26, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_right} },
{174, 70,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 38, 40, 8, 2, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_up} },
{174, 78,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 39, 41, 9, 3, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_slide_down} },
{174, 86,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 40, 42, 10, 25, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::bank_on} },
{174, 94,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 41, 43, 11, 27, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_bank_left} },
{174,102,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 42, 47, 12, 30, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::btn_bank_right} },
{ 22, 94,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 34, 46, 25, 11, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::rear_view} },
{ 22, 70,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 35, 33, 26, 8, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{ 22,102,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 44, 49, 27, 12, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::afterburner} },
{174,110,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 43, 48, 28, 52, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 47, 55, 29, 50, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 22,110,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 46, 53, 30, 28, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::headlight} },
{ 22,126,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 52, 14, 48, 51, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::automap} },
{ 22,126,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 53, 17, 50, 54, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::automap} },
{ 22,118,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 30, 50, 47, 53, BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::energy_to_shield} },
{ 22,118,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 49, 51, 52, 29, BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::energy_to_shield} },
{174,126,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 29, 18, 51, 55, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::toggle_bomb} },
{174,126,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), 48, 13, 54, 13, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::toggle_bomb} },
{ 22, 94,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::rear_view} },
{ 22, 70,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
{ 22,102,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::afterburner} },
#endif
{174,110,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{174,118,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
#if defined(DXX_BUILD_DESCENT_II)
{ 22,110,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::headlight} },
{ 22,126,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::automap} },
{ 22,126,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::automap} },
{ 22,118,102, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT3, {&control_info::state_controls_t::energy_to_shield} },
{ 22,118,132, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, STATE_BIT4, {&control_info::state_controls_t::energy_to_shield} },
{174,126,248, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::toggle_bomb} },
{174,126,278, DXX_KCONFIG_ITEM_JOY_BUTTON_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::toggle_bomb} },
#endif
};
#endif
constexpr kc_item kc_mouse[] = {
{ 25, 46,110, 26, 19, 1, 20, 5, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::fire_primary} },
{ 25, 54,110, 26, 0, 4, 5, 6, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::fire_secondary} },
{ 25, 78,110, 26, 26, 3, 8, 9, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::accelerate} },
{ 25, 86,110, 26, 2, 25, 9, 10, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::reverse} },
{ 25, 62,110, 26, 1, 26, 6, 7, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
{180, 46,239, 26, 23, 6, 0, 1, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::slide_on} },
{180, 54,239, 26, 5, 7, 1, 4, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_left} },
{180, 62,239, 26, 6, 8, 4, 26, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_right} },
{180, 70,239, 26, 7, 9, 26, 2, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_up} },
{180, 78,239, 26, 8, 10, 2, 3, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_down} },
{180, 86,239, 26, 9, 11, 3, 25, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::bank_on} },
{180, 94,239, 26, 10, 12, 25, 27, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_bank_left} },
{180,102,239, 26, 11, 22, 27, 28, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_bank_right} },
{ 25, 46,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::fire_primary} },
{ 25, 54,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::fire_secondary} },
{ 25, 78,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::accelerate} },
{ 25, 86,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::reverse} },
{ 25, 62,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::fire_flare} },
{180, 46,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::slide_on} },
{180, 54,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_left} },
{180, 62,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_right} },
{180, 70,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_up} },
{180, 78,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_slide_down} },
{180, 86,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::bank_on} },
{180, 94,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_bank_left} },
{180,102,239, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::btn_bank_right} },
{ 25,154, 83, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_AXIS, 0, {NULL} },
{ 25,154,131, 8, DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{ 25,162, 83, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_AXIS, 0, {NULL} },
{ 25,162,131, 8, DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{ 25,170, 83, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_AXIS, 0, {NULL} },
{ 25,170,131, 8, DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{ 25,178, 83, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_AXIS, 0, {NULL} },
{ 25,178,131, 8, DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{180,154,238, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_AXIS, 0, {NULL} },
{180,154,286, 8, DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{180,162,238, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_AXIS, 0, {NULL} },
{180,162,286, 8, DXX_KCONFIG_UI_UDLR(), BT_INVERT, 0, {NULL} },
{ 25, 94,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::rear_view} },
{ 25, 70,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
#if defined(DXX_BUILD_DESCENT_I)
{ 25,154, 83, 26, 24, 15, 28, 14, BT_MOUSE_AXIS, 0, {NULL} },
{ 25,154,131, 8, 28, 16, 13, 21, BT_INVERT, 0, {NULL} },
{ 25,102,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{ 25,110,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
#elif defined(DXX_BUILD_DESCENT_II)
{ 25,154, 83, 26, 24, 15, 29, 14, BT_MOUSE_AXIS, 0, {NULL} },
{ 25,154,131, 8, 29, 16, 13, 21, BT_INVERT, 0, {NULL} },
#endif
{ 25,162, 83, 26, 13, 17, 22, 16, BT_MOUSE_AXIS, 0, {NULL} },
{ 25,162,131, 8, 14, 18, 15, 23, BT_INVERT, 0, {NULL} },
{ 25,170, 83, 26, 15, 19, 24, 18, BT_MOUSE_AXIS, 0, {NULL} },
{ 25,170,131, 8, 16, 20, 17, 19, BT_INVERT, 0, {NULL} },
{ 25,178, 83, 26, 17, 0, 18, 20, BT_MOUSE_AXIS, 0, {NULL} },
{ 25,178,131, 8, 18, 21, 19, 0, BT_INVERT, 0, {NULL} },
{180,154,238, 26, 20, 23, 14, 22, BT_MOUSE_AXIS, 0, {NULL} },
{180,154,286, 8, 12, 24, 21, 15, BT_INVERT, 0, {NULL} },
{180,162,238, 26, 21, 5, 16, 24, BT_MOUSE_AXIS, 0, {NULL} },
{180,162,286, 8, 22, 13, 23, 17, BT_INVERT, 0, {NULL} },
{ 25, 94,110, 26, 3, 27, 10, 11, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::rear_view} },
{ 25, 70,110, 26, 4, 2, 7, 8, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::drop_bomb} },
#if defined(DXX_BUILD_DESCENT_I)
{ 25,102,110, 26, 25, 28, 11, 12, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{ 25,110,110, 26, 27, 14, 12, 13, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
#elif defined(DXX_BUILD_DESCENT_II)
{ 25,102,110, 26, 25, 28, 11, 12, BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::afterburner} },
{ 25,110,110, 26, 27, 29, 12, 29, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{ 25,118,110, 26, 28, 14, 28, 13, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
{ 25,102,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, STATE_BIT5, {&control_info::state_controls_t::afterburner} },
{ 25,110,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_primary} },
{ 25,118,110, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::cycle_secondary} },
#endif
};
constexpr kc_item kc_rebirth[] = {
{ 15, 69,157, 26, 29, 3, 29, 1, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 69,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 27, 4, 0, 2, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 69,273, 26, 28, 5, 1, 3, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 77,157, 26, 0, 6, 2, 4, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 77,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 1, 7, 3, 5, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 77,273, 26, 2, 8, 4, 6, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 85,157, 26, 3, 9, 5, 7, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 85,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 4, 10, 6, 8, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 85,273, 26, 5, 11, 7, 9, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 93,157, 26, 6, 12, 8, 10, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 93,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 7, 13, 9, 11, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 93,273, 26, 8, 14, 10, 12, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,101,157, 26, 9, 15, 11, 13, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,101,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 10, 16, 12, 14, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,101,273, 26, 11, 17, 13, 15, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,109,157, 26, 12, 18, 14, 16, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,109,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 13, 19, 15, 17, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,109,273, 26, 14, 20, 16, 18, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,117,157, 26, 15, 21, 17, 19, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,117,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 16, 22, 18, 20, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,117,273, 26, 17, 23, 19, 21, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,125,157, 26, 18, 24, 20, 22, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,125,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 19, 25, 21, 23, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,125,273, 26, 20, 26, 22, 24, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,133,157, 26, 21, 27, 23, 25, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,133,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 22, 28, 24, 26, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,133,273, 26, 23, 29, 25, 27, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,141,157, 26, 24, 1, 26, 28, BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,141,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), 25, 2, 27, 29, BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,141,273, 26, 26, 0, 28, 0, BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 69,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 69,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 69,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 77,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 77,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 77,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 85,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 85,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 85,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 93,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 93,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15, 93,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,101,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,101,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,101,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,109,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,109,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,109,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,117,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,117,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,117,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,125,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,125,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,125,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,133,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,133,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,133,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,141,157, 26, DXX_KCONFIG_UI_UDLR(), BT_KEY, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,141,215, DXX_KCONFIG_ITEM_JOY_WIDTH(26), DXX_KCONFIG_UI_UDLR(), BT_JOY_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
{ 15,141,273, 26, DXX_KCONFIG_UI_UDLR(), BT_MOUSE_BUTTON, 0, {&control_info::state_controls_t::select_weapon} },
};
#undef DXX_KCONFIG_UI_UDLR
#undef DXX_KCONFIG_UI_UDLR2
#undef DXX_KCONFIG_UI_UDLR3