diff --git a/sc2/ChangeLog b/sc2/ChangeLog index f16927047..9233c5208 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,6 @@ Changes towards version 0.6: +- Phase 2 of online keyconfig - Setup Menu can configure assignment of + templates to players - Michael - Control scheme shifted to Menus + Control Templates in preparation for the online keyconfig - Michael - Fixes to logic in the Utwig conversations (Bugs 327, 647), from Nic diff --git a/sc2/content/lbm/setupmenu.txt b/sc2/content/lbm/setupmenu.txt index bcb568701..966e20838 100644 --- a/sc2/content/lbm/setupmenu.txt +++ b/sc2/content/lbm/setupmenu.txt @@ -29,6 +29,8 @@ Positional Audio Sound Driver Sound Quality Slave Shields +Player One +Player Two #(CAT_0_OPTS) 320x240 @@ -301,6 +303,82 @@ This mimics the PC version. Slave shields pulsate. This mimics the 3do verion. +#(CAT_18_OPTS) +Keyboard #1 +Keyboard #2 +Keyboard #3 +Joystick #1 +Joystick #2 +Joystick #3 + +#(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 + +#(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. + #(SLIDERS) Music Volume SFX Volume @@ -352,7 +430,7 @@ Currently unimplemented. #(BUTTON_6_DESC) Set up keyboard and joystick controls. -Currently unimplemented. +Currently partially implemented. #(BUTTON_7_DESC) Select underlying drivers or other @@ -360,9 +438,16 @@ hardware-dependent options. #(LABELS) Incomplete +Keyconfig incomplete #(LABEL_0) This part of the configuration 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. diff --git a/sc2/src/sc2code/controls.h b/sc2/src/sc2code/controls.h index 457b1e4a5..36958393a 100644 --- a/sc2/src/sc2code/controls.h +++ b/sc2/src/sc2code/controls.h @@ -61,7 +61,7 @@ enum { NUM_MENU_KEYS }; -enum { +typedef enum { CONTROL_TEMPLATE_KB_1, CONTROL_TEMPLATE_KB_2, CONTROL_TEMPLATE_KB_3, @@ -69,7 +69,7 @@ enum { CONTROL_TEMPLATE_JOY_2, CONTROL_TEMPLATE_JOY_3, NUM_TEMPLATES -}; +} CONTROL_TEMPLATE; typedef struct _controller_input_state { int key[NUM_TEMPLATES][NUM_KEYS]; @@ -91,6 +91,7 @@ extern battle_summary_func PlayerInput[]; extern CONTROLLER_INPUT_STATE CurrentInputState, PulsedInputState; extern volatile CONTROLLER_INPUT_STATE ImmediateInputState; +extern CONTROL_TEMPLATE PlayerOne, PlayerTwo; void UpdateInputState (void); void FlushInputState (void); diff --git a/sc2/src/sc2code/encount.c b/sc2/src/sc2code/encount.c index 1fe46ad63..0cb98c41c 100644 --- a/sc2/src/sc2code/encount.c +++ b/sc2/src/sc2code/encount.c @@ -652,10 +652,10 @@ UninitEncounter (void) while (!(AnyButtonPress (TRUE)) && GetTimeCounter () < Time) TaskSwitch (); LockMutex (GraphicsLock); - if (!CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_ESCAPE]) + if (!CurrentInputState.key[PlayerOne][KEY_ESCAPE]) { DrawFadeText (str1, str2, FALSE, &scavenge_r); - if (!CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_ESCAPE]) + if (!CurrentInputState.key[PlayerOne][KEY_ESCAPE]) { SetContextForeGroundColor (BLACK_COLOR); r.corner.x = scavenge_r.corner.x + 10; @@ -681,7 +681,7 @@ UninitEncounter (void) && GetTimeCounter () < Time) TaskSwitch (); LockMutex (GraphicsLock); - if (!CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_ESCAPE]) + if (!CurrentInputState.key[PlayerOne][KEY_ESCAPE]) DrawFadeText (str1, str2, FALSE, &scavenge_r); } } diff --git a/sc2/src/sc2code/gameinp.c b/sc2/src/sc2code/gameinp.c index c27c9e8e3..cbdc3c10d 100644 --- a/sc2/src/sc2code/gameinp.c +++ b/sc2/src/sc2code/gameinp.c @@ -49,6 +49,7 @@ typedef struct } MENU_ANNOTATIONS; +CONTROL_TEMPLATE PlayerOne, PlayerTwo; CONTROLLER_INPUT_STATE CurrentInputState, PulsedInputState; static CONTROLLER_INPUT_STATE CachedInputState, OldInputState; static MENU_ANNOTATIONS RepeatDelays, Times; @@ -381,19 +382,19 @@ BATTLE_INPUT_STATE p1_combat_summary (void) { BATTLE_INPUT_STATE InputState = 0; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_UP]) + if (CurrentInputState.key[PlayerOne][KEY_UP]) InputState |= BATTLE_THRUST; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_LEFT]) + if (CurrentInputState.key[PlayerOne][KEY_LEFT]) InputState |= BATTLE_LEFT; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_RIGHT]) + if (CurrentInputState.key[PlayerOne][KEY_RIGHT]) InputState |= BATTLE_RIGHT; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_WEAPON]) + if (CurrentInputState.key[PlayerOne][KEY_WEAPON]) InputState |= BATTLE_WEAPON; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_SPECIAL]) + if (CurrentInputState.key[PlayerOne][KEY_SPECIAL]) InputState |= BATTLE_SPECIAL; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_ESCAPE]) + if (CurrentInputState.key[PlayerOne][KEY_ESCAPE]) InputState |= BATTLE_ESCAPE; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_DOWN]) + if (CurrentInputState.key[PlayerOne][KEY_DOWN]) InputState |= BATTLE_DOWN; return InputState; } @@ -402,17 +403,17 @@ BATTLE_INPUT_STATE p2_combat_summary (void) { BATTLE_INPUT_STATE InputState = 0; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_2][KEY_UP]) + if (CurrentInputState.key[PlayerTwo][KEY_UP]) InputState |= BATTLE_THRUST; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_2][KEY_LEFT]) + if (CurrentInputState.key[PlayerTwo][KEY_LEFT]) InputState |= BATTLE_LEFT; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_2][KEY_RIGHT]) + if (CurrentInputState.key[PlayerTwo][KEY_RIGHT]) InputState |= BATTLE_RIGHT; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_2][KEY_WEAPON]) + if (CurrentInputState.key[PlayerTwo][KEY_WEAPON]) InputState |= BATTLE_WEAPON; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_2][KEY_SPECIAL]) + if (CurrentInputState.key[PlayerTwo][KEY_SPECIAL]) InputState |= BATTLE_SPECIAL; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_2][KEY_DOWN]) + if (CurrentInputState.key[PlayerTwo][KEY_DOWN]) InputState |= BATTLE_DOWN; return InputState; } diff --git a/sc2/src/sc2code/pickmele.c b/sc2/src/sc2code/pickmele.c index 8400eea71..9e2fffc95 100644 --- a/sc2/src/sc2code/pickmele.c +++ b/sc2/src/sc2code/pickmele.c @@ -76,28 +76,28 @@ DoGetMelee (GETMELEE_STATE *gms) } else if (which_player == 0) { - left = PulsedInputState.key[CONTROL_TEMPLATE_KB_1][KEY_LEFT] || + left = PulsedInputState.key[PlayerOne][KEY_LEFT] || PulsedInputState.menu[KEY_MENU_LEFT]; - right = PulsedInputState.key[CONTROL_TEMPLATE_KB_1][KEY_RIGHT] || + right = PulsedInputState.key[PlayerOne][KEY_RIGHT] || PulsedInputState.menu[KEY_MENU_RIGHT]; - up = PulsedInputState.key[CONTROL_TEMPLATE_KB_1][KEY_UP] || + up = PulsedInputState.key[PlayerOne][KEY_UP] || PulsedInputState.menu[KEY_MENU_UP]; - down = PulsedInputState.key[CONTROL_TEMPLATE_KB_1][KEY_DOWN] || + down = PulsedInputState.key[PlayerOne][KEY_DOWN] || PulsedInputState.menu[KEY_MENU_DOWN]; - select = PulsedInputState.key[CONTROL_TEMPLATE_KB_1][KEY_WEAPON] || + select = PulsedInputState.key[PlayerOne][KEY_WEAPON] || PulsedInputState.menu[KEY_MENU_SELECT]; } else { - left = PulsedInputState.key[CONTROL_TEMPLATE_KB_2][KEY_LEFT] || + left = PulsedInputState.key[PlayerTwo][KEY_LEFT] || PulsedInputState.menu[KEY_MENU_LEFT]; - right = PulsedInputState.key[CONTROL_TEMPLATE_KB_2][KEY_RIGHT] || + right = PulsedInputState.key[PlayerTwo][KEY_RIGHT] || PulsedInputState.menu[KEY_MENU_RIGHT]; - up = PulsedInputState.key[CONTROL_TEMPLATE_KB_2][KEY_UP] || + up = PulsedInputState.key[PlayerTwo][KEY_UP] || PulsedInputState.menu[KEY_MENU_UP]; - down = PulsedInputState.key[CONTROL_TEMPLATE_KB_2][KEY_DOWN] || + down = PulsedInputState.key[PlayerTwo][KEY_DOWN] || PulsedInputState.menu[KEY_MENU_DOWN]; - select = PulsedInputState.key[CONTROL_TEMPLATE_KB_2][KEY_WEAPON] || + select = PulsedInputState.key[PlayerTwo][KEY_WEAPON] || PulsedInputState.menu[KEY_MENU_SELECT]; } diff --git a/sc2/src/sc2code/planets/lander.c b/sc2/src/sc2code/planets/lander.c index 0bd1fea62..202939b9f 100644 --- a/sc2/src/sc2code/planets/lander.c +++ b/sc2/src/sc2code/planets/lander.c @@ -1625,7 +1625,7 @@ SetVelocityComponents ( } else if (pMS->delta_item == 0 || (HIBYTE (pMS->delta_item) - && (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_ESCAPE] + && (CurrentInputState.key[PlayerOne][KEY_ESCAPE] || ((PPLANETSIDE_DESC)pMenuState->ModuleFrame)->InTransit))) { if (pMS->delta_item || pMS->CurState > EXPLOSION_LIFE + 60) @@ -1686,9 +1686,9 @@ SetVelocityComponents ( index = GetFrameIndex (LanderFrame[0]); if (LONIBBLE (pMS->CurState)) pMS->CurState -= MAKE_BYTE (1, 0); - else if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_LEFT] || CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_RIGHT]) + else if (CurrentInputState.key[PlayerOne][KEY_LEFT] || CurrentInputState.key[PlayerOne][KEY_RIGHT]) { - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_LEFT]) + if (CurrentInputState.key[PlayerOne][KEY_LEFT]) { dx = -1; --index; @@ -1728,7 +1728,7 @@ SetVelocityComponents ( ); } - if (!CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_UP]) + if (!CurrentInputState.key[PlayerOne][KEY_UP]) dx = dy = 0; else GetNextVelocityComponents ( @@ -1737,7 +1737,7 @@ SetVelocityComponents ( if (HINIBBLE (pMS->CurState)) pMS->CurState -= MAKE_BYTE (0, 1); - else if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_WEAPON]) + else if (CurrentInputState.key[PlayerOne][KEY_WEAPON]) { HELEMENT hWeaponElement; @@ -1766,7 +1766,7 @@ SetVelocityComponents ( index + ANGLE_TO_FACING (FULL_CIRCLE) ); - if (!CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_UP]) + if (!CurrentInputState.key[PlayerOne][KEY_UP]) wdx = wdy = 0; else GetCurrentVelocityComponents ( diff --git a/sc2/src/sc2code/planets/solarsys.c b/sc2/src/sc2code/planets/solarsys.c index 0ad731ea9..973d44562 100644 --- a/sc2/src/sc2code/planets/solarsys.c +++ b/sc2/src/sc2code/planets/solarsys.c @@ -810,15 +810,15 @@ ProcessShipControls (void) ClockTick (); - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_UP]) + if (CurrentInputState.key[PlayerOne][KEY_UP]) delta_y = -1; else delta_y = 0; delta_x = 0; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_LEFT]) + if (CurrentInputState.key[PlayerOne][KEY_LEFT]) delta_x -= 1; - if (CurrentInputState.key[CONTROL_TEMPLATE_KB_1][KEY_RIGHT]) + if (CurrentInputState.key[PlayerOne][KEY_RIGHT]) delta_x += 1; if (delta_x || delta_y < 0) diff --git a/sc2/src/sc2code/setupmenu.c b/sc2/src/sc2code/setupmenu.c index 399cb1cb1..f18cb0d33 100644 --- a/sc2/src/sc2code/setupmenu.c +++ b/sc2/src/sc2code/setupmenu.c @@ -65,10 +65,10 @@ static int do_advanced (WIDGET *self, int event); #endif #define MENU_COUNT 7 -#define CHOICE_COUNT 18 +#define CHOICE_COUNT 20 #define SLIDER_COUNT 3 #define BUTTON_COUNT 8 -#define LABEL_COUNT 1 +#define LABEL_COUNT 2 /* The space for our widgets */ static WIDGET_MENU_SCREEN menus[MENU_COUNT]; @@ -83,14 +83,15 @@ 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 }; + 2, 2, 2, 3, 2, 2, 3, 3, 2, + 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 }; static int menu_sizes[MENU_COUNT] = { - 7, 5, 6, 9, 2, 2, + 7, 5, 6, 9, 2, 4, #ifdef HAVE_OPENGL 5 }; #else @@ -145,13 +146,19 @@ static WIDGET *advanced_widgets[] = { (WIDGET *)(&choices[16]), (WIDGET *)(&buttons[1]) }; +static WIDGET *keyconfig_widgets[] = { + (WIDGET *)(&choices[18]), + (WIDGET *)(&choices[19]), + (WIDGET *)(&labels[1]), + (WIDGET *)(&buttons[1]) }; + 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, incomplete_widgets, advanced_widgets }; + incomplete_widgets, keyconfig_widgets, advanced_widgets }; static int quit_main_menu (WIDGET *self, int event) @@ -293,6 +300,8 @@ SetDefaults (void) choices[15].selected = opts.adriver; choices[16].selected = opts.aquality; choices[17].selected = opts.shield; + choices[18].selected = opts.player1; + choices[19].selected = opts.player2; sliders[0].value = opts.musicvol; sliders[1].value = opts.sfxvol; @@ -321,6 +330,8 @@ PropagateResults (void) opts.adriver = choices[15].selected; opts.aquality = choices[16].selected; opts.shield = choices[17].selected; + opts.player1 = choices[18].selected; + opts.player2 = choices[19].selected; opts.musicvol = sliders[0].value; opts.sfxvol = sliders[1].value; @@ -887,9 +898,13 @@ GetGlobalOptions (GLOBALOPTS *opts) } } + opts->player1 = PlayerOne; + opts->player2 = PlayerTwo; + opts->musicvol = (((int)(musicVolumeScale * 100.0f) + 2) / 5) * 5; opts->sfxvol = (((int)(sfxVolumeScale * 100.0f) + 2) / 5) * 5; opts->speechvol = (((int)(speechVolumeScale * 100.0f) + 2) / 5) * 5; + } void @@ -999,6 +1014,8 @@ SetGlobalOptions (GLOBALOPTS *opts) optWhichShield = (opts->shield == OPTVAL_3DO) ? OPT_3DO : OPT_PC; optMeleeScale = (opts->meleezoom == OPTVAL_3DO) ? TFB_SCALE_TRILINEAR : TFB_SCALE_STEP; optWhichIntro = (opts->intro == OPTVAL_3DO) ? OPT_3DO : OPT_PC; + PlayerOne = opts->player1; + PlayerTwo = opts->player2; res_PutBoolean ("config.subtitles", opts->subtitles == OPTVAL_ENABLED); res_PutBoolean ("config.textmenu", opts->menu == OPTVAL_PC); @@ -1012,6 +1029,8 @@ SetGlobalOptions (GLOBALOPTS *opts) res_PutBoolean ("config.smoothmelee", opts->meleezoom == OPTVAL_3DO); res_PutBoolean ("config.positionalsfx", opts->stereo == OPTVAL_ENABLED); res_PutBoolean ("config.pulseshield", opts->shield == OPTVAL_3DO); + res_PutInteger ("config.player1control", opts->player1); + res_PutInteger ("config.player2control", opts->player2); switch (opts->adriver) { case OPTVAL_SILENCE: diff --git a/sc2/src/sc2code/setupmenu.h b/sc2/src/sc2code/setupmenu.h index ea09ab249..3667020dd 100644 --- a/sc2/src/sc2code/setupmenu.h +++ b/sc2/src/sc2code/setupmenu.h @@ -19,6 +19,8 @@ #ifndef _SETUPMENU_H #define _SETUPMENU_H +#include "controls.h" + typedef enum { OPTVAL_DISABLED, OPTVAL_ENABLED @@ -63,6 +65,9 @@ typedef enum { OPTVAL_HIGH } OPT_AQUALITYTYPE; +/* At the moment, CONTROL_TEMPLATE is directly in this structure. If + * CONTROL_TEMPLATE and the options available diverge, this will need + * to change */ typedef struct globalopts_struct { OPT_SCALETYPE scaler; OPT_RESTYPE res; @@ -71,6 +76,7 @@ typedef struct globalopts_struct { OPT_AQUALITYTYPE aquality; OPT_ENABLABLE fullscreen, subtitles, scanlines, fps, stereo; OPT_CONSOLETYPE music, menu, text, cscan, scroll, intro, meleezoom, shield; + CONTROL_TEMPLATE player1, player2; int speechvol, musicvol, sfxvol; } GLOBALOPTS; diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index 020d2ff7c..160466188 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -30,6 +30,7 @@ #include "libs/sound/sound.h" #include "libs/input/input_common.h" #include "libs/tasklib.h" +#include "controls.h" #include "file.h" #include "port.h" #include "libs/platform.h" @@ -173,6 +174,9 @@ main (int argc, char *argv[]) initIO (); prepareConfigDir (options.configDir); + PlayerOne = CONTROL_TEMPLATE_KB_1; + PlayerTwo = CONTROL_TEMPLATE_KB_2; + // Fill in the options struct based on uqm.cfg res_LoadFilename (configDir, "uqm.cfg"); if (res_HasKey ("config.reswidth")) @@ -309,6 +313,26 @@ main (int argc, char *argv[]) { options.whichShield = res_GetBoolean ("config.pulseshield") ? OPT_3DO : OPT_PC; } + if (res_HasKey ("config.player1control")) + { + PlayerOne = res_GetInteger ("config.player1control"); + /* This is an unsigned, so no < 0 check is necessary */ + if (PlayerOne >= NUM_TEMPLATES) + { + fprintf (stderr, "Illegal control template '%d' for Player One.\n", PlayerOne); + PlayerOne = CONTROL_TEMPLATE_KB_1; + } + } + if (res_HasKey ("config.player2control")) + { + /* This is an unsigned, so no < 0 check is necessary */ + PlayerTwo = res_GetInteger ("config.player2control"); + if (PlayerOne >= NUM_TEMPLATES) + { + fprintf (stderr, "Illegal control template '%d' for Player Two.\n", PlayerOne); + PlayerTwo = CONTROL_TEMPLATE_KB_2; + } + } if (res_HasKey ("config.musicvol")) { parseVolume(res_GetString ("config.musicvol"),