Major reworking of key configuration internals.

VControl no longer uses a custom configuration format; instead, control 
bindings are read in from the standard resource system.  Menu controls 
are specified in menu.key in the content; flight controls are now copied 
from uqm.key to flight.cfg instead of from starcon.key to uqm.key.

This change permits significant streamlining of the VControl code 
itself, and allows more fine-grained control over what the key 
configuration code iself does.  This update thus closes both Bug #949 
and Bug #961.


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2705 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2007-02-09 07:36:07 +00:00
parent ccc6ddac22
commit e7a86e4a8a
9 changed files with 352 additions and 974 deletions
+2
View File
@@ -1,4 +1,6 @@
Changes towards version 0.7:
- Major refactoring of input configuration to use the resource system
instead of custom files (bugs #961 and #949) - Michael
- Added ability to remove entries from ALists - Michael
- Cleaned up FRAME, CONTEXT, and FONT abstraction layers - Michael
- Added Input Frames to pause code to stop infinite loops - Michael
+83
View File
@@ -0,0 +1,83 @@
# Keyboard control definitions for the menus. Most keys can be
# described in a straightforward manner; consult the name table in
# src/sc2code/libs/input/sdl/keynames.c for the names of unusual keys.
# Most keys can be named by just the symbol they produce.
# Menu controls. Both sets of arrow keys, basically. Paging controls
# moving quickly through the file lists in Super Melee. Zooming
# controls zoom controls in the starmap. "Cancel" is also used to get
# you into menu mode to begin with. There is a "menu.Special" command
# currently unused by the game. It seems to have been originally used
# to call up details on starships in the Super Melee selection screen.
# Arrow key controls...
menu.up.1 = key Up
menu.down.1 = key Down
menu.right.1 = key Right
menu.left.1 = key Left
menu.pageup.1 = key PageUp
menu.pagedown.1 = key PageDown
menu.home.1 = key Home
menu.end.1 = key End
menu.zoomin.1 = key PageUp
menu.zoomout.1 = key PageDown
menu.select.1 = key Return
menu.select.2 = key RightControl
menu.cancel.1 = key Space
menu.cancel.2 = key RightShift
# ... and the number pad. Note that zoom controls on the starmap are
# different from the paging controls in Super Melee.
menu.up.2 = key Keypad-8
menu.down.2 = key Keypad-2
menu.left.2 = key Keypad-4
menu.right.2 = key Keypad-6
menu.pageup.2 = key Keypad-9
menu.pagedown.2 = key Keypad-3
menu.home.2 = key Keypad-7
menu.end.2 = key Keypad-1
menu.zoomin.2 = key Keypad-+
menu.zoomout.2 = key Keypad--
menu.select.3 = key Keypad-Enter
menu.cancel.3 = key Keypad-0
# System utility keys.
menu.delete.1 = key Delete
menu.delete.2 = key Keypad-.
menu.backspace.1 = key Backspace
menu.editcancel.1 = key Escape
menu.search.1 = key /
menu.next.1 = key Tab
menu.pause.1 = key Pause
menu.pause.2 = key F1
menu.exit.1 = key F10
menu.special.1 = key LeftAlt
menu.special.2 = key RightAlt
# Joystick controls, for both port 1 and 2.
menu.up.3 = joystick 0 axis 1 negative
menu.down.3 = joystick 0 axis 1 positive
menu.left.3 = joystick 0 axis 0 negative
menu.right.3 = joystick 0 axis 0 positive
menu.up.4 = joystick 0 hat 0 up
menu.down.4 = joystick 0 hat 0 down
menu.left.4 = joystick 0 hat 0 left
menu.right.4 = joystick 0 hat 0 right
menu.cancel.4 = joystick 0 button 1
menu.select.4 = joystick 0 button 0
menu.up.5 = joystick 1 axis 1 negative
menu.down.5 = joystick 1 axis 1 positive
menu.left.5 = joystick 1 axis 0 negative
menu.right.5 = joystick 1 axis 0 positive
menu.up.6 = joystick 1 hat 0 up
menu.down.6 = joystick 1 hat 0 down
menu.left.6 = joystick 1 hat 0 left
menu.right.6 = joystick 1 hat 0 right
menu.cancel.5 = joystick 1 button 1
menu.select.5 = joystick 1 button 0
-182
View File
@@ -1,182 +0,0 @@
# Default UQM input configuration file.
# This is a VCONTROL version 4 config file (UQM 0.5.3 or later).
version 4
# Keyboard control definitions follow this point. Most keys can be
# described in a straightforward manner; consult the name table in
# src/sc2code/libs/input/sdl/keynames.c for the names of unusual keys.
# Most keys can be named by just the symbol they produce.
# Menu controls. Both sets of arrow keys, basically. Paging controls
# moving quickly through the file lists in Super Melee. Zooming
# controls zoom controls in the starmap. "Cancel" is also used to get
# you into menu mode to begin with. There is a "Menu-Special" command
# currently unused by the game. It seems to have been originally used
# to call up details on starships in the Super Melee selection screen.
# Arrow key controls...
Menu-Up: key Up
Menu-Down: key Down
Menu-Right: key Right
Menu-Left: key Left
Menu-Page-Up: key PageUp
Menu-Page-Down: key PageDown
Menu-Home: key Home
Menu-End: key End
Menu-Zoom-In: key PageUp
Menu-Zoom-Out: key PageDown
Menu-Select: key Return
Menu-Select: key RightControl
Menu-Cancel: key Space
Menu-Cancel: key RightShift
# ... and the number pad. Note that zoom controls on the starmap are
# different from the paging controls in Super Melee.
Menu-Up: key Keypad-8
Menu-Down: key Keypad-2
Menu-Left: key Keypad-4
Menu-Right: key Keypad-6
Menu-Page-Up: key Keypad-9
Menu-Page-Down: key Keypad-3
Menu-Home: key Keypad-7
Menu-End: key Keypad-1
Menu-Zoom-In: key Keypad-+
Menu-Zoom-Out: key Keypad--
Menu-Select: key Keypad-Enter
Menu-Cancel: key Keypad-0
Menu-Delete: key Keypad-.
# System utility keys.
Menu-Delete: key Delete
Menu-Backspace: key Backspace
Menu-Edit-Cancel: key Escape
Menu-Search: key /
Menu-Next: key Tab
Pause: key Pause
Pause: key F1
Exit: key F10
# Arrow-key controls. This is the default for the bottom player in
# Super Melee and the player in the full game. Again, the player has
# the option of using either the number pad or the arrow keys.
Template-1-Up: key Up
Template-1-Down: key Down
Template-1-Left: key Left
Template-1-Right: key Right
Template-1-Weapon: key RightControl
Template-1-Special: key RightShift
Template-1-Up: key Keypad-8
Template-1-Down: key Keypad-2
Template-1-Left: key Keypad-4
Template-1-Right: key Keypad-6
Template-1-Weapon: key Keypad-Enter
Template-1-Special: key Keypad-0
Template-1-Escape: key Escape
# WASD for Player 2's default flight controls. We add the key 'd' to
# let him move down in the super-melee ship selection.
Template-2-Up: key w
Template-2-Down: key s
Template-2-Left: key a
Template-2-Right: key d
Template-2-Weapon: key v
Template-2-Special: key b
Template-2-Escape: key Escape
# Control Scheme 3: Variant Arrow keys with brackets for firing.
Template-3-Up: key Keypad-8
Template-3-Down: key Keypad-2
Template-3-Left: key Keypad-4
Template-3-Right: key Keypad-6
Template-3-Up: key Up
Template-3-Down: key Down
Template-3-Left: key Left
Template-3-Right: key Right
Template-3-Weapon: key ]
Template-3-Special: key [
Template-3-Escape: key Escape
# Control Scheme 4: Shifted WASD keys.
Template-4-Up: key e
Template-4-Down: key d
Template-4-Left: key s
Template-4-Right: key f
Template-4-Weapon: key q
Template-4-Special: key a
Template-4-Escape: key Escape
# This is a sample joystick configuration. This is intended to work
# primarily under WinXP with a USB analog/digital gamepad. The
# digital aspect of the gamepad happens to present itself to the
# system as a POV hat. This configuration allows either the digital
# or analog stick to be used simultaneously. More importantly, it
# gives us a chance to give examples for all of the various input types
# that UQM can handle.
joystick 0 threshold 10000 # How far to move before it counts; 0-30000
Template-5-Up: joystick 0 axis 1 negative
Template-5-Down: joystick 0 axis 1 positive
Template-5-Left: joystick 0 axis 0 negative
Template-5-Right: joystick 0 axis 0 positive
Template-5-Up: joystick 0 hat 0 up
Template-5-Down: joystick 0 hat 0 down
Template-5-Left: joystick 0 hat 0 left
Template-5-Right: joystick 0 hat 0 right
Template-5-Weapon: joystick 0 button 0
Template-5-Special: joystick 0 button 1
Template-5-Escape: key Escape
Menu-Up: joystick 0 axis 1 negative
Menu-Down: joystick 0 axis 1 positive
Menu-Left: joystick 0 axis 0 negative
Menu-Right: joystick 0 axis 0 positive
Menu-Up: joystick 0 hat 0 up
Menu-Down: joystick 0 hat 0 down
Menu-Left: joystick 0 hat 0 left
Menu-Right: joystick 0 hat 0 right
Menu-Cancel: joystick 0 button 1
Menu-Select: joystick 0 button 0
joystick 1 threshold 10000 # How far to move before it counts; 0-30000
Template-6-Up: joystick 1 axis 1 negative
Template-6-Down: joystick 1 axis 1 positive
Template-6-Left: joystick 1 axis 0 negative
Template-6-Right: joystick 1 axis 0 positive
Template-6-Up: joystick 1 hat 0 up
Template-6-Down: joystick 1 hat 0 down
Template-6-Left: joystick 1 hat 0 left
Template-6-Right: joystick 1 hat 0 right
Template-6-Weapon: joystick 1 button 0
Template-6-Special: joystick 1 button 1
Template-6-Escape: key Escape
Menu-Up: joystick 1 axis 1 negative
Menu-Down: joystick 1 axis 1 positive
Menu-Left: joystick 1 axis 0 negative
Menu-Right: joystick 1 axis 0 positive
Menu-Up: joystick 1 hat 0 up
Menu-Down: joystick 1 hat 0 down
Menu-Left: joystick 1 hat 0 left
Menu-Right: joystick 1 hat 0 right
Menu-Cancel: joystick 1 button 1
Menu-Select: joystick 1 button 0
+71
View File
@@ -0,0 +1,71 @@
keys.1.name = Arrows
keys.1.up.1 = key Up
keys.1.down.1 = key Down
keys.1.left.1 = key Left
keys.1.right.1 = key Right
keys.1.weapon.1 = key RightControl
keys.1.special.1 = key RightShift
keys.1.up.2 = key Keypad-8
keys.1.down.2 = key Keypad-2
keys.1.left.2 = key Keypad-4
keys.1.right.2 = key Keypad-6
keys.1.weapon.2 = key Keypad-Enter
keys.1.special.2 = key Keypad-0
keys.1.escape.1 = key Escape
keys.2.name = WASD
keys.2.up.1 = key w
keys.2.down.1 = key s
keys.2.left.1 = key a
keys.2.right.1 = key d
keys.2.weapon.1 = key v
keys.2.special.1 = key b
keys.2.escape.1 = key Escape
keys.3.name = Arrows (2)
keys.3.up.1 = key Up
keys.3.down.1 = key Down
keys.3.left.1 = key Left
keys.3.right.1 = key Right
keys.3.up.2 = key Keypad-8
keys.3.down.2 = key Keypad-2
keys.3.left.2 = key Keypad-4
keys.3.right.2 = key Keypad-6
keys.3.weapon.1 = key ]
keys.3.special.1 = key [
keys.3.escape.1 = key Escape
keys.4.name = ESDF
keys.4.up.1 = key e
keys.4.down.1 = key d
keys.4.left.1 = key s
keys.4.right.1 = key f
keys.4.weapon.1 = key q
keys.4.special.1 = key a
keys.4.escape.1 = key Escape
keys.5.name = Joystick 1
keys.5.up.1 = joystick 0 axis 1 negative
keys.5.down.1 = joystick 0 axis 1 positive
keys.5.left.1 = joystick 0 axis 0 negative
keys.5.right.1 = joystick 0 axis 0 positive
keys.5.up.2 = joystick 0 hat 0 up
keys.5.down.2 = joystick 0 hat 0 down
keys.5.left.2 = joystick 0 hat 0 left
keys.5.right.2 = joystick 0 hat 0 right
keys.5.weapon.1 = joystick 0 button 0
keys.5.special.1 = joystick 0 button 1
keys.5.escape.1 = key Escape
keys.6.name = Joystick 2
keys.6.up.1 = joystick 1 axis 1 negative
keys.6.down.1 = joystick 1 axis 1 positive
keys.6.left.1 = joystick 1 axis 0 negative
keys.6.right.1 = joystick 1 axis 0 positive
keys.6.up.2 = joystick 1 hat 0 up
keys.6.down.2 = joystick 1 hat 0 down
keys.6.left.2 = joystick 1 hat 0 left
keys.6.right.2 = joystick 1 hat 0 right
keys.6.weapon.1 = joystick 1 button 0
keys.6.special.1 = joystick 1 button 1
keys.6.escape.1 = key Escape
+164 -181
View File
@@ -44,150 +44,145 @@ static BOOLEAN InputInitialized = FALSE;
static BOOLEAN _in_character_mode = FALSE;
#define VCONTROL_VERSION 4
static const char *menu_res_names[] = {
"pause",
"exit",
"abort",
"debug",
"up",
"down",
"left",
"right",
"select",
"cancel",
"special",
"pageup",
"pagedown",
"home",
"end",
"zoomin",
"zoomout",
"delete",
"backspace",
"editcancel",
"search",
"next",
NULL
};
static VControl_NameBinding control_names[] = {
{ "Menu-Up", (int *)&ImmediateInputState.menu[KEY_MENU_UP] },
{ "Menu-Down", (int *)&ImmediateInputState.menu[KEY_MENU_DOWN] },
{ "Menu-Left", (int *)&ImmediateInputState.menu[KEY_MENU_LEFT] },
{ "Menu-Right", (int *)&ImmediateInputState.menu[KEY_MENU_RIGHT] },
{ "Menu-Select", (int *)&ImmediateInputState.menu[KEY_MENU_SELECT] },
{ "Menu-Cancel", (int *)&ImmediateInputState.menu[KEY_MENU_CANCEL] },
{ "Menu-Special", (int *)&ImmediateInputState.menu[KEY_MENU_SPECIAL] },
{ "Menu-Page-Up", (int *)&ImmediateInputState.menu[KEY_MENU_PAGE_UP] },
{ "Menu-Page-Down", (int *)&ImmediateInputState.menu[KEY_MENU_PAGE_DOWN] },
{ "Menu-Home", (int *)&ImmediateInputState.menu[KEY_MENU_HOME] },
{ "Menu-End", (int *)&ImmediateInputState.menu[KEY_MENU_END] },
{ "Menu-Zoom-In", (int *)&ImmediateInputState.menu[KEY_MENU_ZOOM_IN] },
{ "Menu-Zoom-Out", (int *)&ImmediateInputState.menu[KEY_MENU_ZOOM_OUT] },
{ "Menu-Delete", (int *)&ImmediateInputState.menu[KEY_MENU_DELETE] },
{ "Menu-Backspace", (int *)&ImmediateInputState.menu[KEY_MENU_BACKSPACE] },
{ "Menu-Edit-Cancel", (int *)&ImmediateInputState.menu[KEY_MENU_EDIT_CANCEL] },
{ "Menu-Search", (int *)&ImmediateInputState.menu[KEY_MENU_SEARCH] },
{ "Menu-Next", (int *)&ImmediateInputState.menu[KEY_MENU_NEXT] },
{ "Template-1-Up", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_UP] },
{ "Template-1-Down", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_DOWN] },
{ "Template-1-Left", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_LEFT] },
{ "Template-1-Right", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_RIGHT] },
{ "Template-1-Weapon", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_WEAPON] },
{ "Template-1-Special", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_SPECIAL] },
{ "Template-1-Escape", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_1][KEY_ESCAPE] },
{ "Template-2-Up", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_UP] },
{ "Template-2-Down", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_DOWN] },
{ "Template-2-Left", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_LEFT] },
{ "Template-2-Right", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_RIGHT] },
{ "Template-2-Weapon", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_WEAPON] },
{ "Template-2-Special", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_SPECIAL] },
{ "Template-2-Escape", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_2][KEY_ESCAPE] },
{ "Template-3-Up", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_UP] },
{ "Template-3-Down", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_DOWN] },
{ "Template-3-Left", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_LEFT] },
{ "Template-3-Right", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_RIGHT] },
{ "Template-3-Weapon", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_WEAPON] },
{ "Template-3-Special", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_SPECIAL] },
{ "Template-3-Escape", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_KB_3][KEY_ESCAPE] },
{ "Template-4-Up", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_UP] },
{ "Template-4-Down", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_DOWN] },
{ "Template-4-Left", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_LEFT] },
{ "Template-4-Right", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_RIGHT] },
{ "Template-4-Weapon", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_WEAPON] },
{ "Template-4-Special", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_SPECIAL] },
{ "Template-4-Escape", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_1][KEY_ESCAPE] },
{ "Template-5-Up", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_UP] },
{ "Template-5-Down", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_DOWN] },
{ "Template-5-Left", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_LEFT] },
{ "Template-5-Right", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_RIGHT] },
{ "Template-5-Weapon", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_WEAPON] },
{ "Template-5-Special", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_SPECIAL] },
{ "Template-5-Escape", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_2][KEY_ESCAPE] },
{ "Template-6-Up", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_UP] },
{ "Template-6-Down", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_DOWN] },
{ "Template-6-Left", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_LEFT] },
{ "Template-6-Right", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_RIGHT] },
{ "Template-6-Weapon", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_WEAPON] },
{ "Template-6-Special", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_SPECIAL] },
{ "Template-6-Escape", (int *)&ImmediateInputState.key[CONTROL_TEMPLATE_JOY_3][KEY_ESCAPE] },
{ "Pause", (int *)&ImmediateInputState.menu[KEY_PAUSE] },
{ "Exit", (int *)&ImmediateInputState.menu[KEY_EXIT] },
{ "Abort", (int *)&ImmediateInputState.menu[KEY_ABORT] },
{ "Debug", (int *)&ImmediateInputState.menu[KEY_DEBUG] },
{ "Illegal", NULL}};
static const char *flight_res_names[] = {
"up",
"down",
"left",
"right",
"weapon",
"special",
"escape",
NULL
};
static void
register_menu_controls (int index)
{
int i;
char buf[40];
buf[39] = '\0';
i = 1;
while (TRUE)
{
VCONTROL_GESTURE g;
snprintf (buf, 39, "menu.%s.%d", menu_res_names[index], i);
if (!res_HasKey (buf))
break;
VControl_ParseGesture (&g, res_GetString (buf));
VControl_AddGestureBinding (&g, (int *)&ImmediateInputState.menu[index]);
i++;
}
}
static VCONTROL_GESTURE controls[NUM_TEMPLATES][NUM_KEYS][2];
static void
register_flight_controls (void)
{
int i, j, k;
char buf[40];
buf[39] = '\0';
for (i = 0; i < NUM_TEMPLATES; i++)
{
/* Copy in name */
snprintf (buf, 39, "keys.%d.name", i+1);
if (res_HasKey (buf))
{
strncpy (input_templates[i].name, res_GetString (buf), 29);
input_templates[i].name[29] = '\0';
}
else
{
input_templates[i].name[0] = '\0';
}
for (j = 0; j < NUM_KEYS; j++)
{
for (k = 0; k < 2; k++)
{
VCONTROL_GESTURE *g = &controls[i][j][k];
snprintf (buf, 39, "keys.%d.%s.%d", i+1, flight_res_names[j], k+1);
if (!res_HasKey (buf))
{
g->type = VCONTROL_NONE;
continue;
}
VControl_ParseGesture (g, res_GetString (buf));
VControl_AddGestureBinding (g, (int *)&ImmediateInputState.key[i][j]);
}
}
}
}
static void
initKeyConfig (void)
{
uio_Stream *fp;
int i, errors;
for (i = 0; i < 2; ++i)
int i;
/* First, load in the menu keys */
res_LoadFilename (contentDir, "menu.key");
for (i = 0; i < NUM_MENU_KEYS; i++)
{
if ((fp = res_OpenResFile (configDir, "keys.cfg", "rt")) == NULL)
if (!menu_res_names[i])
break;
register_menu_controls (i);
}
fp = res_OpenResFile (configDir, "flight.cfg", "rt");
if (!fp)
{
if (copyFile (contentDir, "uqm.key",
configDir, "flight.cfg") == -1)
{
if (copyFile (contentDir, "starcon.key",
configDir, "keys.cfg") == -1)
{
log_add (log_Fatal, "Error: Could not copy default key config "
"to user config dir: %s.", strerror (errno));
exit (EXIT_FAILURE);
}
log_add (log_Info, "Copying default key config file to user "
"config dir.");
if ((fp = res_OpenResFile (configDir, "keys.cfg", "rt")) == NULL)
{
log_add (log_Fatal, "Error: Could not open keys.cfg");
exit (EXIT_FAILURE);
}
}
errors = VControl_ReadConfiguration (fp);
res_CloseResFile (fp);
if (errors || (VControl_GetConfigFileVersion () != VCONTROL_VERSION))
{
bool do_rename = false;
if (errors)
log_add (log_Warning, "%d errors encountered in key configuration file.", errors);
if (VControl_GetValidCount () == 0)
{
log_add (log_Error, "\nI didn't understand a single line in your configuration file.");
log_add (log_Error, "This is likely because you're still using a 0.2 era or earlier keys.cfg.");
do_rename = true;
}
if (VControl_GetConfigFileVersion () != VCONTROL_VERSION)
{
log_add (log_Error, "\nThe control scheme for UQM has changed since you last updated keys.cfg.");
log_add (log_Error, "(I'm using control scheme version %d, while your config file appears to be\nfor version %d.)", VCONTROL_VERSION, VControl_GetConfigFileVersion ());
do_rename = true;
}
if (do_rename)
{
log_add (log_Error, "\nRenaming keys.cfg to keys.old and retrying.");
if (fileExists2 (configDir, "keys.old"))
uio_unlink (configDir, "keys.old");
if ((uio_rename (configDir, "keys.cfg", configDir, "keys.old")) == -1)
{
log_add (log_Fatal, "Error: Renaming failed!");
log_add (log_Fatal, "You must delete keys.cfg manually before you can run the game.");
exit (EXIT_FAILURE);
}
continue;
}
log_add (log_Fatal, "\nRepair your keys.cfg file to continue.");
log_add (log_Fatal, "Error: Could not copy default key config "
"to user config dir: %s.", strerror (errno));
exit (EXIT_FAILURE);
}
log_add (log_Info, "Copying default key config file to user "
"config dir.");
return;
if ((fp = res_OpenResFile (configDir, "flight.cfg", "rt")) == NULL)
{
log_add (log_Fatal, "Error: Could not open flight.cfg");
exit (EXIT_FAILURE);
}
}
res_LoadFile (fp);
res_CloseResFile (fp);
log_add (log_Fatal, "Error: Something went wrong and we were looping again and again so aborting.");
log_add (log_Fatal, "Possible cause is your content dir not being up-to-date.");
exit (EXIT_FAILURE);
register_flight_controls ();
return;
}
static void
@@ -239,7 +234,6 @@ TFB_InitInput (int driver, int flags)
/* Prepare the Virtual Controller system. */
VControl_Init ();
VControl_RegisterNameTable (control_names);
initKeyConfig ();
@@ -387,62 +381,45 @@ FlushInput (void)
void
InterrogateInputState (int template, int control, int index, char *buffer, int maxlen)
{
int i;
VCONTROL_GESTURE g;
VCONTROL_GESTURE *g = &controls[template][control][index];
VControl_StartIter (&ImmediateInputState.key[template][control]);
i = 0;
while (VControl_NextBinding (&g))
switch (g->type)
{
if (i++ < index)
{
continue;
}
switch (g.type)
{
case VCONTROL_KEY:
snprintf (buffer, maxlen, "%s", VControl_code2name (g.gesture.key));
buffer[maxlen-1] = 0;
break;
case VCONTROL_JOYBUTTON:
snprintf (buffer, maxlen, "[J%d B%d]", g.gesture.button.port, g.gesture.button.index + 1);
buffer[maxlen-1] = 0;
break;
case VCONTROL_JOYAXIS:
snprintf (buffer, maxlen, "[J%d A%d %c]", g.gesture.axis.port, g.gesture.axis.index, g.gesture.axis.polarity > 0 ? '+' : '-');
break;
case VCONTROL_JOYHAT:
snprintf (buffer, maxlen, "[J%d H%d %d]", g.gesture.hat.port, g.gesture.hat.index, g.gesture.hat.dir);
break;
default:
/* Something we don't handle yet */
buffer[0] = 0;
break;
}
return;
case VCONTROL_KEY:
snprintf (buffer, maxlen, "%s", VControl_code2name (g->gesture.key));
buffer[maxlen-1] = 0;
break;
case VCONTROL_JOYBUTTON:
snprintf (buffer, maxlen, "[J%d B%d]", g->gesture.button.port, g->gesture.button.index + 1);
buffer[maxlen-1] = 0;
break;
case VCONTROL_JOYAXIS:
snprintf (buffer, maxlen, "[J%d A%d %c]", g->gesture.axis.port, g->gesture.axis.index, g->gesture.axis.polarity > 0 ? '+' : '-');
break;
case VCONTROL_JOYHAT:
snprintf (buffer, maxlen, "[J%d H%d %d]", g->gesture.hat.port, g->gesture.hat.index, g->gesture.hat.dir);
break;
default:
/* Something we don't handle yet */
buffer[0] = 0;
break;
}
/* There aren't that many bindings, so return blank string */
buffer[0] = 0;
return;
}
void
RemoveInputState (int template, int control, int index)
{
int i;
VCONTROL_GESTURE g;
VCONTROL_GESTURE *g = &controls[template][control][index];
char keybuf[40];
keybuf[39] = '\0';
VControl_RemoveGestureBinding (g, (int *)&ImmediateInputState.key[template][control]);
g->type = VCONTROL_NONE;
snprintf (keybuf, 39, "keys.%d.%s.%d", template+1, flight_res_names[control], index+1);
res_Remove (keybuf);
VControl_StartIter (&ImmediateInputState.key[template][control]);
i = 0;
while (VControl_NextBinding (&g))
{
if (i++ < index)
{
continue;
}
VControl_RemoveGestureBinding (&g, &ImmediateInputState.key[template][control]);
return;
}
/* No such gesture! */
return;
}
@@ -450,6 +427,8 @@ void
RebindInputState (int template, int control, int index)
{
VCONTROL_GESTURE g;
char keybuf[40], valbuf[40];
keybuf[39] = valbuf[39] = '\0';
/* Remove the old binding on this spot */
RemoveInputState (template, control, index);
@@ -462,7 +441,11 @@ RebindInputState (int template, int control, int index)
}
/* And now, add the new binding. */
VControl_AddGestureBinding (&g, &ImmediateInputState.key[template][control]);
VControl_AddGestureBinding (&g, (int *)&ImmediateInputState.key[template][control]);
controls[template][control][index] = g;
snprintf (keybuf, 39, "keys.%d.%s.%d", template+1, flight_res_names[control], index+1);
VControl_DumpGesture (valbuf, 39, &g);
res_PutString (keybuf, valbuf);
}
void
@@ -473,9 +456,9 @@ SaveKeyConfiguration (uio_DirHandle *path, const char *fname)
f = res_OpenResFile (path, fname, "wb");
if (f)
{
VControl_Dump (f);
res_SaveFile (f, "keys.");
res_CloseResFile (f);
}
}
}
void
+23 -552
View File
@@ -71,16 +71,6 @@ static int num_sdl_keys = 0;
static keybinding **bindings = NULL;
static keypool *pool;
static VControl_NameBinding *nametable;
/* Statistics variables - set by VControl_ReadConfiguration */
static int version, errors, validlines;
/* Iterator temp variables */
static int *iter_target;
static int iter_device, iter_index;
/* Last interesting event */
static int event_ready;
@@ -243,30 +233,16 @@ key_uninit (void)
#endif /* HAVE_JOYSTICK */
}
static void
name_init (void)
{
nametable = NULL;
}
static void
name_uninit (void)
{
nametable = NULL;
}
void
VControl_Init (void)
{
key_init ();
name_init ();
}
void
VControl_Uninit (void)
{
key_uninit ();
name_uninit ();
}
int
@@ -413,8 +389,6 @@ event2gesture (SDL_Event *e, VCONTROL_GESTURE *g)
g->type = VCONTROL_KEY;
g->gesture.key = e->key.keysym.sym;
break;
#ifdef HAVE_JOYSTICK
case SDL_JOYAXISMOTION:
g->type = VCONTROL_JOYAXIS;
g->gesture.axis.port = e->jaxis.which;
@@ -432,7 +406,6 @@ event2gesture (SDL_Event *e, VCONTROL_GESTURE *g)
g->gesture.button.port = e->jbutton.which;
g->gesture.button.index = e->jbutton.button;
break;
#endif /* HAVE_JOYSTICK */
default:
g->type = VCONTROL_NONE;
@@ -450,17 +423,24 @@ VControl_AddGestureBinding (VCONTROL_GESTURE *g, int *target)
result = VControl_AddKeyBinding (g->gesture.key, target);
break;
#ifdef HAVE_JOYSTICK
case VCONTROL_JOYAXIS:
#ifdef HAVE_JOYSTICK
result = VControl_AddJoyAxisBinding (g->gesture.axis.port, g->gesture.axis.index, (g->gesture.axis.polarity < 0) ? -1 : 1, target);
break;
#endif
case VCONTROL_JOYHAT:
#ifdef HAVE_JOYSTICK
result = VControl_AddJoyHatBinding (g->gesture.hat.port, g->gesture.hat.index, g->gesture.hat.dir, target);
break;
#endif
case VCONTROL_JOYBUTTON:
#ifdef HAVE_JOYSTICK
result = VControl_AddJoyButtonBinding (g->gesture.button.port, g->gesture.button.index, target);
break;
#endif /* HAVE_JOYSTICK */
case VCONTROL_NONE:
/* Do nothing */
break;
default:
log_add (log_Warning, "VControl_AddGestureBinding didn't understand argument gesture");
@@ -479,18 +459,23 @@ VControl_RemoveGestureBinding (VCONTROL_GESTURE *g, int *target)
VControl_RemoveKeyBinding (g->gesture.key, target);
break;
#ifdef HAVE_JOYSTICK
case VCONTROL_JOYAXIS:
#ifdef HAVE_JOYSTICK
VControl_RemoveJoyAxisBinding (g->gesture.axis.port, g->gesture.axis.index, (g->gesture.axis.polarity < 0) ? -1 : 1, target);
break;
#endif /* HAVE_JOYSTICK */
case VCONTROL_JOYHAT:
#ifdef HAVE_JOYSTICK
VControl_RemoveJoyHatBinding (g->gesture.hat.port, g->gesture.hat.index, g->gesture.hat.dir, target);
break;
#endif /* HAVE_JOYSTICK */
case VCONTROL_JOYBUTTON:
#ifdef HAVE_JOYSTICK
VControl_RemoveJoyButtonBinding (g->gesture.button.port, g->gesture.button.index, target);
break;
#endif /* HAVE_JOYSTICK */
case VCONTROL_NONE:
break;
default:
log_add (log_Warning, "VControl_RemoveGestureBinding didn't understand argument gesture");
break;
@@ -948,299 +933,6 @@ VControl_HandleEvent (const SDL_Event *e)
}
}
void
VControl_RegisterNameTable (VControl_NameBinding *table)
{
nametable = table;
}
static char *
target2name (int *target)
{
VControl_NameBinding *b = nametable;
while (b->target)
{
if (target == b->target)
{
return b->name;
}
++b;
}
return NULL;
}
static int *
name2target (char *name)
{
VControl_NameBinding *b = nametable;
while (b->target)
{
if (!stricmp (name, b->name))
{
return b->target;
}
++b;
}
return NULL;
}
static void
dump_keybindings (uio_Stream *out, keybinding *kb, char *name)
{
while (kb != NULL)
{
char *targetname = target2name (kb->target);
WriteResFile (targetname, 1, strlen (targetname), out);
PutResFileChar (':', out);
PutResFileChar (' ', out);
WriteResFile (name, 1, strlen (name), out);
PutResFileNewline (out);
kb = kb->next;
}
}
void
VControl_Dump (uio_Stream *out)
{
int i;
char namebuffer[64];
sprintf (namebuffer, "version %d", version);
WriteResFile (namebuffer, 1, strlen (namebuffer), out);
PutResFileNewline (out);
/* Print out keyboard bindings */
for (i = 0; i < num_sdl_keys; i++)
{
keybinding *kb = bindings[i];
if (kb != NULL)
{
sprintf (namebuffer, "key %s", VControl_code2name (i));
dump_keybindings (out, kb, namebuffer);
}
}
#ifdef HAVE_JOYSTICK
/* Print out joystick bindings */
for (i = 0; i < joycount; i++)
{
if (joysticks[i].stick)
{
int j;
sprintf (namebuffer, "joystick %d threshold %d", i, joysticks[i].threshold);
WriteResFile (namebuffer, 1, strlen (namebuffer), out);
PutResFileNewline (out);
for (j = 0; j < joysticks[i].numaxes; j++)
{
sprintf (namebuffer, "joystick %d axis %d negative", i, j);
dump_keybindings (out, joysticks[i].axes[j].neg, namebuffer);
sprintf (namebuffer, "joystick %d axis %d positive", i, j);
dump_keybindings (out, joysticks[i].axes[j].pos, namebuffer);
}
for (j = 0; j < joysticks[i].numbuttons; j++)
{
keybinding *kb = joysticks[i].buttons[j];
if (kb != NULL)
{
sprintf (namebuffer, "joystick %d button %d", i, j);
dump_keybindings (out, kb, namebuffer);
}
}
for (j = 0; j < joysticks[i].numhats; j++)
{
sprintf (namebuffer, "joystick %d hat %d left", i, j);
dump_keybindings (out, joysticks[i].hats[j].left, namebuffer);
sprintf (namebuffer, "joystick %d hat %d right", i, j);
dump_keybindings (out, joysticks[i].hats[j].right, namebuffer);
sprintf (namebuffer, "joystick %d hat %d up", i, j);
dump_keybindings (out, joysticks[i].hats[j].up, namebuffer);
sprintf (namebuffer, "joystick %d hat %d down", i, j);
dump_keybindings (out, joysticks[i].hats[j].down, namebuffer);
}
}
}
#endif /* HAVE_JOYSTICK */
#ifdef VCONTROL_DEBUG
/* Print out allocation data */
{
keypool bp = pool;
i = 0;
while (bp != NULL)
{
fprintf (out, "# Internal Debug: Chunk #%i: %d slots remaining.\n", i, bp->remaining);
i++;
bp = bp->next;
}
fprintf (out, "# Internal Debug: %d chunks allocated.\n", i);
}
#endif
}
/* Iterator routines. iter_target holds the target keybinding.
iter_device is -1 for the keyboard, otherwise it is joystick
#(iter_device/3). (iter_device%3) gives whether we're checking the
joystick's axes (0), buttons (1), or hats (2). */
static int *iter_target;
static int iter_device, iter_index;
void
VControl_StartIter (int *target)
{
iter_target = target;
iter_device = -1;
iter_index = 0;
}
void
VControl_StartIterByName (char *targetname)
{
VControl_StartIter (name2target (targetname));
}
int
VControl_NextBinding (VCONTROL_GESTURE *gesture)
{
if ((gesture == NULL) || (iter_target == NULL)
|| iter_device >= (joycount * 3))
return 0;
while (iter_device < (joycount * 3))
{
if (iter_device == -1) /* keyboard */
{
keybinding *kb = bindings[iter_index];
int done = 0;
while (kb != NULL)
{
if (kb->target == iter_target)
{
gesture->type = VCONTROL_KEY;
gesture->gesture.key = iter_index;
done = 1;
}
kb = kb->next;
}
if (++iter_index == num_sdl_keys)
{
iter_device = 0;
iter_index = 0;
}
if (done) return 1;
}
#ifdef HAVE_JOYSTICK
else
{
int i = iter_device / 3;
int t = iter_device % 3;
if (!joysticks[i].stick) /* Joystick wasn't opened; this binding is dead */
{
iter_device++;
iter_index = 0;
}
else
{
int done = 0;
switch (t)
{
case 0: { /* Axes */
int axis = iter_index / 2;
int dir = iter_index % 2;
if (axis >= joysticks[i].numaxes)
{
iter_device++;
iter_index = 0;
}
else
{
keybinding *kb = (dir) ? joysticks[i].axes[axis].pos : joysticks[i].axes[axis].neg;
while (kb != NULL)
{
if (kb->target == iter_target)
{
done = 1;
gesture->type = VCONTROL_JOYAXIS;
gesture->gesture.axis.port = i;
gesture->gesture.axis.index = axis;
gesture->gesture.axis.polarity = (dir) ? 1 : -1;
}
kb = kb->next;
}
iter_index++;
}
break;
}
case 1: { /* Buttons */
keybinding *kb = joysticks[i].buttons[iter_index];
if (iter_index >= joysticks[i].numbuttons)
{
iter_device++;
iter_index = 0;
}
else
{
while (kb != NULL)
{
if (kb->target == iter_target)
{
gesture->type = VCONTROL_JOYBUTTON;
gesture->gesture.button.port = i;
gesture->gesture.button.index = iter_index;
done = 1;
}
kb = kb->next;
}
iter_index++;
}
break;
}
case 2: { /* Hats */
int hat = iter_index / 4;
int hatd = iter_index % 4;
if (hat >= joysticks[i].numhats)
{
iter_device++;
iter_index = 0;
}
else
{
keybinding *kb;
Uint8 targetdir;
switch (hatd)
{
case 0: kb = joysticks[i].hats[hat].left; targetdir = SDL_HAT_LEFT; break;
case 1: kb = joysticks[i].hats[hat].right; targetdir = SDL_HAT_RIGHT; break;
case 2: kb = joysticks[i].hats[hat].up; targetdir = SDL_HAT_UP; break;
default: kb = joysticks[i].hats[hat].down; targetdir = SDL_HAT_DOWN; break;
}
while (kb != NULL)
{
if (kb->target == iter_target)
{
done = 1;
gesture->type = VCONTROL_JOYHAT;
gesture->gesture.hat.port = i;
gesture->gesture.hat.index = hat;
gesture->gesture.hat.dir = targetdir;
}
kb = kb->next;
}
iter_index++;
}
break;
}
}
if (done) return 1;
}
}
#endif /* HAVE_JOYSTICK */
}
return 0;
}
/* Tracking the last interesting event */
void
@@ -1337,43 +1029,6 @@ next_token (parse_state *state)
state->index = base+index;
}
static void
next_line (parse_state *state, uio_Stream *in)
{
int i, ch = 0;
state->linenum++;
for (i = 0; i < LINE_SIZE-1; i++)
{
if (uio_feof (in))
{
break;
}
ch = uio_fgetc (in);
if (ch == '#' || ch == '\n' || ch == EOF)
{
/* If this line is blank or all commented, include some
* whitespace. This lets us detect EOF as a completely
* blank line. */
if (i==0)
{
state->line[i] = '\n';
i++;
}
break;
}
state->line[i] = ch;
}
state->line[i] = '\0';
/* Skip to end of line */
while (ch != '\n' && !uio_feof (in))
{
ch = uio_fgetc (in);
}
state->token[0] = 0;
state->index = 0;
state->error = 0;
}
static void
expected_error (parse_state *state, char *expected)
{
@@ -1406,45 +1061,6 @@ consume_keyname (parse_state *state)
return keysym;
}
static int *
consume_idname (parse_state *state)
{
int *result = NULL;
int index = 0;
while (state->token[index])
{
index++;
}
if (index == 0)
{
log_add (log_Debug, "VControl: Can't happen: blank token to consume_idname (line %d)",
state->linenum);
state->error = 1;
return NULL;
}
index--;
if (state->token[index] != ':')
{
expected_error (state, ":");
return NULL;
}
state->token[index] = 0; /* remove trailing colon */
result = name2target (state->token);
if (!result)
{
log_add (log_Warning, "VControl: Illegal command type '%s' on config file line %d",
state->token, state->linenum);
state->error = 1;
}
next_token (state);
return result;
}
static int
consume_num (parse_state *state)
{
@@ -1484,7 +1100,6 @@ static Uint8
consume_dir (parse_state *state)
{
Uint8 result = 0;
#ifdef HAVE_JOYSTICK
if (!stricmp (state->token, "left"))
{
result = SDL_HAT_LEFT;
@@ -1505,7 +1120,6 @@ consume_dir (parse_state *state)
{
expected_error (state, "left', 'right', 'up' or 'down");
}
#endif /* HAVE_JOYSTICK */
next_token (state);
return result;
}
@@ -1586,29 +1200,14 @@ parse_gesture (parse_state *state, VCONTROL_GESTURE *gesture)
gesture->type = VCONTROL_KEY;
gesture->gesture.key = keysym;
}
else if (!stricmp (state->token, "joystick"))
{
parse_joybinding (state, gesture);
}
else
{
expected_error (state, "key' or 'joystick");
}
}
}
static void
parse_binding (parse_state *state)
{
int *target = consume_idname (state);
if (!state->error)
else if (!stricmp (state->token, "joystick"))
{
VCONTROL_GESTURE g;
parse_gesture (state, &g);
if (g.type != VCONTROL_NONE)
{
VControl_AddGestureBinding (&g, target);
}
parse_joybinding (state, gesture);
}
else
{
expected_error (state, "key' or 'joystick");
}
}
@@ -1624,6 +1223,8 @@ VControl_ParseGesture (VCONTROL_GESTURE *g, const char *spec)
next_token (&ps);
parse_gesture (&ps, g);
if (ps.error)
printf ("Error parsing %s\n", spec);
}
int
@@ -1648,133 +1249,3 @@ VControl_DumpGesture (char *buf, int n, VCONTROL_GESTURE *g)
return 0;
}
}
static void
parse_config_line (parse_state *state)
{
state->error = 0;
next_token (state);
if (!state->token[0])
{
/* Blank line, skip it */
return;
}
if (!stricmp (state->token, "joystick"))
{
int sticknum, threshold = 0;
consume (state, "joystick");
sticknum = consume_num (state);
if (!state->error) consume (state, "threshold");
if (!state->error) threshold = consume_num (state);
if (!state->error)
{
if (VControl_SetJoyThreshold (sticknum, threshold))
{
// Don't count this as an error
// state->error = 1;
}
}
if (!state->error)
{
validlines++;
}
return;
}
if (!stricmp (state->token, "version"))
{
consume (state, "version");
version = consume_num (state);
if (!state->error)
{
validlines++;
}
return;
}
/* Otherwise, it must be a binding */
parse_binding (state);
if (!state->error)
{
validlines++;
}
}
int
VControl_ReadConfiguration (uio_Stream *in)
{
parse_state ps;
if (!in)
{
log_add (log_Warning, "VControl: Invalid configuration file stream");
return 1;
}
ps.linenum = 0;
errors = version = validlines = 0;
while (1)
{
next_line (&ps, in);
if (!ps.line[0])
break;
parse_config_line (&ps);
if (ps.error)
{
errors++;
}
}
return errors;
}
int
VControl_GetErrorCount (void)
{
return errors;
}
int
VControl_GetValidCount (void)
{
return validlines;
}
int
VControl_GetConfigFileVersion (void)
{
return version;
}
void
VControl_SetConfigFileVersion (int v)
{
version = v;
}
#if 0
/* This was kinda handy for proving (lack of) buffer overrun
* vulnerabilities, but there's no real need for it otherwise. */
void
VControl_TokenizeFile (FILE *in)
{
parse_state ps;
if (!in)
{
log_add (log_Warning, "VControl: Invalid configuration file stream");
return;
}
ps.linenum = 0;
while (1)
{
_next_line (&ps, in);
if (!ps.line[0])
break;
printf ("%3d:", ps.linenum);
while (1)
{
_next_token (&ps);
if (!ps.token[0])
break;
printf (" \"%s\"", ps.token);
}
printf ("\n");
}
}
#endif
-36
View File
@@ -18,7 +18,6 @@
#define _VCONTROL_H_
#include "port.h"
#include "libs/uio.h"
#include SDL_INCLUDE(SDL.h)
/* Initialization routines */
@@ -80,45 +79,10 @@ void VControl_ProcessJoyHat (int port, int which, Uint8 value);
/* Force the input into the blank state. For preventing "sticky" keys. */
void VControl_ResetInput (void);
/* Name control. To provide a table of names and bindings, declare
* a persistent, unchanging array of VControl_NameBinding and end it
* with a {0, 0} entry. Pass this array to VControl_RegisterNameTable.
* Only one name table may be registered at a time; subsequent calls
* replace the previous values. */
typedef struct vcontrol_namebinding {
char *name;
int *target;
} VControl_NameBinding;
void VControl_RegisterNameTable (VControl_NameBinding *table);
/* Version number control */
int VControl_GetConfigFileVersion (void);
void VControl_SetConfigFileVersion (int v);
/* Translate between gestures and string representations thereof. */
void VControl_ParseGesture (VCONTROL_GESTURE *g, const char *spec);
int VControl_DumpGesture (char *buf, int n, VCONTROL_GESTURE *g);
/* Dump a configuration file corresponding to the current bindings and names. */
void VControl_Dump (uio_Stream *out);
void VControl_SaveFilename (uio_DirHandle *path, const char *fname);
/* Read a configuration file. Returns number of errors encountered. */
int VControl_ReadConfiguration (uio_Stream *in);
int VControl_GetErrorCount (void);
int VControl_GetValidCount (void);
/* Iterator control. Start an iteration with StartIter or
StartIterByName; then call NextBindingName until it returns 0.
Produces gestures. */
void VControl_StartIter (int *target);
void VControl_StartIterByName (char *targetname);
int VControl_NextBinding (VCONTROL_GESTURE *gesture);
/* Tracking the "last interesting gesture." Used to poll to find new
control keys. */
+7 -7
View File
@@ -1360,13 +1360,13 @@ SetGlobalOptions (GLOBALOPTS *opts)
SetMusicVolume (musicVolume);
SetSpeechVolume (speechVolumeScale);
res_PutString ("config.keys.1.name", input_templates[0].name);
res_PutString ("config.keys.2.name", input_templates[1].name);
res_PutString ("config.keys.3.name", input_templates[2].name);
res_PutString ("config.keys.4.name", input_templates[3].name);
res_PutString ("config.keys.5.name", input_templates[4].name);
res_PutString ("config.keys.6.name", input_templates[5].name);
res_PutString ("keys.1.name", input_templates[0].name);
res_PutString ("keys.2.name", input_templates[1].name);
res_PutString ("keys.3.name", input_templates[2].name);
res_PutString ("keys.4.name", input_templates[3].name);
res_PutString ("keys.5.name", input_templates[4].name);
res_PutString ("keys.6.name", input_templates[5].name);
res_SaveFilename (configDir, "uqm.cfg", "config.");
SaveKeyConfiguration (configDir, "keys.cfg");
SaveKeyConfiguration (configDir, "flight.cfg");
}
+2 -16
View File
@@ -369,12 +369,7 @@ main (int argc, char *argv[])
&options.speechVolumeScale, "speech volume");
}
{ /* init control template names */
static const char* defaultNames[] =
{
"Arrows", "WASD", "Arrows (2)",
"ESDF", "Joystick 1", "Joystick 2"
};
{ /* remove old control template names */
int i;
for (i = 0; i < 6; ++i)
@@ -384,16 +379,7 @@ main (int argc, char *argv[])
snprintf(cfgkey, sizeof(cfgkey), "config.keys.%d.name", i + 1);
cfgkey[sizeof(cfgkey) - 1] = '\0';
if (res_HasKey (cfgkey))
{
strncpy (input_templates[i].name, res_GetString (cfgkey), 30);
input_templates[i].name[29] = 0;
}
else
{
strcpy (input_templates[i].name, defaultNames[i]);
res_PutString (cfgkey, input_templates[i].name);
}
res_Remove (cfgkey);
}
}