Merge branch 'control-switching' into 'master'

Game control switching

See merge request STJr/SRB2Internal!202
This commit is contained in:
Digiku 2018-11-13 10:48:18 -05:00
commit fae095f9e8
5 changed files with 196 additions and 47 deletions

View file

@ -129,6 +129,10 @@ extern INT16 titlemap;
extern boolean hidetitlepics; extern boolean hidetitlepics;
extern INT16 bootmap; //bootmap for loading a map on startup extern INT16 bootmap; //bootmap for loading a map on startup
extern INT16 tutorialmap; // map to load for tutorial
extern boolean tutorialmode; // are we in a tutorial right now?
extern INT32 tutorialgcs; // which control scheme is loaded?
extern boolean looptitle; extern boolean looptitle;
// CTF colors. // CTF colors.

View file

@ -127,6 +127,10 @@ INT16 titlemap = 0;
boolean hidetitlepics = false; boolean hidetitlepics = false;
INT16 bootmap; //bootmap for loading a map on startup INT16 bootmap; //bootmap for loading a map on startup
INT16 tutorialmap = 0; // map to load for tutorial
boolean tutorialmode = false; // are we in a tutorial right now?
INT32 tutorialgcs = gcs_custom; // which control scheme is loaded?
boolean looptitle = false; boolean looptitle = false;
UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_redteam = SKINCOLOR_RED;

View file

@ -45,6 +45,47 @@ UINT8 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control // two key codes (or virtual key) per game control
INT32 gamecontrol[num_gamecontrols][2]; INT32 gamecontrol[num_gamecontrols][2];
INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player
INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention
// lists of GC codes for selective operation
const INT32 gcl_tutorial_check[num_gcl_tutorial_check] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
gc_turnleft, gc_turnright
};
const INT32 gcl_tutorial_used[num_gcl_tutorial_used] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
gc_turnleft, gc_turnright,
gc_jump, gc_use
};
const INT32 gcl_tutorial_full[num_gcl_tutorial_full] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
gc_lookup, gc_lookdown, gc_turnleft, gc_turnright, gc_centerview,
gc_jump, gc_use,
gc_fire, gc_firenormal
};
const INT32 gcl_movement[num_gcl_movement] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight
};
const INT32 gcl_camera[num_gcl_camera] = {
gc_turnleft, gc_turnright
};
const INT32 gcl_movement_camera[num_gcl_movement_camera] = {
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
gc_turnleft, gc_turnright
};
const INT32 gcl_jump[num_gcl_jump] = { gc_jump };
const INT32 gcl_use[num_gcl_use] = { gc_use };
const INT32 gcl_jump_use[num_gcl_jump_use] = {
gc_jump, gc_use
};
typedef struct typedef struct
{ {
@ -611,55 +652,117 @@ INT32 G_KeyStringtoNum(const char *keystr)
return 0; return 0;
} }
void G_Controldefault(void) void G_DefineDefaultControls(void)
{ {
gamecontrol[gc_forward ][0] = 'w'; INT32 i;
gamecontrol[gc_backward ][0] = 's';
gamecontrol[gc_strafeleft ][0] = 'a'; // FPS game controls (WASD)
gamecontrol[gc_straferight][0] = 'd'; gamecontroldefault[gcs_fps][gc_forward ][0] = 'w';
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW; gamecontroldefault[gcs_fps][gc_backward ][0] = 's';
gamecontrol[gc_turnright ][0] = KEY_RIGHTARROW; gamecontroldefault[gcs_fps][gc_strafeleft ][0] = 'a';
gamecontrol[gc_weaponnext ][0] = 'e'; gamecontroldefault[gcs_fps][gc_straferight][0] = 'd';
gamecontrol[gc_weaponprev ][0] = 'q'; gamecontroldefault[gcs_fps][gc_lookup ][0] = KEY_UPARROW;
gamecontrol[gc_wepslot1 ][0] = '1'; gamecontroldefault[gcs_fps][gc_lookdown ][0] = KEY_DOWNARROW;
gamecontrol[gc_wepslot2 ][0] = '2'; gamecontroldefault[gcs_fps][gc_turnleft ][0] = KEY_LEFTARROW;
gamecontrol[gc_wepslot3 ][0] = '3'; gamecontroldefault[gcs_fps][gc_turnright ][0] = KEY_RIGHTARROW;
gamecontrol[gc_wepslot4 ][0] = '4'; gamecontroldefault[gcs_fps][gc_centerview ][0] = KEY_END;
gamecontrol[gc_wepslot5 ][0] = '5'; gamecontroldefault[gcs_fps][gc_jump ][0] = KEY_SPACE;
gamecontrol[gc_wepslot6 ][0] = '6'; gamecontroldefault[gcs_fps][gc_use ][0] = KEY_LSHIFT;
gamecontrol[gc_wepslot7 ][0] = '7'; gamecontroldefault[gcs_fps][gc_fire ][0] = KEY_RCTRL;
gamecontrol[gc_wepslot8 ][0] = '8'; gamecontroldefault[gcs_fps][gc_fire ][1] = KEY_MOUSE1+0;
gamecontrol[gc_wepslot9 ][0] = '9'; gamecontroldefault[gcs_fps][gc_firenormal ][0] = 'c';
gamecontrol[gc_wepslot10 ][0] = '0';
gamecontrol[gc_fire ][0] = KEY_RCTRL; // Platform game controls (arrow keys)
gamecontrol[gc_fire ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_platform][gc_forward ][0] = KEY_UPARROW;
gamecontrol[gc_firenormal ][0] = 'c'; gamecontroldefault[gcs_platform][gc_backward ][0] = KEY_DOWNARROW;
gamecontrol[gc_tossflag ][0] = '\''; gamecontroldefault[gcs_platform][gc_strafeleft ][0] = 'a';
gamecontrol[gc_use ][0] = KEY_LSHIFT; gamecontroldefault[gcs_platform][gc_straferight][0] = 'd';
gamecontrol[gc_camtoggle ][0] = 'v'; gamecontroldefault[gcs_platform][gc_lookup ][0] = KEY_PGUP;
gamecontrol[gc_camreset ][0] = 'r'; gamecontroldefault[gcs_platform][gc_lookdown ][0] = KEY_PGDN;
gamecontrol[gc_lookup ][0] = KEY_UPARROW; gamecontroldefault[gcs_platform][gc_turnleft ][0] = KEY_LEFTARROW;
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW; gamecontroldefault[gcs_platform][gc_turnright ][0] = KEY_RIGHTARROW;
gamecontrol[gc_centerview ][0] = KEY_END; gamecontroldefault[gcs_platform][gc_centerview ][0] = KEY_END;
gamecontrol[gc_talkkey ][0] = 't'; gamecontroldefault[gcs_platform][gc_jump ][0] = KEY_SPACE;
gamecontrol[gc_teamkey ][0] = 'y'; gamecontroldefault[gcs_platform][gc_use ][0] = KEY_LSHIFT;
gamecontrol[gc_scores ][0] = KEY_TAB; gamecontroldefault[gcs_platform][gc_fire ][0] = 's';
gamecontrol[gc_jump ][0] = KEY_SPACE; gamecontroldefault[gcs_platform][gc_fire ][1] = KEY_MOUSE1+0;
gamecontrol[gc_console ][0] = KEY_CONSOLE; gamecontroldefault[gcs_platform][gc_firenormal ][0] = 'w';
gamecontrol[gc_pause ][0] = KEY_PAUSE;
for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0)
{
gamecontroldefault[i][gc_weaponnext ][0] = 'e';
gamecontroldefault[i][gc_weaponprev ][0] = 'q';
gamecontroldefault[i][gc_wepslot1 ][0] = '1';
gamecontroldefault[i][gc_wepslot2 ][0] = '2';
gamecontroldefault[i][gc_wepslot3 ][0] = '3';
gamecontroldefault[i][gc_wepslot4 ][0] = '4';
gamecontroldefault[i][gc_wepslot5 ][0] = '5';
gamecontroldefault[i][gc_wepslot6 ][0] = '6';
gamecontroldefault[i][gc_wepslot7 ][0] = '7';
gamecontroldefault[i][gc_wepslot8 ][0] = '8';
gamecontroldefault[i][gc_wepslot9 ][0] = '9';
gamecontroldefault[i][gc_wepslot10 ][0] = '0';
gamecontroldefault[i][gc_tossflag ][0] = '\'';
gamecontroldefault[i][gc_camtoggle ][0] = 'v';
gamecontroldefault[i][gc_camreset ][0] = 'r';
gamecontroldefault[i][gc_talkkey ][0] = 't';
gamecontroldefault[i][gc_teamkey ][0] = 'y';
gamecontroldefault[i][gc_scores ][0] = KEY_TAB;
gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE;
gamecontroldefault[i][gc_pause ][0] = KEY_PAUSE;
}
} }
void G_SaveKeySetting(FILE *f) INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen)
{
INT32 i, j, gc;
boolean skipscheme;
for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0)
{
skipscheme = false;
for (j = 0; j < (gclist && gclen ? gclen : num_gamecontrols); j++)
{
gc = (gclist && gclen) ? gclist[j] : j;
if (((fromcontrols[gc][0] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][0] : true) &&
((fromcontrols[gc][0] && gamecontroldefault[i][gc][1]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][1] : true) &&
((fromcontrols[gc][1] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][1] != gamecontroldefault[i][gc][0] : true) &&
((fromcontrols[gc][1] && gamecontroldefault[i][gc][1]) ? fromcontrols[gc][1] != gamecontroldefault[i][gc][1] : true))
{
skipscheme = true;
break;
}
}
if (!skipscheme)
return i;
}
return gcs_custom;
}
void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen)
{
INT32 i, gc;
for (i = 0; i < (gclist && gclen ? gclen : num_gamecontrols); i++)
{
gc = (gclist && gclen) ? gclist[i] : i;
setupcontrols[gc][0] = fromcontrols[gc][0];
setupcontrols[gc][1] = fromcontrols[gc][1];
}
}
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2])
{ {
INT32 i; INT32 i;
for (i = 1; i < num_gamecontrols; i++) for (i = 1; i < num_gamecontrols; i++)
{ {
fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(gamecontrol[i][0])); G_KeynumToString(fromcontrols[i][0]));
if (gamecontrol[i][1]) if (fromcontrols[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol[i][1])); fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1]));
else else
fprintf(f, "\n"); fprintf(f, "\n");
} }
@ -667,10 +770,10 @@ void G_SaveKeySetting(FILE *f)
for (i = 1; i < num_gamecontrols; i++) for (i = 1; i < num_gamecontrols; i++)
{ {
fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i],
G_KeynumToString(gamecontrolbis[i][0])); G_KeynumToString(fromcontrolsbis[i][0]));
if (gamecontrolbis[i][1]) if (fromcontrolsbis[i][1])
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1])); fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1]));
else else
fprintf(f, "\n"); fprintf(f, "\n");
} }

View file

@ -99,6 +99,14 @@ typedef enum
num_gamecontrols num_gamecontrols
} gamecontrols_e; } gamecontrols_e;
typedef enum
{
gcs_custom,
gcs_fps,
gcs_platform,
num_gamecontrolschemes
} gamecontrolschemes_e;
// mouse values are used once // mouse values are used once
extern consvar_t cv_mousesens, cv_mouseysens; extern consvar_t cv_mousesens, cv_mouseysens;
extern consvar_t cv_mousesens2, cv_mouseysens2; extern consvar_t cv_mousesens2, cv_mouseysens2;
@ -116,9 +124,30 @@ extern UINT8 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control // two key codes (or virtual key) per game control
extern INT32 gamecontrol[num_gamecontrols][2]; extern INT32 gamecontrol[num_gamecontrols][2];
extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player
extern INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention
#define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]]) #define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]])
#define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]]) #define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]])
#define num_gcl_tutorial_check 6
#define num_gcl_tutorial_used 8
#define num_gcl_tutorial_full 13
#define num_gcl_movement 4
#define num_gcl_camera 2
#define num_gcl_movement_camera 6
#define num_gcl_jump 1
#define num_gcl_use 1
#define num_gcl_jump_use 2
extern const INT32 gcl_tutorial_check[num_gcl_tutorial_check];
extern const INT32 gcl_tutorial_used[num_gcl_tutorial_used];
extern const INT32 gcl_tutorial_full[num_gcl_tutorial_full];
extern const INT32 gcl_movement[num_gcl_movement];
extern const INT32 gcl_camera[num_gcl_camera];
extern const INT32 gcl_movement_camera[num_gcl_movement_camera];
extern const INT32 gcl_jump[num_gcl_jump];
extern const INT32 gcl_use[num_gcl_use];
extern const INT32 gcl_jump_use[num_gcl_jump_use];
// peace to my little coder fingers! // peace to my little coder fingers!
// check a gamecontrol being active or not // check a gamecontrol being active or not
@ -133,8 +162,10 @@ INT32 G_KeyStringtoNum(const char *keystr);
void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control);
void Command_Setcontrol_f(void); void Command_Setcontrol_f(void);
void Command_Setcontrol2_f(void); void Command_Setcontrol2_f(void);
void G_Controldefault(void); void G_DefineDefaultControls(void);
void G_SaveKeySetting(FILE *f); INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]);
void G_CheckDoubleUsage(INT32 keynum); void G_CheckDoubleUsage(INT32 keynum);
#endif #endif

View file

@ -58,7 +58,7 @@ typedef off_t off64_t;
#if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) #if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3))
#define PRIdS "u" #define PRIdS "u"
#elif defined (_WIN32) #elif defined (_WIN32)
#define PRIdS "Iu" #define PRIdS "Iu"
#elif defined (DJGPP) #elif defined (DJGPP)
#define PRIdS "u" #define PRIdS "u"
@ -475,7 +475,8 @@ void M_FirstLoadConfig(void)
} }
// load default control // load default control
G_Controldefault(); G_DefineDefaultControls();
G_CopyControls(gamecontrol, gamecontroldefault[gcs_fps], NULL, 0);
// load config, make sure those commands doesnt require the screen... // load config, make sure those commands doesnt require the screen...
COM_BufInsertText(va("exec \"%s\"\n", configfile)); COM_BufInsertText(va("exec \"%s\"\n", configfile));
@ -539,7 +540,13 @@ void M_SaveConfig(const char *filename)
// FIXME: save key aliases if ever implemented.. // FIXME: save key aliases if ever implemented..
CV_SaveVariables(f); CV_SaveVariables(f);
if (!dedicated) G_SaveKeySetting(f); if (!dedicated)
{
if (tutorialmode && tutorialgcs)
G_SaveKeySetting(f, gamecontroldefault[gcs_custom], gamecontrolbis); // using gcs_custom as temp storage
else
G_SaveKeySetting(f, gamecontrol, gamecontrolbis);
}
fclose(f); fclose(f);
} }