Next phase of online keyconfig; editable names of templates, and

some other groundwork for the next steps.


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2424 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2006-08-27 15:01:37 +00:00
parent b5d6c11bcd
commit e0366a964f
9 changed files with 268 additions and 53 deletions
+1
View File
@@ -1,4 +1,5 @@
Changes towards version 0.6:
- Input templates can now be renamed, both online and off - Michael
- Fixed an integer-size error that was causing crashes on AMD64, from
Solomon Peachy (#895) - Michael
- Added some generic lib code to be used by future code. - SvdB
+61 -29
View File
@@ -9,6 +9,7 @@ Audio Options
Resources Options
Controls Setup
Advanced Options
Edit Controls
#(CHOICES)
Resolution
@@ -31,6 +32,7 @@ Sound Quality
Slave Shields
Player One
Player Two
Control Set
#(CAT_0_OPTS)
320x240
@@ -304,81 +306,95 @@ Slave shields pulsate.
This mimics the 3do verion.
#(CAT_18_OPTS)
Keyboard #1
Keyboard #2
Keyboard #3
Joystick #1
Joystick #2
Joystick #3
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
#(CAT_18_OPT_0_DESC)
Player 1 uses the Keyboard 1 template.
Player 1 controls the bottom player in
Super Melee, and the entire Full Game.
#(CAT_18_OPT_1_DESC)
Player 1 uses the Keyboard 2 template.
Player 1 controls the bottom player in
Super Melee, and the entire Full Game.
#(CAT_18_OPT_2_DESC)
Player 1 uses the Keyboard 3 template.
Player 1 controls the bottom player in
Super Melee, and the entire Full Game.
#(CAT_18_OPT_3_DESC)
Player 1 uses the Joystick 1 template.
Player 1 controls the bottom player in
Super Melee, and the entire Full Game.
#(CAT_18_OPT_4_DESC)
Player 1 uses the Joystick 2 template.
Player 1 controls the bottom player in
Super Melee, and the entire Full Game.
#(CAT_18_OPT_5_DESC)
Player 1 uses the Joystick 3 template.
Player 1 controls the bottom player in
Super Melee, and the entire Full Game.
#(CAT_19_OPTS)
Keyboard #1
Keyboard #2
Keyboard #3
Joystick #1
Joystick #2
Joystick #3
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
#(CAT_19_OPT_0_DESC)
Player 2 uses the Keyboard 1 template.
Player 2 controls the top player
in Super Melee.
#(CAT_19_OPT_1_DESC)
Player 2 uses the Keyboard 2 template.
Player 2 controls the top player
in Super Melee.
#(CAT_19_OPT_2_DESC)
Player 2 uses the Keyboard 3 template.
Player 2 controls the top player
in Super Melee.
#(CAT_19_OPT_3_DESC)
Player 2 uses the Joystick 1 template.
Player 2 controls the top player
in Super Melee.
#(CAT_19_OPT_4_DESC)
Player 2 uses the Joystick 2 template.
Player 2 controls the top player
in Super Melee.
#(CAT_19_OPT_5_DESC)
Player 2 uses the Joystick 3 template.
Player 2 controls the top player
in Super Melee.
#(CAT_20_OPTS)
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
#(CAT_20_OPT_0_DESC)
Select the control template to edit.
#(CAT_20_OPT_1_DESC)
Select the control template to edit.
#(CAT_20_OPT_2_DESC)
Select the control template to edit.
#(CAT_20_OPT_3_DESC)
Select the control template to edit.
#(CAT_20_OPT_4_DESC)
Select the control template to edit.
#(CAT_20_OPT_5_DESC)
Select the control template to edit.
#(SLIDERS)
Music Volume
SFX Volume
@@ -402,6 +418,8 @@ Sound Options
Resources Options
Configure Controls
Advanced Options
Edit Controls
Back to Control Select
#(BUTTON_0_DESC)
Return to the main menu.
@@ -436,9 +454,16 @@ Currently partially implemented.
Select underlying drivers or other
hardware-dependent options.
#(BUTTON_8_DESC)
Edit key control sets.
#(BUTTON_9_DESC)
Return to control set selection screen.
#(LABELS)
Incomplete
Keyconfig incomplete
Keyconfig header
Editkey header
#(LABEL_0)
This part of the configuration
@@ -447,7 +472,14 @@ has not yet been implemented.
Expect it in a future version.
#(LABEL_1)
Control templates are currently defined
in the KEYS.CFG file stored near your
save games. A future UQM version will
offer in-game key configuration.
To view or edit key controls,
select the option below:
#(LABEL_2)
Controls
#(TEXT_ENTRIES)
Name
#(TEXT_ENTRIES_INITIAL)
Placeholder
+1
View File
@@ -58,6 +58,7 @@ uio_DirList *availableAddons;
extern uio_Repository *repository;
extern uio_DirHandle *rootDir;
INPUT_TEMPLATE input_templates[6];
static const char *findFileInDirs (const char *locs[], int numLocs,
const char *file);
+13
View File
@@ -49,6 +49,19 @@ extern uio_DirHandle *meleeDir;
extern uio_DirList *availableAddons;
/* These get edited by TEXTENTRY widgets, so they should have room to
* hold as much as one of them allows by default. */
typedef struct _input_template {
char name[30];
/* This should eventually also hold things like Joystick Port
* and whether or not joysticks are enabled at all, and
* possibly the whole configuration scheme. If we do that, we
* can actually ditch much of VControl. */
} INPUT_TEMPLATE;
extern INPUT_TEMPLATE input_templates[6];
void prepareContentDir (const char *contentDirName, const char **addons);
void prepareConfigDir (const char *configDirName);
void prepareMeleeDir (void);
+7
View File
@@ -600,8 +600,15 @@ Widget_HandleEventChoice (WIDGET *_self, int event)
self->highlighted = 0;
return TRUE;
case WIDGET_EVENT_SELECT:
{
int oldval = self->selected;
self->selected = self->highlighted;
if (self->onChange)
{
(*(self->onChange))(self, oldval);
}
return TRUE;
}
default:
return FALSE;
}
+2
View File
@@ -74,6 +74,7 @@ typedef struct _widget_choice {
int maxcolumns;
CHOICE_OPTION *options;
int selected, highlighted;
void (*onChange)(struct _widget_choice *self, int oldval);
} WIDGET_CHOICE;
typedef struct _widget_button {
@@ -130,6 +131,7 @@ typedef struct _widget_textentry {
// handleEventSelect is an overridable callback event
// called by the default handleEvent implementation
// can be NULL, in which case SELECT is ignored
void (*onChange)(struct _widget_textentry *self);
const char *category;
char value[WIDGET_TEXTENTRY_WIDTH];
int maxlen;
@@ -20,4 +20,3 @@
#include "inpintrn.h"
volatile BOOLEAN ExitRequested, GamePaused;
+123 -23
View File
@@ -58,6 +58,10 @@ static int do_engine (WIDGET *self, int event);
static int do_resources (WIDGET *self, int event);
static int do_keyconfig (WIDGET *self, int event);
static int do_advanced (WIDGET *self, int event);
static int do_editkeys (WIDGET *self, int event);
static void change_template (WIDGET_CHOICE *self, int oldval);
static void rename_template (WIDGET_TEXTENTRY *self);
#ifdef HAVE_OPENGL
#define RES_OPTS 4
@@ -65,11 +69,11 @@ static int do_advanced (WIDGET *self, int event);
#define RES_OPTS 2
#endif
#define MENU_COUNT 7
#define CHOICE_COUNT 20
#define MENU_COUNT 8
#define CHOICE_COUNT 21
#define SLIDER_COUNT 3
#define BUTTON_COUNT 8
#define LABEL_COUNT 2
#define BUTTON_COUNT 10
#define LABEL_COUNT 3
#define TEXTENTRY_COUNT 1
/* The space for our widgets */
@@ -85,23 +89,26 @@ static WIDGET_TEXTENTRY textentries[TEXTENTRY_COUNT];
typedef int (*HANDLER)(WIDGET *, int);
static int choice_widths[CHOICE_COUNT] = {
3, 2, 3, 3, 2, 2, 2, 2, 2,
2, 2, 2, 3, 2, 2, 3, 3, 2,
3, 3 };
3, 2, 3, 3, 2, 2, 2, 2, 2, 2,
2, 2, 3, 2, 2, 3, 3, 2, 3, 3,
3 };
static HANDLER button_handlers[BUTTON_COUNT] = {
quit_main_menu, quit_sub_menu, do_graphics, do_engine,
do_audio, do_resources, do_keyconfig, do_advanced };
do_audio, do_resources, do_keyconfig, do_advanced, do_editkeys,
do_keyconfig };
static int menu_sizes[MENU_COUNT] = {
8, 5, 6, 9, 2, 4,
7, 5, 6, 9, 2, 5,
#ifdef HAVE_OPENGL
5 };
5,
#else
4 };
4,
#endif
4
};
static int menu_bgs[MENU_COUNT] = { 0, 1, 1, 2, 3, 1, 2 };
static int menu_bgs[MENU_COUNT] = { 0, 1, 1, 2, 3, 1, 2, 1 };
/* These refer to uninitialized widgets, but that's OK; we'll fill
* them in before we touch them */
@@ -112,7 +119,6 @@ static WIDGET *main_widgets[] = {
(WIDGET *)(&buttons[5]),
(WIDGET *)(&buttons[6]),
(WIDGET *)(&buttons[7]),
(WIDGET *)(&textentries[0]),
(WIDGET *)(&buttons[0]) };
static WIDGET *graphics_widgets[] = {
@@ -154,15 +160,22 @@ static WIDGET *keyconfig_widgets[] = {
(WIDGET *)(&choices[18]),
(WIDGET *)(&choices[19]),
(WIDGET *)(&labels[1]),
(WIDGET *)(&buttons[8]),
(WIDGET *)(&buttons[1]) };
static WIDGET *editkeys_widgets[] = {
(WIDGET *)(&choices[20]),
(WIDGET *)(&labels[2]),
(WIDGET *)(&textentries[0]),
(WIDGET *)(&buttons[9]) };
static WIDGET *incomplete_widgets[] = {
(WIDGET *)(&labels[0]),
(WIDGET *)(&buttons[1]) };
static WIDGET **menu_widgets[MENU_COUNT] = {
main_widgets, graphics_widgets, audio_widgets, engine_widgets,
incomplete_widgets, keyconfig_widgets, advanced_widgets };
incomplete_widgets, keyconfig_widgets, advanced_widgets, editkeys_widgets };
static int
quit_main_menu (WIDGET *self, int event)
@@ -267,6 +280,39 @@ do_advanced (WIDGET *self, int event)
return FALSE;
}
static int
do_editkeys (WIDGET *self, int event)
{
if (event == WIDGET_EVENT_SELECT)
{
next = (WIDGET *)(&menus[7]);
/* Prepare the components */
choices[20].selected = 0;
strncpy (textentries[0].value, input_templates[0].name, textentries[0].maxlen);
textentries[0].value[textentries[0].maxlen] = 0;
(*next->receiveFocus) (next, WIDGET_EVENT_DOWN);
return TRUE;
}
(void)self;
return FALSE;
}
static void
change_template (WIDGET_CHOICE *self, int oldval)
{
strncpy (textentries[0].value, input_templates[self->selected].name, WIDGET_TEXTENTRY_WIDTH);
textentries[0].value[WIDGET_TEXTENTRY_WIDTH-1] = 0;
}
static void
rename_template (WIDGET_TEXTENTRY *self)
{
strncpy (input_templates[choices[20].selected].name, self->value, WIDGET_TEXTENTRY_WIDTH);
/* TODO: This will have to change if the size of the input_templates name is changed */
input_templates[choices[20].selected].name[WIDGET_TEXTENTRY_WIDTH-1] = 0;
}
#define NUM_STEPS 20
#define X_STEP (SCREEN_WIDTH / NUM_STEPS)
#define Y_STEP (SCREEN_HEIGHT / NUM_STEPS)
@@ -306,6 +352,7 @@ SetDefaults (void)
choices[17].selected = opts.shield;
choices[18].selected = opts.player1;
choices[19].selected = opts.player2;
choices[20].selected = 0;
sliders[0].value = opts.musicvol;
sliders[1].value = opts.sfxvol;
@@ -474,6 +521,13 @@ OnTextEntryEvent (WIDGET_TEXTENTRY *widget)
{ // editing failed (canceled) -- revert the changes
utf8StringCopy (widget->value, widget->maxlen, revert_buf);
}
else
{
if (widget->onChange)
{
(*(widget->onChange))(widget);
}
}
widget->state = WTE_NORMAL;
redraw_menu ();
@@ -539,7 +593,6 @@ init_widgets (void)
/* Options */
if (SplitString (GetStringAddress (SetAbsStringTableIndex (SetupTab, 2)), '\n', 100, buffer, bank) != CHOICE_COUNT)
{
/* TODO: Ignore extras instead of dying. */
log_add (log_Fatal, "PANIC: Incorrect number of Choice Options");
exit (EXIT_FAILURE);
}
@@ -558,6 +611,7 @@ init_widgets (void)
choices[i].selected = 0;
choices[i].highlighted = 0;
choices[i].maxcolumns = choice_widths[i];
choices[i].onChange = NULL;
}
/* Fill in the options now */
@@ -607,6 +661,17 @@ init_widgets (void)
/* The first choice is resolution, and is handled specially */
choices[0].numopts = RES_OPTS;
/* Choices 18-20 are also special, being the names of the key configurations */
for (i = 0; i < 6; i++)
{
choices[18].options[i].optname = input_templates[i].name;
choices[19].options[i].optname = input_templates[i].name;
choices[20].options[i].optname = input_templates[i].name;
}
/* Choice 20 has a special onChange handler, too. */
choices[20].onChange = change_template;
/* Sliders */
if (index >= count)
{
@@ -755,14 +820,18 @@ init_widgets (void)
}
}
/* Check for garbage at the end */
if (index < count)
/* Text Entry boxes */
if (index >= count)
{
log_add (log_Warning, "WARNING: Setup strings had %d garbage entries at the end.",
count - index);
log_add (log_Fatal, "PANIC: String table cut short while reading text entries");
exit (EXIT_FAILURE);
}
/* Hardcode the test textentry for now. */
if (SplitString (GetStringAddress (SetAbsStringTableIndex (SetupTab, index++)), '\n', 100, buffer, bank) != TEXTENTRY_COUNT)
{
log_add (log_Fatal, "PANIC: Incorrect number of Text Entries");
exit (EXIT_FAILURE);
}
for (i = 0; i < TEXTENTRY_COUNT; i++)
{
textentries[i].parent = NULL;
@@ -772,15 +841,38 @@ init_widgets (void)
textentries[i].height = Widget_HeightOneLine;
textentries[i].width = Widget_WidthFullScreen;
textentries[i].handleEventSelect = OnTextEntryEvent;
textentries[i].category = NULL;
textentries[i].category = buffer[i];
textentries[i].value[0] = 0;
textentries[i].maxlen = WIDGET_TEXTENTRY_WIDTH-1;
textentries[i].state = WTE_NORMAL;
textentries[i].cursor_pos = 0;
}
textentries[0].category = "TestText";
strcpy (textentries[0].value, "Sample value");
if (index >= count)
{
log_add (log_Fatal, "PANIC: String table cut short while reading text entries");
exit (EXIT_FAILURE);
}
if (SplitString (GetStringAddress (SetAbsStringTableIndex (SetupTab, index++)), '\n', 100, buffer, bank) != TEXTENTRY_COUNT)
{
/* TODO: Ignore extras instead of dying. */
log_add (log_Fatal, "PANIC: Incorrect number of Text Entries");
exit (EXIT_FAILURE);
}
for (i = 0; i < TEXTENTRY_COUNT; i++)
{
strncpy (textentries[i].value, buffer[i], textentries[i].maxlen);
textentries[i].value[textentries[i].maxlen] = 0;
}
textentries[0].onChange = rename_template;
/* Check for garbage at the end */
if (index < count)
{
log_add (log_Warning, "WARNING: Setup strings had %d garbage entries at the end.",
count - index);
}
}
static void
@@ -1015,6 +1107,7 @@ SetGlobalOptions (GLOBALOPTS *opts)
int NewWidth = ScreenWidthActual;
int NewHeight = ScreenHeightActual;
int NewDriver = GraphicsDriver;
int i;
NewGfxFlags &= ~TFB_GFXFLAGS_SCALE_ANY;
@@ -1172,5 +1265,12 @@ 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_SaveFilename (configDir, "uqm.cfg", "config.");
}
+60
View File
@@ -354,6 +354,66 @@ main (int argc, char *argv[])
parseVolume (res_GetString ("config.speechvol"),
&options.speechVolumeScale, "speech volume");
}
if (res_HasKey ("config.keys.1.name"))
{
strncpy(input_templates[0].name, res_GetString ("config.keys.1.name"), 30);
input_templates[0].name[29] = 0;
}
else
{
strcpy (input_templates[0].name, "Keyboard 1");
res_PutString ("config.keys.1.name", input_templates[0].name);
}
if (res_HasKey ("config.keys.2.name"))
{
strncpy(input_templates[1].name, res_GetString ("config.keys.2.name"), 30);
input_templates[1].name[29] = 0;
}
else
{
strcpy (input_templates[1].name, "Keyboard 2");
res_PutString ("config.keys.2.name", input_templates[1].name);
}
if (res_HasKey ("config.keys.3.name"))
{
strncpy(input_templates[2].name, res_GetString ("config.keys.3.name"), 30);
input_templates[2].name[29] = 0;
}
else
{
strcpy (input_templates[2].name, "Keyboard 3");
res_PutString ("config.keys.3.name", input_templates[2].name);
}
if (res_HasKey ("config.keys.4.name"))
{
strncpy(input_templates[3].name, res_GetString ("config.keys.4.name"), 30);
input_templates[3].name[29] = 0;
}
else
{
strcpy (input_templates[3].name, "Joystick 1");
res_PutString ("config.keys.4.name", input_templates[3].name);
}
if (res_HasKey ("config.keys.5.name"))
{
strncpy(input_templates[4].name, res_GetString ("config.keys.5.name"), 30);
input_templates[4].name[29] = 0;
}
else
{
strcpy (input_templates[4].name, "Joystick 2");
res_PutString ("config.keys.5.name", input_templates[4].name);
}
if (res_HasKey ("config.keys.6.name"))
{
strncpy(input_templates[5].name, res_GetString ("config.keys.6.name"), 30);
input_templates[5].name[29] = 0;
}
else
{
strcpy (input_templates[5].name, "Joystick 3");
res_PutString ("config.keys.6.name", input_templates[5].name);
}
optionsResult = parseOptions (argc, argv, &options);
if (optionsResult != 0)