newgamechoices

git-svn-id: https://svn.eduke32.com/eduke32@7930 1a8010ca-5511-0410-912e-c29ae57300e0

# Conflicts:
#	source/build/src/defs.cpp
This commit is contained in:
hendricks266 2019-08-09 08:21:19 +00:00 committed by Christoph Oelckers
parent 284adb6ac6
commit 67b7d2408b
8 changed files with 370 additions and 4 deletions

View file

@ -123,6 +123,7 @@ enum scripttoken_t
T_SHADEFACTOR,
T_RFFDEFINEID,
T_IFCRC,
T_NEWGAMECHOICES,
};
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
@ -405,7 +406,7 @@ static int32_t defsparser(scriptfile *script)
{ "undefpalookuprange", T_UNDEFPALOOKUPRANGE },
{ "undefblendtablerange", T_UNDEFBLENDTABLERANGE },
{ "shadefactor", T_SHADEFACTOR },
{ "newgamechoices", T_NEWGAMECHOICES },
{ "rffdefineid", T_RFFDEFINEID }, // dummy
};
@ -3645,6 +3646,15 @@ static int32_t defsparser(scriptfile *script)
paletteloaded &= ~PALETTE_TRANSLUC;
}
break;
case T_NEWGAMECHOICES: // stub
{
char *blockend;
if (scriptfile_getbraces(script,&blockend))
break;
script->textptr = blockend;
break;
}
case T_RFFDEFINEID:
{
char *dummy;

View file

@ -159,6 +159,7 @@ enum GameEvent_t {
EVENT_DISPLAYROOMSCAMERATILE,
EVENT_RESETGOTPICS,
EVENT_VALIDATESTART,
EVENT_NEWGAMECUSTOM,
#ifdef LUNATIC
EVENT_ANIMATEALLSPRITES,
#endif

View file

@ -187,6 +187,11 @@ enum gametokens
T_FORCEFILTER,
T_FORCENOFILTER,
T_TEXTUREFILTER,
T_NEWGAMECHOICES,
T_CHOICE,
T_NAME,
T_LOCKED,
T_HIDDEN,
};
void G_HandleSpecialKeys(void)
@ -5291,6 +5296,7 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass)
{ "animsounds", T_ANIMSOUNDS },
{ "renamefile", T_RENAMEFILE },
{ "globalgameflags", T_GLOBALGAMEFLAGS },
{ "newgamechoices", T_NEWGAMECHOICES },
};
static const tokenlist soundTokens[] =
@ -5315,6 +5321,24 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass)
{ "texturefilter", T_TEXTUREFILTER },
};
static const tokenlist newGameTokens[] =
{
{ "choice", T_CHOICE },
};
static const tokenlist newGameChoiceTokens[] =
{
{ "name", T_NAME },
{ "locked", T_LOCKED },
{ "hidden", T_HIDDEN },
{ "choice", T_CHOICE },
};
static const tokenlist newGameSubchoiceTokens[] =
{
{ "name", T_NAME },
{ "locked", T_LOCKED },
{ "hidden", T_HIDDEN },
};
do
{
token = getatoken(pScript, tokens, ARRAY_SIZE(tokens));
@ -5557,6 +5581,125 @@ static int parsedefinitions_game(scriptfile *pScript, int firstPass)
}
break;
case T_GLOBALGAMEFLAGS: scriptfile_getnumber(pScript, &duke3d_globalflags); break;
case T_NEWGAMECHOICES:
{
char * newGameChoicesEnd;
if (scriptfile_getbraces(pScript,&newGameChoicesEnd))
break;
if (firstPass)
{
pScript->textptr = newGameChoicesEnd;
break;
}
while (pScript->textptr < newGameChoicesEnd)
{
switch (getatoken(pScript, newGameTokens, ARRAY_SIZE(newGameTokens)))
{
case T_CHOICE:
{
char * choicePtr = pScript->ltextptr;
char * choiceEnd;
int32_t choiceID;
if (scriptfile_getsymbol(pScript,&choiceID))
break;
if (scriptfile_getbraces(pScript,&choiceEnd))
break;
if ((unsigned)choiceID >= MAXMENUGAMEPLAYENTRIES)
{
initprintf("Error: Maximum choices exceeded near line %s:%d\n",
pScript->filename, scriptfile_getlinum(pScript, choicePtr));
pScript->textptr = choiceEnd;
}
MenuGameplayStemEntry & stem = g_MenuGameplayEntries[choiceID];
stem = MenuGameplayStemEntry{};
MenuGameplayEntry & entry = stem.entry;
while (pScript->textptr < choiceEnd)
{
switch (getatoken(pScript, newGameChoiceTokens, ARRAY_SIZE(newGameChoiceTokens)))
{
case T_CHOICE:
{
char * subChoicePtr = pScript->ltextptr;
char * subChoiceEnd;
int32_t subChoiceID;
if (scriptfile_getsymbol(pScript,&subChoiceID))
break;
if (scriptfile_getbraces(pScript,&subChoiceEnd))
break;
if ((unsigned)subChoiceID >= MAXMENUGAMEPLAYENTRIES)
{
initprintf("Error: Maximum subchoices exceeded near line %s:%d\n",
pScript->filename, scriptfile_getlinum(pScript, subChoicePtr));
pScript->textptr = subChoiceEnd;
}
MenuGameplayEntry & subentry = stem.subentries[subChoiceID];
subentry = MenuGameplayEntry{};
while (pScript->textptr < subChoiceEnd)
{
switch (getatoken(pScript, newGameSubchoiceTokens, ARRAY_SIZE(newGameSubchoiceTokens)))
{
case T_NAME:
{
char *name = NULL;
if (scriptfile_getstring(pScript, &name))
break;
memset(subentry.name, 0, ARRAY_SIZE(subentry.name));
strncpy(subentry.name, name, ARRAY_SIZE(subentry.name)-1);
break;
}
case T_LOCKED:
{
subentry.flags |= MGE_Locked;
break;
}
case T_HIDDEN:
{
subentry.flags |= MGE_Hidden;
break;
}
}
}
break;
}
case T_NAME:
{
char *name = NULL;
if (scriptfile_getstring(pScript, &name))
break;
memset(entry.name, 0, ARRAY_SIZE(entry.name));
strncpy(entry.name, name, ARRAY_SIZE(entry.name)-1);
break;
}
case T_LOCKED:
{
entry.flags |= MGE_Locked;
break;
}
case T_HIDDEN:
{
entry.flags |= MGE_Hidden;
break;
}
}
}
break;
}
}
}
break;
}
case T_EOF: return 0;
default: break;
}

View file

@ -990,6 +990,7 @@ const char *EventNames[MAXEVENTS] =
"EVENT_DISPLAYROOMSCAMERATILE",
"EVENT_RESETGOTPICS",
"EVENT_VALIDATESTART",
"EVENT_NEWGAMECUSTOM",
#ifdef LUNATIC
"EVENT_ANIMATEALLSPRITES",
#endif

View file

@ -635,6 +635,8 @@ enum UserdefsLabel_t
USERDEFS_DRAW_Y,
USERDEFS_DRAW_YXASPECT,
USERDEFS_FOV,
USERDEFS_NEWGAMECUSTOMOPEN,
USERDEFS_NEWGAMECUSTOMSUBOPEN,
USERDEFS_END
};

View file

@ -1358,6 +1358,8 @@ const memberlabel_t UserdefsLabels[]=
{ "draw_y", USERDEFS_DRAW_Y, 0, 0, -1 },
{ "draw_yxaspect", USERDEFS_DRAW_YXASPECT, 0, 0, -1 },
{ "fov", USERDEFS_FOV, 0, 0, -1 },
{ "newgamecustomopen", USERDEFS_NEWGAMECUSTOMOPEN, 0, 0, -1 },
{ "newgamecustomsubopen", USERDEFS_NEWGAMECUSTOMSUBOPEN, LABEL_HASPARM2, MAXMENUGAMEPLAYENTRIES, -1 },
};
int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2)
@ -1750,6 +1752,16 @@ void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t cons
case USERDEFS_DRAW_Y: rotatesprite_y_offset = iSet; break;
case USERDEFS_DRAW_YXASPECT: rotatesprite_yxaspect = iSet; break;
case USERDEFS_FOV: ud.fov = iSet; break;
case USERDEFS_NEWGAMECUSTOMOPEN:
for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b)
if (iSet & (1u<<b))
ME_NEWGAMECUSTOMENTRIES[b].flags = 0;
break;
case USERDEFS_NEWGAMECUSTOMSUBOPEN:
for (unsigned int b = 0; b < MAXMENUGAMEPLAYENTRIES; ++b)
if (iSet & (1u<<b))
ME_NEWGAMECUSTOMSUBENTRIES[lParm2][b].flags = 0;
break;
}
}

View file

@ -185,13 +185,16 @@ All MAKE_* macros are generally for the purpose of keeping state initialization
separate from actual data. Alternatively, they can serve to factor out repetitive
stuff and keep the important bits from getting lost to our eyes.
They serve as a stand-in for C++ default value constructors, since we're using C89.
They serve as a stand-in for C++ default value constructors, since this was written
when the codebase still used C89.
Note that I prefer to include a space on the inside of the macro parentheses, since
they effectively stand in for curly braces as struct initializers.
*/
MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];
// common font types
// tilenums are set after namesdyn runs
@ -210,6 +213,8 @@ MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 },
static MenuMenuFormat_t MMF_Top_Main = { { MENU_MARGIN_CENTER<<16, 55<<16, }, -(170<<16) };
static MenuMenuFormat_t MMF_Top_Episode = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) };
static MenuMenuFormat_t MMF_Top_NewGameCustom = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) };
static MenuMenuFormat_t MMF_Top_NewGameCustomSub = { { MENU_MARGIN_CENTER<<16, 48<<16, }, -(190<<16) };
static MenuMenuFormat_t MMF_Top_Skill = { { MENU_MARGIN_CENTER<<16, 58<<16, }, -(190<<16) };
static MenuMenuFormat_t MMF_Top_Options = { { MENU_MARGIN_CENTER<<16, 38<<16, }, -(190<<16) };
static MenuMenuFormat_t MMF_Top_Joystick_Network = { { MENU_MARGIN_CENTER<<16, 70<<16, }, -(190<<16) };
@ -377,6 +382,15 @@ static MenuLink_t MEO_EPISODE_USERMAP = { MENU_USERMAP, MA_Advance, };
static MenuEntry_t ME_EPISODE_USERMAP = MAKE_MENUENTRY( "User Map", &MF_Redfont, &MEF_CenterMenu, &MEO_EPISODE_USERMAP, Link );
static MenuEntry_t *MEL_EPISODE[MAXVOLUMES+2]; // +2 for spacer and User Map
static MenuLink_t MEO_NEWGAMECUSTOM_TEMPLATE = { MENU_NEWGAMECUSTOMSUB, MA_Advance, };
static MenuLink_t MEO_NEWGAMECUSTOM[MAXMENUGAMEPLAYENTRIES];
static MenuLink_t MEO_NEWGAMECUSTOMSUB_TEMPLATE = { MENU_SKILL, MA_Advance, };
static MenuLink_t MEO_NEWGAMECUSTOMSUB[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES];
MenuEntry_t ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES];
MenuEntry_t ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES];
static MenuEntry_t *MEL_NEWGAMECUSTOM[MAXMENUGAMEPLAYENTRIES];
static MenuEntry_t *MEL_NEWGAMECUSTOMSUB[MAXMENUGAMEPLAYENTRIES];
static MenuEntry_t ME_SKILL_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Redfont, &MEF_CenterMenu, &MEO_NULL, Link );
static MenuEntry_t ME_SKILL[MAXSKILLS];
static MenuEntry_t *MEL_SKILL[MAXSKILLS];
@ -1319,6 +1333,8 @@ static MenuMenu_t M_MAIN = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN );
static MenuMenu_t M_MAIN_INGAME = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN_INGAME );
static MenuMenu_t M_EPISODE = MAKE_MENUMENU( "Select An Episode", &MMF_Top_Episode, MEL_EPISODE );
static MenuMenu_t M_SKILL = MAKE_MENUMENU( "Select Skill", &MMF_Top_Skill, MEL_SKILL );
static MenuMenu_t M_NEWGAMECUSTOM = MAKE_MENUMENU( s_NewGame, &MMF_Top_NewGameCustom, MEL_NEWGAMECUSTOM );
static MenuMenu_t M_NEWGAMECUSTOMSUB = MAKE_MENUMENU( s_NewGame, &MMF_Top_NewGameCustomSub, MEL_NEWGAMECUSTOMSUB );
#ifndef EDUKE32_SIMPLE_MENU
static MenuMenu_t M_GAMESETUP = MAKE_MENUMENU( "Game Setup", &MMF_BigOptions, MEL_GAMESETUP );
#endif
@ -1406,8 +1422,10 @@ static Menu_t Menus[] = {
{ &M_MAIN, MENU_MAIN, MENU_CLOSE, MA_None, Menu },
{ &M_MAIN_INGAME, MENU_MAIN_INGAME, MENU_CLOSE, MA_None, Menu },
{ &M_EPISODE, MENU_EPISODE, MENU_MAIN, MA_Return, Menu },
{ &M_USERMAP, MENU_USERMAP, MENU_EPISODE, MA_Return, FileSelect },
{ &M_SKILL, MENU_SKILL, MENU_EPISODE, MA_Return, Menu },
{ &M_USERMAP, MENU_USERMAP, MENU_PREVIOUS, MA_Return, FileSelect },
{ &M_NEWGAMECUSTOM, MENU_NEWGAMECUSTOM, MENU_MAIN, MA_Return, Menu },
{ &M_NEWGAMECUSTOMSUB, MENU_NEWGAMECUSTOMSUB, MENU_NEWGAMECUSTOM, MA_Return, Menu },
{ &M_SKILL, MENU_SKILL, MENU_PREVIOUS, MA_Return, Menu },
#ifndef EDUKE32_SIMPLE_MENU
{ &M_GAMESETUP, MENU_GAMESETUP, MENU_OPTIONS, MA_Return, Menu },
#endif
@ -1545,6 +1563,51 @@ static MenuEntry_t *Menu_AdjustForCurrentEntryAssignmentBlind(MenuMenu_t *menu)
static int32_t SELECTDIR_z = 65536;
void Menu_PopulateNewGameCustom(void)
{
M_NEWGAMECUSTOM.title = s_NewGame;
int e = 0;
for (MenuGameplayStemEntry const & stem : g_MenuGameplayEntries)
{
MenuGameplayEntry const & entry = stem.entry;
if (!entry.isValid())
break;
MEL_NEWGAMECUSTOM[e] = &ME_NEWGAMECUSTOMENTRIES[e];
++e;
}
M_NEWGAMECUSTOM.numEntries = e;
MMF_Top_NewGameCustom.pos.y = (58 + (3-e)*6)<<16;
}
void Menu_PopulateNewGameCustomSub(int e)
{
if ((unsigned)e >= MAXMENUGAMEPLAYENTRIES)
return;
MenuGameplayStemEntry const & stem = g_MenuGameplayEntries[e];
MenuGameplayEntry const & entry = stem.entry;
if (!entry.isValid())
return;
M_NEWGAMECUSTOMSUB.title = entry.name;
int s = 0;
for (MenuGameplayEntry const & subentry : stem.subentries)
{
if (!subentry.isValid())
break;
MEL_NEWGAMECUSTOMSUB[s] = &ME_NEWGAMECUSTOMSUBENTRIES[e][s];
++s;
}
M_NEWGAMECUSTOMSUB.numEntries = s;
MMF_Top_NewGameCustomSub.pos.y = (58 + (3-s)*6)<<16;
}
/*
This function prepares data after ART and CON have been processed.
It also initializes some data in loops rather than statically at compile time.
@ -1639,6 +1702,60 @@ void Menu_Init(void)
MEO_EPISODE.linkID = MENU_NULL;
M_EPISODE.currentEntry = ud.default_volume;
// prepare new game custom :O
if (g_MenuGameplayEntries[0].entry.isValid())
{
MEO_MAIN_NEWGAME.linkID = M_NEWVERIFY.linkID = MENU_NEWGAMECUSTOM;
int e = 0;
for (MenuGameplayStemEntry const & stem : g_MenuGameplayEntries)
{
MenuGameplayEntry const & entry = stem.entry;
if (!entry.isValid())
break;
MenuEntry_t & e_me = ME_NEWGAMECUSTOMENTRIES[e];
e_me = ME_EPISODE_TEMPLATE;
MenuLink_t & e_meo = MEO_NEWGAMECUSTOM[e];
e_meo = MEO_NEWGAMECUSTOM_TEMPLATE;
e_me.entry = &e_meo;
e_me.name = entry.name;
if (entry.flags & MGE_Locked)
e_me.flags |= MEF_Disabled;
if (entry.flags & MGE_Hidden)
e_me.flags |= MEF_Hidden;
int s = 0;
for (MenuGameplayEntry const & subentry : stem.subentries)
{
if (!subentry.isValid())
break;
MenuEntry_t & s_me = ME_NEWGAMECUSTOMSUBENTRIES[e][s];
s_me = ME_EPISODE_TEMPLATE;
MenuLink_t & s_meo = MEO_NEWGAMECUSTOMSUB[e][s];
s_meo = MEO_NEWGAMECUSTOMSUB_TEMPLATE;
s_me.entry = &s_meo;
s_me.name = subentry.name;
if (subentry.flags & MGE_Locked)
s_me.flags |= MEF_Disabled;
if (subentry.flags & MGE_Hidden)
s_me.flags |= MEF_Hidden;
++s;
}
if (s == 0)
e_meo.linkID = MENU_SKILL;
++e;
}
Menu_PopulateNewGameCustom();
}
// prepare skills
k = -1;
for (i = 0; i < g_skillCnt && g_skillNames[i][0]; ++i)
@ -2951,6 +3068,17 @@ static void Menu_EntryLinkActivate(MenuEntry_t *entry)
}
break;
case MENU_NEWGAMECUSTOM:
ud.returnvar[0] = -1;
VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, M_NEWGAMECUSTOM.currentEntry);
break;
case MENU_NEWGAMECUSTOMSUB:
ud.returnvar[0] = M_NEWGAMECUSTOMSUB.currentEntry;
ud.returnvar[1] = -1;
VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, M_NEWGAMECUSTOM.currentEntry);
break;
case MENU_SKILL:
{
int32_t skillsound = PISTOL_BODYHIT;
@ -3987,6 +4115,10 @@ static void Menu_AboutToStartDisplaying(Menu_t * m)
ME_MAIN_LOADGAME.name = s_LoadGame;
break;
case MENU_NEWGAMECUSTOMSUB:
Menu_PopulateNewGameCustomSub(M_NEWGAMECUSTOM.currentEntry);
break;
case MENU_LOAD:
if (FURY)
M_LOAD.title = (g_player[myconnectindex].ps->gm & MODE_GAME) ? s_LoadGame : s_Continue;
@ -6828,6 +6960,12 @@ void M_DisplayMenus(void)
{
ud.returnvar[0] = origin.x;
ud.returnvar[1] = origin.y;
if (m_parentMenu->type == Menu)
{
ud.returnvar[2] = ((MenuMenu_t *)m_parentMenu->object)->currentEntry;
if (m_parentMenu->menuID == MENU_NEWGAMECUSTOMSUB)
ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry;
}
VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENU, g_player[screenpeek].ps->i, screenpeek, m_parentMenu->menuID);
origin.x = ud.returnvar[0];
origin.y = ud.returnvar[1];
@ -6843,6 +6981,12 @@ void M_DisplayMenus(void)
ud.returnvar[0] = previousOrigin.x;
ud.returnvar[1] = previousOrigin.y;
if (m_animation.previous->type == Menu)
{
ud.returnvar[2] = ((MenuMenu_t *)m_animation.previous->object)->currentEntry;
if (m_animation.previous->menuID == MENU_NEWGAMECUSTOMSUB)
ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry;
}
VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENU, g_player[screenpeek].ps->i, screenpeek, m_animation.previous->menuID);
previousOrigin.x = ud.returnvar[0];
previousOrigin.y = ud.returnvar[1];
@ -6850,6 +6994,12 @@ void M_DisplayMenus(void)
ud.returnvar[0] = origin.x;
ud.returnvar[1] = origin.y;
if (m_currentMenu->type == Menu)
{
ud.returnvar[2] = ((MenuMenu_t *)m_currentMenu->object)->currentEntry;
if (g_currentMenu == MENU_NEWGAMECUSTOMSUB)
ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry;
}
VM_OnEventWithReturn(EVENT_DISPLAYMENU, g_player[screenpeek].ps->i, screenpeek, g_currentMenu);
origin.x = ud.returnvar[0];
origin.y = ud.returnvar[1];
@ -6881,6 +7031,12 @@ void M_DisplayMenus(void)
{
ud.returnvar[0] = origin.x;
ud.returnvar[1] = origin.y;
if (m_parentMenu->type == Menu)
{
ud.returnvar[2] = ((MenuMenu_t *)m_parentMenu->object)->currentEntry;
if (m_parentMenu->menuID == MENU_NEWGAMECUSTOMSUB)
ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry;
}
VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENUREST, g_player[screenpeek].ps->i, screenpeek, m_parentMenu->menuID);
}
@ -6888,11 +7044,23 @@ void M_DisplayMenus(void)
{
ud.returnvar[0] = previousOrigin.x;
ud.returnvar[1] = previousOrigin.y;
if (m_animation.previous->type == Menu)
{
ud.returnvar[2] = ((MenuMenu_t *)m_animation.previous->object)->currentEntry;
if (m_animation.previous->menuID == MENU_NEWGAMECUSTOMSUB)
ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry;
}
VM_OnEventWithReturn(EVENT_DISPLAYINACTIVEMENUREST, g_player[screenpeek].ps->i, screenpeek, m_animation.previous->menuID);
}
ud.returnvar[0] = origin.x;
ud.returnvar[1] = origin.y;
if (m_currentMenu->type == Menu)
{
ud.returnvar[2] = ((MenuMenu_t *)m_currentMenu->object)->currentEntry;
if (g_currentMenu == MENU_NEWGAMECUSTOMSUB)
ud.returnvar[3] = M_NEWGAMECUSTOM.currentEntry;
}
VM_OnEventWithReturn(EVENT_DISPLAYMENUREST, g_player[screenpeek].ps->i, screenpeek, g_currentMenu);
#if !defined EDUKE32_TOUCH_DEVICES

View file

@ -44,6 +44,8 @@ enum MenuIndex_t {
MENU_MAIN_INGAME = 50,
MENU_EPISODE = 100,
MENU_USERMAP = 101,
MENU_NEWGAMECUSTOM = 102,
MENU_NEWGAMECUSTOMSUB = 103,
MENU_SKILL = 110,
MENU_GAMESETUP = 200,
MENU_OPTIONS = 202,
@ -490,6 +492,33 @@ extern int32_t m_mousewake_watchpoint, m_menuchange_watchpoint;
# define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || m_mousewake_watchpoint || m_menuchange_watchpoint == 3)
#endif
#define MAXMENUGAMEPLAYENTRIES 7
enum MenuGameplayEntryFlags
{
MGE_Locked = 1u<<0u,
MGE_Hidden = 1u<<1u,
};
typedef struct MenuGameplayEntry
{
char name[64];
uint8_t flags;
bool isValid() const { return name[0] != '\0'; }
} MenuGameplayEntry;
typedef struct MenuGameplayStemEntry
{
MenuGameplayEntry entry;
MenuGameplayEntry subentries[MAXMENUGAMEPLAYENTRIES];
} MenuGameplayStemEntry;
extern MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];
extern MenuEntry_t ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES];
extern MenuEntry_t ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES];
#ifdef __cplusplus
}
#endif