Password entry on Extras menu

- Type in anything you want
- On closing the field, if a cheat sequence is matched *exactly*, activate it!
    - Directly hooked up to a modified form of the previously existing SCRAMBLE interpreter system in m_cheat.c
- The existing cht_Responder call in D_ProcessEvents is gone
    - Done this way because the new input paragadim is not very friendly to unqualified keyboard/controller input, and we still want text
- Plenty of opportunity to add fun future passwords in addition to the currently underbaked Tournament Mode
    - Got a debug M_StartMessage just so you can tell what's up without sound
This commit is contained in:
toaster 2023-06-04 21:36:52 +01:00
parent 823315667b
commit d8e2b4a906
6 changed files with 89 additions and 101 deletions

View file

@ -249,12 +249,6 @@ void D_ProcessEvents(void)
HandleGamepadDeviceEvents(ev); HandleGamepadDeviceEvents(ev);
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
{
if (cht_Responder(ev))
continue;
}
if (demo.savemode == DSM_TITLEENTRY) if (demo.savemode == DSM_TITLEENTRY)
{ {
if (G_DemoTitleResponder(ev)) if (G_DemoTitleResponder(ev))
@ -295,14 +289,6 @@ void D_ProcessEvents(void)
if (eaten) if (eaten)
continue; // menu ate the event continue; // menu ate the event
// Demo input:
/*
if (demo.playback)
if (M_DemoResponder(ev))
continue; // demo ate the event
*/
G_Responder(ev); G_Responder(ev);
} }

View file

@ -1035,6 +1035,7 @@ typedef enum
extras_statistics, extras_statistics,
extras_eggtv, extras_eggtv,
extras_stereo, extras_stereo,
extras_password,
} extras_e; } extras_e;
void M_InitExtras(INT32 choice); // init for the struct void M_InitExtras(INT32 choice); // init for the struct
@ -1098,6 +1099,7 @@ void M_AddonsRefresh(void);
void M_HandleAddons(INT32 choice); void M_HandleAddons(INT32 choice);
char *M_AddonsHeaderPath(void); char *M_AddonsHeaderPath(void);
extern consvar_t cv_dummyaddonsearch; extern consvar_t cv_dummyaddonsearch;
extern consvar_t cv_dummyextraspassword;
void M_Manual(INT32 choice); void M_Manual(INT32 choice);
void M_HandleImageDef(INT32 choice); void M_HandleImageDef(INT32 choice);

View file

@ -1190,5 +1190,7 @@ void M_Init(void)
CV_RegisterVar(&cv_dummyaddonsearch); CV_RegisterVar(&cv_dummyaddonsearch);
CV_RegisterVar(&cv_dummyextraspassword);
M_UpdateMenuBGImage(true); M_UpdateMenuBGImage(true);
} }

View file

@ -68,9 +68,6 @@ static UINT8 cheatf_warp(void)
/*if (modifiedgame) /*if (modifiedgame)
return 0;*/ return 0;*/
if (menuactive && currentMenu != &MainDef)
return 0; // Only on the main menu!
// Unlock EVERYTHING. // Unlock EVERYTHING.
for (i = 0; i < MAXUNLOCKABLES; i++) for (i = 0; i < MAXUNLOCKABLES; i++)
{ {
@ -89,9 +86,8 @@ static UINT8 cheatf_warp(void)
S_StartSound(0, sfx_kc42); S_StartSound(0, sfx_kc42);
} }
// Refresh secrets menu existing. M_StartMessage(M_GetText("TOURNAMENT MODE ENGAGED!!\n\nIs what I would be saying if I actually\nimplemented anything special here.\n\nPress (B)\n"), NULL, MM_NOTHING);
M_ClearMenus(true);
M_StartControlPanel();
return 1; return 1;
} }
@ -103,50 +99,46 @@ static UINT8 cheatf_devmode(void)
if (modifiedgame) if (modifiedgame)
return 0; return 0;
if (menuactive && currentMenu != &MainDef)
return 0; // Only on the main menu!
S_StartSound(0, sfx_itemup);
// Just unlock all the things and turn on -debug and console devmode. // Just unlock all the things and turn on -debug and console devmode.
G_SetUsedCheats();
for (i = 0; i < MAXUNLOCKABLES; i++) for (i = 0; i < MAXUNLOCKABLES; i++)
{
if (!unlockables[i].conditionset)
continue;
gamedata->unlocked[i] = true; gamedata->unlocked[i] = true;
}
G_SetUsedCheats();
S_StartSound(0, sfx_kc42);
devparm = true; devparm = true;
cht_debug |= 0x8000; cht_debug |= 0x8000;
// Refresh secrets menu existing.
M_ClearMenus(true);
M_StartControlPanel();
return 1; return 1;
} }
#endif #endif
static cheatseq_t cheat_warp = { static cheatseq_t cheat_warp = {
0, cheatf_warp, NULL, cheatf_warp,
//{ SCRAMBLE('r'), SCRAMBLE('e'), SCRAMBLE('d'), SCRAMBLE('x'), SCRAMBLE('v'), SCRAMBLE('i'), 0xff } //{ SCRAMBLE('r'), SCRAMBLE('e'), SCRAMBLE('d'), SCRAMBLE('x'), SCRAMBLE('v'), SCRAMBLE('i'), 0xff }
(UINT8[]){ SCRAMBLE('b'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('a'), 0xff } (UINT8[]){ SCRAMBLE('b'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('a'), SCRAMBLE('n'), SCRAMBLE('a'), 0xff }
}; };
static cheatseq_t cheat_warp_joy = {
0, cheatf_warp,
/*{ SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW),
SCRAMBLE(KEY_RIGHTARROW), SCRAMBLE(KEY_RIGHTARROW), SCRAMBLE(KEY_UPARROW),
SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW),
SCRAMBLE(KEY_ENTER), 0xff }*/
(UINT8[]){ SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_RIGHTARROW),
SCRAMBLE(KEY_RIGHTARROW), SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_LEFTARROW),
SCRAMBLE(KEY_DOWNARROW), SCRAMBLE(KEY_RIGHTARROW),
SCRAMBLE(KEY_ENTER), 0xff }
};
#ifdef DEVELOP #ifdef DEVELOP
static cheatseq_t cheat_devmode = { static cheatseq_t cheat_devmode = {
0, cheatf_devmode, NULL, cheatf_devmode,
(UINT8[]){ SCRAMBLE('d'), SCRAMBLE('e'), SCRAMBLE('v'), SCRAMBLE('m'), SCRAMBLE('o'), SCRAMBLE('d'), SCRAMBLE('e'), 0xff } (UINT8[]){ SCRAMBLE('d'), SCRAMBLE('e'), SCRAMBLE('v'), SCRAMBLE('m'), SCRAMBLE('o'), SCRAMBLE('d'), SCRAMBLE('e'), 0xff }
}; };
#endif #endif
cheatseq_t *cheatseqlist[] =
{
&cheat_warp,
#ifdef DEVELOP
&cheat_devmode,
#endif
NULL
};
// ========================================================================== // ==========================================================================
// CHEAT SEQUENCE PACKAGE // CHEAT SEQUENCE PACKAGE
// ========================================================================== // ==========================================================================
@ -168,73 +160,64 @@ void cht_Init(void)
// Called in st_stuff module, which handles the input. // Called in st_stuff module, which handles the input.
// Returns a 1 if the cheat was successful, 0 if failed. // Returns a 1 if the cheat was successful, 0 if failed.
// //
static UINT8 cht_CheckCheat(cheatseq_t *cht, char key) static UINT8 cht_CheckCheat(cheatseq_t *cht, char key, boolean shouldend)
{ {
UINT8 rc = 0; UINT8 rc = 0; // end of sequence character
if (!cht->p) if (cht->p == NULL || *cht->p == 0xff)
cht->p = cht->sequence; // initialize if first time return rc;
if (*cht->p == 0) if (*cht->p == 0)
*(cht->p++) = key; *(cht->p++) = key;
else if (cheat_xlate_table[(UINT8)key] == *cht->p) else if (cheat_xlate_table[(UINT8)key] == *cht->p)
cht->p++; cht->p++;
else else
cht->p = cht->sequence; {
cht->p = NULL;
return rc;
}
if (*cht->p == 1) if (*cht->p == 1)
cht->p++; cht->p++;
else if (*cht->p == 0xff) // end of sequence character if (shouldend && *cht->p == 0xff) // end of sequence character
{
cht->p = cht->sequence;
rc = cht->func(); rc = cht->func();
}
return rc; return rc;
} }
boolean cht_Responder(event_t *ev) boolean cht_Interpret(const char *password)
{ {
UINT8 ret = 0, ch = 0; if (!password)
if (ev->type != ev_keydown)
return false; return false;
if (ev->data1 > 0xFF) UINT8 ret = 0;
{
// map some fake (joy) inputs into keys
// map joy inputs into keys
switch (ev->data1)
{
case KEY_JOY1:
case KEY_JOY1 + 2:
ch = KEY_ENTER;
break;
case KEY_HAT1:
ch = KEY_UPARROW;
break;
case KEY_HAT1 + 1:
ch = KEY_DOWNARROW;
break;
case KEY_HAT1 + 2:
ch = KEY_LEFTARROW;
break;
case KEY_HAT1 + 3:
ch = KEY_RIGHTARROW;
break;
default:
// no mapping
return false;
}
}
else
ch = (UINT8)ev->data1;
ret += cht_CheckCheat(&cheat_warp, (char)ch); size_t cheatseqid = 0;
ret += cht_CheckCheat(&cheat_warp_joy, (char)ch);
#ifdef DEVELOP const char *endofpassword = password;
ret += cht_CheckCheat(&cheat_devmode, (char)ch); while (*endofpassword && *(endofpassword+1))
#endif endofpassword++;
return (ret != 0);
cheatseqid = 0;
while (cheatseqlist[cheatseqid])
{
cheatseqlist[cheatseqid]->p = cheatseqlist[cheatseqid]->sequence;
cheatseqid++;
}
while (*password)
{
cheatseqid = 0;
while (cheatseqlist[cheatseqid])
{
ret += cht_CheckCheat(cheatseqlist[cheatseqid], *password, (password == endofpassword));
cheatseqid++;
}
password++;
}
return (ret > 0);
} }
// Console cheat commands rely on these a lot... // Console cheat commands rely on these a lot...

View file

@ -46,7 +46,7 @@ typedef enum {
// //
// Cheat sequences // Cheat sequences
// //
boolean cht_Responder(event_t *ev); boolean cht_Interpret(const char *password);
void cht_Init(void); void cht_Init(void);
// //

View file

@ -3,6 +3,7 @@
#include "../k_menu.h" #include "../k_menu.h"
#include "../m_cond.h" #include "../m_cond.h"
#include "../m_cheat.h"
#include "../s_sound.h" #include "../s_sound.h"
menuitem_t EXTRAS_Main[] = menuitem_t EXTRAS_Main[] =
@ -28,6 +29,9 @@ menuitem_t EXTRAS_Main[] =
{IT_STRING | IT_CALL, NULL, NULL, {IT_STRING | IT_CALL, NULL, NULL,
NULL, {.routine = M_SoundTest}, 0, 0}, NULL, {.routine = M_SoundTest}, 0, 0},
{IT_STRING | IT_CVAR | IT_CV_STRING, "Password", "If you don't know any passwords, come back later!",
NULL, {.cvar = &cv_dummyextraspassword}, 0, 0},
}; };
// the extras menu essentially reuses the options menu stuff // the extras menu essentially reuses the options menu stuff
@ -53,18 +57,10 @@ menu_t EXTRAS_MainDef = {
struct extrasmenu_s extrasmenu; struct extrasmenu_s extrasmenu;
consvar_t cv_dummyextraspassword = CVAR_INIT ("dummyextraspassword", "", CV_HIDDEN, NULL, NULL);
void M_InitExtras(INT32 choice) void M_InitExtras(INT32 choice)
{ {
(void)choice;
extrasmenu.ticker = 0;
extrasmenu.offset = 0;
extrasmenu.extx = 0;
extrasmenu.exty = 0;
extrasmenu.textx = 0;
extrasmenu.texty = 0;
// Addons // Addons
if (M_SecretUnlocked(SECRET_ADDONS, true)) if (M_SecretUnlocked(SECRET_ADDONS, true))
{ {
@ -127,6 +123,17 @@ void M_InitExtras(INT32 choice)
EXTRAS_Main[extras_stereo].text = EXTRAS_Main[extras_stereo].tooltip = "???"; EXTRAS_Main[extras_stereo].text = EXTRAS_Main[extras_stereo].tooltip = "???";
} }
if (choice == -1)
return;
extrasmenu.ticker = 0;
extrasmenu.offset = 0;
extrasmenu.extx = 0;
extrasmenu.exty = 0;
extrasmenu.textx = 0;
extrasmenu.texty = 0;
M_SetupNextMenu(&EXTRAS_MainDef, false); M_SetupNextMenu(&EXTRAS_MainDef, false);
} }
@ -163,6 +170,14 @@ void M_ExtrasTick(void)
extrasmenu.textx = 160; extrasmenu.textx = 160;
extrasmenu.texty = 50; extrasmenu.texty = 50;
} }
if (menutyping.active == false && cv_dummyextraspassword.string[0] != '\0')
{
if (cht_Interpret(cv_dummyextraspassword.string) == true)
M_InitExtras(-1);
CV_StealthSet(&cv_dummyextraspassword, "");
}
} }
boolean M_ExtrasInputs(INT32 ch) boolean M_ExtrasInputs(INT32 ch)