More title screen features; menu meta state implementation (active and previous menu types)
* Draw background over titlemap * HIDEBACKGROUND to show titlemap * Specify NOMUSIC or IGNOREMUSIC (to not change music) * Linedef execs implemented for tree hierarchy, including bubbling (NOENTERBUBBLE/NOEXITBUBBLE) * Specify ENTERWIPE and EXITWIPE * Menuid hierarchy fixes (Control mapping, joystick setup) * Time attack handling fixes * Specify custom wipes on runtime for D_Display and P_SetupLevel (for titlemap) * Allow for forcing and skipping a wipe * Wipe utility functions F_GetWipeLength and F_WipeExists
This commit is contained in:
parent
d2bbddbed4
commit
758647fab2
36
src/d_main.c
36
src/d_main.c
|
@ -233,6 +233,9 @@ void D_ProcessEvents(void)
|
||||||
// wipegamestate can be set to -1 to force a wipe on the next draw
|
// wipegamestate can be set to -1 to force a wipe on the next draw
|
||||||
// added comment : there is a wipe eatch change of the gamestate
|
// added comment : there is a wipe eatch change of the gamestate
|
||||||
gamestate_t wipegamestate = GS_LEVEL;
|
gamestate_t wipegamestate = GS_LEVEL;
|
||||||
|
// -1: Default; 0-n: Wipe index; INT16_MAX: do not wipe
|
||||||
|
INT16 wipetypepre = -1;
|
||||||
|
INT16 wipetypepost = -1;
|
||||||
|
|
||||||
static void D_Display(void)
|
static void D_Display(void)
|
||||||
{
|
{
|
||||||
|
@ -266,7 +269,7 @@ static void D_Display(void)
|
||||||
|
|
||||||
// save the current screen if about to wipe
|
// save the current screen if about to wipe
|
||||||
wipe = (gamestate != wipegamestate);
|
wipe = (gamestate != wipegamestate);
|
||||||
if (wipe)
|
if (wipe && wipetypepre != INT16_MAX)
|
||||||
{
|
{
|
||||||
// set for all later
|
// set for all later
|
||||||
wipedefindex = gamestate; // wipe_xxx_toblack
|
wipedefindex = gamestate; // wipe_xxx_toblack
|
||||||
|
@ -278,21 +281,29 @@ static void D_Display(void)
|
||||||
wipedefindex = wipe_multinter_toblack;
|
wipedefindex = wipe_multinter_toblack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wipetypepre < 0 || !F_WipeExists(wipetypepre))
|
||||||
|
wipetypepre = wipedefs[wipedefindex];
|
||||||
|
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
{
|
{
|
||||||
// Fade to black first
|
// Fade to black first
|
||||||
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always
|
if ((wipegamestate == FORCEWIPE ||
|
||||||
&& wipedefs[wipedefindex] != UINT8_MAX)
|
!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) // fades to black on its own timing, always
|
||||||
|
&& wipetypepre != UINT8_MAX)
|
||||||
{
|
{
|
||||||
F_WipeStartScreen();
|
F_WipeStartScreen();
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||||
F_WipeEndScreen();
|
F_WipeEndScreen();
|
||||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
F_WipeStartScreen();
|
F_WipeStartScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wipetypepre = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
wipetypepre = -1;
|
||||||
|
|
||||||
// do buffered drawing
|
// do buffered drawing
|
||||||
switch (gamestate)
|
switch (gamestate)
|
||||||
|
@ -359,6 +370,10 @@ static void D_Display(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run menu state updates and linedef execs in titlemap
|
||||||
|
if (wipe && (gamestate == GS_TITLESCREEN || gamestate == GS_TIMEATTACK))
|
||||||
|
M_ApplyMenuMetaState();
|
||||||
|
|
||||||
// clean up border stuff
|
// clean up border stuff
|
||||||
// see if the border needs to be initially drawn
|
// see if the border needs to be initially drawn
|
||||||
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
|
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
|
||||||
|
@ -465,18 +480,25 @@ static void D_Display(void)
|
||||||
//
|
//
|
||||||
// wipe update
|
// wipe update
|
||||||
//
|
//
|
||||||
if (wipe)
|
if (wipe && wipetypepost != INT16_MAX)
|
||||||
{
|
{
|
||||||
// note: moved up here because NetUpdate does input changes
|
// note: moved up here because NetUpdate does input changes
|
||||||
// and input during wipe tends to mess things up
|
// and input during wipe tends to mess things up
|
||||||
wipedefindex += WIPEFINALSHIFT;
|
wipedefindex += WIPEFINALSHIFT;
|
||||||
|
|
||||||
|
if (wipetypepost < 0 || !F_WipeExists(wipetypepost))
|
||||||
|
wipetypepost = wipedefs[wipedefindex];
|
||||||
|
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
{
|
{
|
||||||
F_WipeEndScreen();
|
F_WipeEndScreen();
|
||||||
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
|
F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wipetypepost = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
wipetypepost = -1;
|
||||||
|
|
||||||
NetUpdate(); // send out any new accumulation
|
NetUpdate(); // send out any new accumulation
|
||||||
|
|
||||||
|
@ -729,6 +751,7 @@ void D_StartTitle(void)
|
||||||
gametype = GT_COOP;
|
gametype = GT_COOP;
|
||||||
paused = false;
|
paused = false;
|
||||||
advancedemo = false;
|
advancedemo = false;
|
||||||
|
MN_Start();
|
||||||
F_StartTitleScreen();
|
F_StartTitleScreen();
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
|
|
||||||
|
@ -1378,6 +1401,7 @@ void D_SRB2Main(void)
|
||||||
{
|
{
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
CON_ClearHUD();
|
CON_ClearHUD();
|
||||||
|
MN_Start();
|
||||||
F_StartTitleScreen();
|
F_StartTitleScreen();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1954,13 +1954,19 @@ static void readmenu(MYFILE *f, INT32 num)
|
||||||
|
|
||||||
value = atoi(word2); // used for numerical settings
|
value = atoi(word2); // used for numerical settings
|
||||||
|
|
||||||
CONS_Printf("Menu %d> %s | %s\n", num, word, word2);
|
|
||||||
|
|
||||||
if (fastcmp(word, "BACKGROUNDNAME"))
|
if (fastcmp(word, "BACKGROUNDNAME"))
|
||||||
{
|
{
|
||||||
strncpy(menumeta[num].bgname, word2, 8);
|
strncpy(menumeta[num].bgname, word2, 8);
|
||||||
titlechanged = true;
|
titlechanged = true;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "HIDEBACKGROUND"))
|
||||||
|
{
|
||||||
|
// HACK: Use CHAR_MAX to signal that we want to hide the background
|
||||||
|
// Only effective during titlemap
|
||||||
|
menumeta[num].bgname[0] = CHAR_MAX;
|
||||||
|
menumeta[num].bgname[1] = 0;
|
||||||
|
titlechanged = true;
|
||||||
|
}
|
||||||
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS"))
|
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS"))
|
||||||
{
|
{
|
||||||
// true by default, except MM_MAIN
|
// true by default, except MM_MAIN
|
||||||
|
@ -2006,7 +2012,17 @@ static void readmenu(MYFILE *f, INT32 num)
|
||||||
else if (fastcmp(word, "MUSICLOOP"))
|
else if (fastcmp(word, "MUSICLOOP"))
|
||||||
{
|
{
|
||||||
// true by default except MM_MAIN
|
// true by default except MM_MAIN
|
||||||
menumeta[num].muslooping = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
|
menumeta[num].muslooping = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||||
|
titlechanged = true;
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "NOMUSIC"))
|
||||||
|
{
|
||||||
|
menumeta[num].musstop = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||||
|
titlechanged = true;
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "IGNOREMUSIC"))
|
||||||
|
{
|
||||||
|
menumeta[num].musignore = (value || word2[0] == 'T' || word2[0] == 'Y');
|
||||||
titlechanged = true;
|
titlechanged = true;
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "FADESTRENGTH"))
|
else if (fastcmp(word, "FADESTRENGTH"))
|
||||||
|
@ -2015,9 +2031,14 @@ static void readmenu(MYFILE *f, INT32 num)
|
||||||
menumeta[num].fadestrength = value-1;
|
menumeta[num].fadestrength = value-1;
|
||||||
titlechanged = true;
|
titlechanged = true;
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "EXITPARENTS"))
|
else if (fastcmp(word, "NOENTERBUBBLE"))
|
||||||
{
|
{
|
||||||
menumeta[num].exitparents = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
|
menumeta[num].enterbubble = !(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||||
|
titlechanged = true;
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "NOEXITBUBBLE"))
|
||||||
|
{
|
||||||
|
menumeta[num].exitbubble = !(value || word2[0] == 'T' || word2[0] == 'Y');
|
||||||
titlechanged = true;
|
titlechanged = true;
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "ENTERTAG"))
|
else if (fastcmp(word, "ENTERTAG"))
|
||||||
|
@ -2030,6 +2051,16 @@ static void readmenu(MYFILE *f, INT32 num)
|
||||||
menumeta[num].exittag = value;
|
menumeta[num].exittag = value;
|
||||||
titlechanged = true;
|
titlechanged = true;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "ENTERWIPE"))
|
||||||
|
{
|
||||||
|
menumeta[num].enterwipe = value;
|
||||||
|
titlechanged = true;
|
||||||
|
}
|
||||||
|
else if (fastcmp(word, "EXITWIPE"))
|
||||||
|
{
|
||||||
|
menumeta[num].exitwipe = value;
|
||||||
|
titlechanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (!myfeof(f)); // finish when the line is empty
|
} while (!myfeof(f)); // finish when the line is empty
|
||||||
|
|
||||||
|
|
|
@ -546,6 +546,8 @@ extern boolean precache;
|
||||||
// wipegamestate can be set to -1
|
// wipegamestate can be set to -1
|
||||||
// to force a wipe on the next draw
|
// to force a wipe on the next draw
|
||||||
extern gamestate_t wipegamestate;
|
extern gamestate_t wipegamestate;
|
||||||
|
extern INT16 wipetypepre;
|
||||||
|
extern INT16 wipetypepost;
|
||||||
|
|
||||||
// debug flag to cancel adaptiveness
|
// debug flag to cancel adaptiveness
|
||||||
extern boolean singletics;
|
extern boolean singletics;
|
||||||
|
|
|
@ -1353,15 +1353,16 @@ void F_GameEndTicker(void)
|
||||||
// ==============
|
// ==============
|
||||||
void F_StartTitleScreen(void)
|
void F_StartTitleScreen(void)
|
||||||
{
|
{
|
||||||
MN_Start();
|
|
||||||
|
|
||||||
if (menumeta[MN_MAIN].musname[0])
|
if (menumeta[MN_MAIN].musname[0])
|
||||||
S_ChangeMusic(menumeta[MN_MAIN].musname, menumeta[MN_MAIN].mustrack, menumeta[MN_MAIN].muslooping);
|
S_ChangeMusic(menumeta[MN_MAIN].musname, menumeta[MN_MAIN].mustrack, menumeta[MN_MAIN].muslooping);
|
||||||
else
|
else
|
||||||
S_ChangeMusicInternal("_title", looptitle);
|
S_ChangeMusicInternal("_title", looptitle);
|
||||||
|
|
||||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
||||||
|
{
|
||||||
finalecount = 0;
|
finalecount = 0;
|
||||||
|
wipetypepost = menumeta[MN_MAIN].enterwipe;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
wipegamestate = GS_TITLESCREEN;
|
wipegamestate = GS_TITLESCREEN;
|
||||||
|
|
||||||
|
@ -1411,6 +1412,10 @@ void F_StartTitleScreen(void)
|
||||||
camera.chase = true;
|
camera.chase = true;
|
||||||
camera.height = 0;
|
camera.height = 0;
|
||||||
|
|
||||||
|
// Run enter linedef exec for MN_MAIN, since this is where we start
|
||||||
|
if (menumeta[MN_MAIN].entertag)
|
||||||
|
P_LinedefExecute(menumeta[MN_MAIN].entertag, players[displayplayer].mo, NULL);
|
||||||
|
|
||||||
wipegamestate = prevwipegamestate;
|
wipegamestate = prevwipegamestate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -84,12 +84,17 @@ extern UINT8 titlemapinaction;
|
||||||
//
|
//
|
||||||
// WIPE
|
// WIPE
|
||||||
//
|
//
|
||||||
|
// HACK for menu fading while titlemapinaction; skips the level check
|
||||||
|
#define FORCEWIPE -2
|
||||||
|
|
||||||
extern boolean WipeInAction;
|
extern boolean WipeInAction;
|
||||||
extern INT32 lastwipetic;
|
extern INT32 lastwipetic;
|
||||||
|
|
||||||
void F_WipeStartScreen(void);
|
void F_WipeStartScreen(void);
|
||||||
void F_WipeEndScreen(void);
|
void F_WipeEndScreen(void);
|
||||||
void F_RunWipe(UINT8 wipetype, boolean drawMenu);
|
void F_RunWipe(UINT8 wipetype, boolean drawMenu);
|
||||||
|
tic_t F_GetWipeLength(UINT8 wipetype);
|
||||||
|
boolean F_WipeExists(UINT8 wipetype);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
45
src/f_wipe.c
45
src/f_wipe.c
|
@ -378,3 +378,48 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
|
||||||
WipeInAction = false;
|
WipeInAction = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns tic length of wipe
|
||||||
|
* One lump equals one tic
|
||||||
|
*/
|
||||||
|
tic_t F_GetWipeLength(UINT8 wipetype)
|
||||||
|
{
|
||||||
|
#ifdef NOWIPE
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static char lumpname[10] = "FADEmmss";
|
||||||
|
lumpnum_t lumpnum;
|
||||||
|
UINT8 wipeframe;
|
||||||
|
|
||||||
|
if (wipetype > 99)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (wipeframe = 0; wipeframe < 100; wipeframe++)
|
||||||
|
{
|
||||||
|
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipetype, (UINT16)wipeframe);
|
||||||
|
|
||||||
|
lumpnum = W_CheckNumForName(lumpname);
|
||||||
|
if (lumpnum == LUMPERROR)
|
||||||
|
return --wipeframe;
|
||||||
|
}
|
||||||
|
return --wipeframe;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean F_WipeExists(UINT8 wipetype)
|
||||||
|
{
|
||||||
|
#ifdef NOWIPE
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
static char lumpname[10] = "FADEmm00";
|
||||||
|
lumpnum_t lumpnum;
|
||||||
|
|
||||||
|
if (wipetype > 99)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sprintf(&lumpname[4], "%.2hu00", (UINT16)wipetype);
|
||||||
|
|
||||||
|
lumpnum = W_CheckNumForName(lumpname);
|
||||||
|
return !(lumpnum == LUMPERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
345
src/m_menu.c
345
src/m_menu.c
|
@ -1809,9 +1809,9 @@ menu_t MP_RoomDef =
|
||||||
menu_t MP_PlayerSetupDef =
|
menu_t MP_PlayerSetupDef =
|
||||||
{
|
{
|
||||||
#ifdef NONET
|
#ifdef NONET
|
||||||
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12),
|
|
||||||
#else
|
|
||||||
MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6),
|
MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6),
|
||||||
|
#else
|
||||||
|
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12),
|
||||||
#endif
|
#endif
|
||||||
"M_SPLAYR",
|
"M_SPLAYR",
|
||||||
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
|
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
|
||||||
|
@ -1850,7 +1850,7 @@ menu_t OP_Joystick2Def = DEFAULTMENUSTYLE(
|
||||||
"M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30);
|
"M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30);
|
||||||
menu_t OP_JoystickSetDef =
|
menu_t OP_JoystickSetDef =
|
||||||
{
|
{
|
||||||
MN_OP_MAIN + (MN_OP_JOYSTICKSET << 12), // second level (<<6) set on runtime
|
MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime
|
||||||
"M_CONTRO",
|
"M_CONTRO",
|
||||||
sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t),
|
sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t),
|
||||||
&OP_Joystick1Def,
|
&OP_Joystick1Def,
|
||||||
|
@ -2196,6 +2196,10 @@ static tic_t xscrolltimer;
|
||||||
static tic_t yscrolltimer;
|
static tic_t yscrolltimer;
|
||||||
static INT32 menuanimtimer;
|
static INT32 menuanimtimer;
|
||||||
|
|
||||||
|
// menu IDs are equal to current/prevMenu in most cases, except MM_SPECIAL when we don't want to operate on Message, Pause, etc.
|
||||||
|
static UINT32 prevMenuId = 0;
|
||||||
|
static UINT32 activeMenuId = 0;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char musname[7];
|
char musname[7];
|
||||||
|
@ -2203,6 +2207,38 @@ typedef struct
|
||||||
boolean muslooping;
|
boolean muslooping;
|
||||||
} menumetamusic_t;
|
} menumetamusic_t;
|
||||||
|
|
||||||
|
void MN_InitInfoTables(void)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
// Called in d_main before SOC can get to the tables
|
||||||
|
// Set menumeta defaults
|
||||||
|
for (i = 0; i < NUMMENUTYPES; i++)
|
||||||
|
{
|
||||||
|
if (i != MN_MAIN)
|
||||||
|
{
|
||||||
|
menumeta[i].muslooping = true;
|
||||||
|
}
|
||||||
|
if (i == MN_SP_TIMEATTACK || i == MN_SP_NIGHTSATTACK)
|
||||||
|
strncpy(menumeta[i].musname, "_inter", 7);
|
||||||
|
if (i == MN_SP_PLAYER)
|
||||||
|
strncpy(menumeta[i].musname, "_chsel", 7);
|
||||||
|
|
||||||
|
// so-called "undefined"
|
||||||
|
menumeta[i].fadestrength = -1;
|
||||||
|
menumeta[i].hidetitlepics = -1; // inherits global hidetitlepics
|
||||||
|
menumeta[i].enterwipe = -1;
|
||||||
|
menumeta[i].exitwipe = -1;
|
||||||
|
// default true
|
||||||
|
menumeta[i].enterbubble = true;
|
||||||
|
menumeta[i].exitbubble = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================================
|
||||||
|
// TREE ITERATION
|
||||||
|
// ====================================
|
||||||
|
|
||||||
// UINT32 menutype - current menutype_t
|
// UINT32 menutype - current menutype_t
|
||||||
// INT32 level - current level up the tree, higher means younger
|
// INT32 level - current level up the tree, higher means younger
|
||||||
// INT32 *retval - Return value
|
// INT32 *retval - Return value
|
||||||
|
@ -2210,7 +2246,7 @@ typedef struct
|
||||||
//
|
//
|
||||||
// return true - stop iterating
|
// return true - stop iterating
|
||||||
// return false - continue
|
// return false - continue
|
||||||
typedef boolean (*menutree_iterator)(UINT32, INT32, INT32 *, void **);
|
typedef boolean (*menutree_iterator)(UINT32, INT32, INT32 *, void **, boolean fromoldest);
|
||||||
|
|
||||||
static INT32 M_IterateMenuTree(menutree_iterator itfunc, void *input)
|
static INT32 M_IterateMenuTree(menutree_iterator itfunc, void *input)
|
||||||
{
|
{
|
||||||
|
@ -2220,8 +2256,8 @@ static INT32 M_IterateMenuTree(menutree_iterator itfunc, void *input)
|
||||||
for (i = NUMMENULEVELS; i >= 0; i--)
|
for (i = NUMMENULEVELS; i >= 0; i--)
|
||||||
{
|
{
|
||||||
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
||||||
menutype = (currentMenu->menuid & bitmask) >> (MENUBITS*i);
|
menutype = (activeMenuId & bitmask) >> (MENUBITS*i);
|
||||||
if (itfunc(menutype, i, &retval, &input))
|
if (itfunc(menutype, i, &retval, &input, false))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2236,8 +2272,8 @@ static INT32 M_IterateMenuTreeFromTop(menutree_iterator itfunc, void *input)
|
||||||
for (i = 0; i <= NUMMENULEVELS; i++)
|
for (i = 0; i <= NUMMENULEVELS; i++)
|
||||||
{
|
{
|
||||||
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
||||||
menutype = (currentMenu->menuid & bitmask) >> (MENUBITS*i);
|
menutype = (activeMenuId & bitmask) >> (MENUBITS*i);
|
||||||
if (itfunc(menutype, i, &retval, &input))
|
if (itfunc(menutype, i, &retval, &input, true))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2248,17 +2284,32 @@ static INT32 M_IterateMenuTreeFromTop(menutree_iterator itfunc, void *input)
|
||||||
// ITERATORS
|
// ITERATORS
|
||||||
// ====================================
|
// ====================================
|
||||||
|
|
||||||
static boolean MIT_GetEdgeMenu(UINT32 menutype, INT32 level, INT32 *retval, void **input)
|
static boolean MIT_GetMenuAtLevel(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
{
|
{
|
||||||
|
INT32 *inputptr = (INT32*)*input;
|
||||||
|
INT32 targetlevel = *inputptr;
|
||||||
if (menutype)
|
if (menutype)
|
||||||
{
|
{
|
||||||
*retval = menutype;
|
// \todo offset targetlevel by failed initial attempts
|
||||||
return true;
|
if (level == targetlevel || targetlevel < 0)
|
||||||
|
{
|
||||||
|
*retval = menutype;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (targetlevel >= 0)
|
||||||
|
{
|
||||||
|
// offset targetlevel by failed attempts; this should only happen in beginning of iteration
|
||||||
|
if (fromoldest)
|
||||||
|
(*inputptr)++;
|
||||||
|
else
|
||||||
|
(*inputptr)--; // iterating backwards, so count from highest
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean MIT_GetEdgeLevel(UINT32 menutype, INT32 level, INT32 *retval, void **input)
|
#if 0
|
||||||
|
static boolean MIT_GetEdgeLevel(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
{
|
{
|
||||||
if (menutype)
|
if (menutype)
|
||||||
{
|
{
|
||||||
|
@ -2267,22 +2318,36 @@ static boolean MIT_GetEdgeLevel(UINT32 menutype, INT32 level, INT32 *retval, voi
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static boolean MIT_DrawScrollingBackground(UINT32 menutype, INT32 level, INT32 *retval, void **input)
|
static boolean MIT_HasMenuType(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
|
{
|
||||||
|
menutype_t inputtype = *(menutype_t*)*input;
|
||||||
|
if (menutype == inputtype)
|
||||||
|
{
|
||||||
|
*retval = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean MIT_DrawScrollingBackground(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
{
|
{
|
||||||
char *defaultname = (char*)*input;
|
char *defaultname = (char*)*input;
|
||||||
|
|
||||||
if (menumeta[menutype].bgname[0])
|
if (menumeta[menutype].bgname[0] && menumeta[menutype].bgname[0] != CHAR_MAX)
|
||||||
{
|
{
|
||||||
M_SkyScroll(menumeta[menutype].titlescrollxspeed, menumeta[menutype].titlescrollyspeed, menumeta[menutype].bgname);
|
M_SkyScroll(menumeta[menutype].titlescrollxspeed, menumeta[menutype].titlescrollyspeed, menumeta[menutype].bgname);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (!level && defaultname && defaultname[0])
|
else if (menumeta[menutype].bgname[0] == CHAR_MAX && titlemapinaction) // hide the background
|
||||||
|
return true;
|
||||||
|
else if (!level && defaultname && defaultname[0] && !titlemapinaction) // hide the background by default in titlemap
|
||||||
M_SkyScroll(titlescrollxspeed, titlescrollyspeed, defaultname);
|
M_SkyScroll(titlescrollxspeed, titlescrollyspeed, defaultname);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean MIT_ChangeMusic(UINT32 menutype, INT32 level, INT32 *retval, void **input)
|
static boolean MIT_ChangeMusic(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
{
|
{
|
||||||
menumetamusic_t *defaultmusic = (menumetamusic_t*)*input;
|
menumetamusic_t *defaultmusic = (menumetamusic_t*)*input;
|
||||||
|
|
||||||
|
@ -2291,12 +2356,19 @@ static boolean MIT_ChangeMusic(UINT32 menutype, INT32 level, INT32 *retval, void
|
||||||
S_ChangeMusic(menumeta[menutype].musname, menumeta[menutype].mustrack, menumeta[menutype].muslooping);
|
S_ChangeMusic(menumeta[menutype].musname, menumeta[menutype].mustrack, menumeta[menutype].muslooping);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (menumeta[menutype].musstop)
|
||||||
|
{
|
||||||
|
S_StopMusic();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (menumeta[menutype].musignore)
|
||||||
|
return true;
|
||||||
else if (!level && defaultmusic && defaultmusic->musname[0])
|
else if (!level && defaultmusic && defaultmusic->musname[0])
|
||||||
S_ChangeMusic(defaultmusic->musname, defaultmusic->mustrack, defaultmusic->muslooping);
|
S_ChangeMusic(defaultmusic->musname, defaultmusic->mustrack, defaultmusic->muslooping);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean MIT_FadeScreen(UINT32 menutype, INT32 level, INT32 *retval, void **input)
|
static boolean MIT_FadeScreen(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
{
|
{
|
||||||
UINT8 defaultvalue = *(UINT8*)*input;
|
UINT8 defaultvalue = *(UINT8*)*input;
|
||||||
if (menumeta[menutype].fadestrength >= 0)
|
if (menumeta[menutype].fadestrength >= 0)
|
||||||
|
@ -2310,7 +2382,7 @@ static boolean MIT_FadeScreen(UINT32 menutype, INT32 level, INT32 *retval, void
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean MIT_GetHideTitlePics(UINT32 menutype, INT32 level, INT32 *retval, void **input)
|
static boolean MIT_GetHideTitlePics(UINT32 menutype, INT32 level, INT32 *retval, void **input, boolean fromoldest)
|
||||||
{
|
{
|
||||||
(void)input;
|
(void)input;
|
||||||
if (menumeta[menutype].hidetitlepics >= 0)
|
if (menumeta[menutype].hidetitlepics >= 0)
|
||||||
|
@ -2327,20 +2399,44 @@ static boolean MIT_GetHideTitlePics(UINT32 menutype, INT32 level, INT32 *retval,
|
||||||
// TREE RETRIEVAL
|
// TREE RETRIEVAL
|
||||||
// ====================================
|
// ====================================
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// level is nth level relative to top or bottom from tree
|
||||||
|
static menutype_t M_GetMenuAtLevel(INT32 level, boolean fromoldest)
|
||||||
|
{
|
||||||
|
if (fromoldest)
|
||||||
|
return M_IterateMenuTreeFromTop(MIT_GetMenuAtLevel, &level);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (level >= 0)
|
||||||
|
level = NUMMENULEVELS - level; // iterating backwards, so count from highest value
|
||||||
|
return M_IterateMenuTree(MIT_GetMenuAtLevel, &level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static UINT8 M_GetYoungestChildMenu() // aka the active menu
|
static UINT8 M_GetYoungestChildMenu() // aka the active menu
|
||||||
{
|
{
|
||||||
return M_IterateMenuTree(MIT_GetEdgeMenu, NULL);
|
INT32 targetlevel = -1;
|
||||||
|
return M_IterateMenuTree(MIT_GetMenuAtLevel, &targetlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static UINT8 M_GetOldestParentMenu()
|
static UINT8 M_GetOldestParentMenu()
|
||||||
{
|
{
|
||||||
return M_IterateMenuTreeFromTop(MIT_GetEdgeMenu, NULL);
|
INT32 targetlevel = -1;
|
||||||
|
return M_IterateMenuTreeFromTop(MIT_GetMenuAtLevel, &targetlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT8 M_GetYoungestChildLevel() // aka the active menu
|
static UINT8 M_GetYoungestChildLevel() // aka the active menu
|
||||||
{
|
{
|
||||||
return M_IterateMenuTree(MIT_GetEdgeLevel, NULL);
|
return M_IterateMenuTree(MIT_GetEdgeLevel, NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static boolean M_HasMenuType(menutype_t needletype)
|
||||||
|
{
|
||||||
|
return M_IterateMenuTreeFromTop(MIT_HasMenuType, &needletype);
|
||||||
|
}
|
||||||
|
|
||||||
// ====================================
|
// ====================================
|
||||||
// EFFECTS
|
// EFFECTS
|
||||||
|
@ -2377,6 +2473,162 @@ boolean M_GetHideTitlePics(void)
|
||||||
return (retval >= 0 ? retval : hidetitlepics);
|
return (retval >= 0 ? retval : hidetitlepics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====================================
|
||||||
|
// MENU STATE
|
||||||
|
// ====================================
|
||||||
|
|
||||||
|
static INT32 exitlevel, enterlevel, anceslevel;
|
||||||
|
static INT16 exittype, entertype;
|
||||||
|
static INT16 exitwipe, enterwipe;
|
||||||
|
static boolean exitbubble, enterbubble;
|
||||||
|
static INT16 exittag, entertag;
|
||||||
|
|
||||||
|
static void M_HandleMenuMetaState(menu_t *newMenu)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
UINT32 bitmask;
|
||||||
|
SINT8 prevtype, activetype, menutype;
|
||||||
|
|
||||||
|
if (M_HasMenuType(MN_SPECIAL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (currentMenu && newMenu && currentMenu->menuid == newMenu->menuid) // same menu?
|
||||||
|
return;
|
||||||
|
|
||||||
|
exittype = entertype = exitlevel = enterlevel = anceslevel = exitwipe = enterwipe = -1;
|
||||||
|
exitbubble = enterbubble = true;
|
||||||
|
|
||||||
|
prevMenuId = currentMenu ? currentMenu->menuid : 0;
|
||||||
|
activeMenuId = newMenu ? newMenu->menuid : 0;
|
||||||
|
|
||||||
|
// don't do the below during the in-game menus
|
||||||
|
if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Loop through both menu IDs in parallel and look for type changes
|
||||||
|
// The youngest child in activeMenuId is the entered menu
|
||||||
|
// The youngest child in prevMenuId is the exited menu
|
||||||
|
|
||||||
|
// 0. Get the type and level of each menu, and level of common ancestor
|
||||||
|
// 1. Get the wipes for both, then run the exit wipe
|
||||||
|
// 2. Change music (so that execs can change it again later)
|
||||||
|
// 3. Run each exit exec on the prevMenuId up to the common ancestor (UNLESS NoBubbleExecs)
|
||||||
|
// 4. Run each entrance exec on the activeMenuId down from the common ancestor (UNLESS NoBubbleExecs)
|
||||||
|
// 5. Run the entrance wipe
|
||||||
|
|
||||||
|
// Get the parameters for each menu
|
||||||
|
for (i = NUMMENULEVELS; i >= 0; i--)
|
||||||
|
{
|
||||||
|
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
||||||
|
prevtype = (prevMenuId & bitmask) >> (MENUBITS*i);
|
||||||
|
activetype = (activeMenuId & bitmask) >> (MENUBITS*i);
|
||||||
|
|
||||||
|
if (prevtype && (exittype < 0))
|
||||||
|
{
|
||||||
|
exittype = prevtype;
|
||||||
|
exitlevel = i;
|
||||||
|
exitwipe = menumeta[exittype].exitwipe;
|
||||||
|
exitbubble = menumeta[exittype].exitbubble;
|
||||||
|
exittag = menumeta[exittype].exittag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activetype && (entertype < 0))
|
||||||
|
{
|
||||||
|
entertype = activetype;
|
||||||
|
enterlevel = i;
|
||||||
|
enterwipe = menumeta[entertype].enterwipe;
|
||||||
|
enterbubble = menumeta[entertype].enterbubble;
|
||||||
|
entertag = menumeta[entertype].entertag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevtype && activetype && prevtype == activetype && anceslevel < 0)
|
||||||
|
{
|
||||||
|
anceslevel = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the music
|
||||||
|
M_ChangeMusic("_title", false);
|
||||||
|
|
||||||
|
// Run the linedef execs
|
||||||
|
if (titlemapinaction)
|
||||||
|
{
|
||||||
|
// Run the exit tags
|
||||||
|
if (enterlevel <= exitlevel) // equals is an edge case
|
||||||
|
{
|
||||||
|
if (exitbubble)
|
||||||
|
{
|
||||||
|
for (i = exitlevel; i > anceslevel; i--) // don't run the common ancestor's exit tag
|
||||||
|
{
|
||||||
|
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
||||||
|
menutype = (prevMenuId & bitmask) >> (MENUBITS*i);
|
||||||
|
if (menumeta[menutype].exittag)
|
||||||
|
P_LinedefExecute(menumeta[menutype].exittag, players[displayplayer].mo, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (exittag)
|
||||||
|
P_LinedefExecute(exittag, players[displayplayer].mo, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the enter tags
|
||||||
|
if (enterlevel >= exitlevel) // equals is an edge case
|
||||||
|
{
|
||||||
|
if (enterbubble)
|
||||||
|
{
|
||||||
|
for (i = anceslevel+1; i <= enterlevel; i++) // don't run the common ancestor's enter tag
|
||||||
|
{
|
||||||
|
bitmask = ((1 << MENUBITS) - 1) << (MENUBITS*i);
|
||||||
|
menutype = (activeMenuId & bitmask) >> (MENUBITS*i);
|
||||||
|
if (menumeta[menutype].entertag)
|
||||||
|
P_LinedefExecute(menumeta[menutype].entertag, players[displayplayer].mo, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entertag)
|
||||||
|
P_LinedefExecute(entertag, players[displayplayer].mo, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set the wipes for next frame
|
||||||
|
if (
|
||||||
|
(exitwipe >= 0 && enterlevel <= exitlevel) ||
|
||||||
|
(enterwipe >= 0 && enterlevel >= exitlevel)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (gamestate == GS_TIMEATTACK)
|
||||||
|
wipetypepre = (exitwipe && enterlevel <= exitlevel) ? exitwipe : -1; // force default
|
||||||
|
else
|
||||||
|
// HACK: INT16_MAX signals to not wipe
|
||||||
|
// because 0 is a valid index and -1 means default
|
||||||
|
wipetypepre = (exitwipe && enterlevel <= exitlevel) ? exitwipe : INT16_MAX;
|
||||||
|
wipetypepost = (enterwipe && enterlevel >= exitlevel) ? enterwipe : INT16_MAX;
|
||||||
|
wipegamestate = FORCEWIPE;
|
||||||
|
// D_Display runs the next step of processing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
M_ApplyMenuMetaState(); // run the next step now
|
||||||
|
}
|
||||||
|
|
||||||
|
void M_ApplyMenuMetaState(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
INT32 i;
|
||||||
|
UINT32 bitmask, menutype;
|
||||||
|
|
||||||
|
if (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 3. Run each exit exec on the prevMenuId up to the common ancestor (UNLESS NoBubbleExecs)
|
||||||
|
// 4. Run each entrance exec on the activeMenuId down from the common ancestor (UNLESS NoBubbleExecs)
|
||||||
|
|
||||||
|
// \todo placeholder -- do we want any logic to happen between wipes?
|
||||||
|
// do we want to split linedef execs between pre-wipe and tween-wipe?
|
||||||
|
|
||||||
|
// D_Display runs the enter wipe, if applicable
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// BASIC MENU HANDLING
|
// BASIC MENU HANDLING
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
@ -2402,6 +2654,7 @@ static void M_GoBack(INT32 choice)
|
||||||
Z_Free(levelselect.rows);
|
Z_Free(levelselect.rows);
|
||||||
levelselect.rows = NULL;
|
levelselect.rows = NULL;
|
||||||
menuactive = false;
|
menuactive = false;
|
||||||
|
wipetypepre = menumeta[M_GetYoungestChildMenu(currentMenu->menuid)].exitwipe;
|
||||||
D_StartTitle();
|
D_StartTitle();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3062,6 +3315,9 @@ void M_SetupNextMenu(menu_t *menudef)
|
||||||
if (currentMenu != menudef && !currentMenu->quitroutine())
|
if (currentMenu != menudef && !currentMenu->quitroutine())
|
||||||
return; // we can't quit this menu (also used to set parameter from the menu)
|
return; // we can't quit this menu (also used to set parameter from the menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M_HandleMenuMetaState(menudef);
|
||||||
|
|
||||||
currentMenu = menudef;
|
currentMenu = menudef;
|
||||||
itemOn = currentMenu->lastOn;
|
itemOn = currentMenu->lastOn;
|
||||||
|
|
||||||
|
@ -3170,27 +3426,11 @@ void M_Init(void)
|
||||||
// COMMON MENU DRAW ROUTINES
|
// COMMON MENU DRAW ROUTINES
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
void MN_InitInfoTables(void)
|
|
||||||
{
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
// Called in d_main before SOC can get to the tables
|
|
||||||
// Set menumeta defaults
|
|
||||||
for (i = 0; i < NUMMENUTYPES; i++)
|
|
||||||
{
|
|
||||||
if (i != MN_MAIN)
|
|
||||||
{
|
|
||||||
menumeta[i].muslooping = true;
|
|
||||||
}
|
|
||||||
// so-called "undefined"
|
|
||||||
menumeta[i].fadestrength = -1;
|
|
||||||
menumeta[i].hidetitlepics = -1; // inherits global hidetitlepics
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MN_Start(void)
|
void MN_Start(void)
|
||||||
{
|
{
|
||||||
menuanimtimer = 0;
|
menuanimtimer = 0;
|
||||||
|
prevMenuId = 0;
|
||||||
|
activeMenuId = MainDef.menuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MN_Ticker(boolean run)
|
void MN_Ticker(boolean run)
|
||||||
|
@ -5006,7 +5246,10 @@ static void M_DrawMessageMenu(void)
|
||||||
|
|
||||||
// hack: draw RA background in RA menus
|
// hack: draw RA background in RA menus
|
||||||
if (gamestate == GS_TIMEATTACK)
|
if (gamestate == GS_TIMEATTACK)
|
||||||
|
{
|
||||||
M_DrawScrollingBackground("SRB2BACK");
|
M_DrawScrollingBackground("SRB2BACK");
|
||||||
|
M_DrawFadeScreen(0);
|
||||||
|
}
|
||||||
|
|
||||||
M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines);
|
M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines);
|
||||||
|
|
||||||
|
@ -7397,6 +7640,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
|
||||||
// Black BG
|
// Black BG
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||||
//M_DrawScrollingBackground("SRB2BACK");
|
//M_DrawScrollingBackground("SRB2BACK");
|
||||||
|
//M_DrawFadeScreen(0);
|
||||||
|
|
||||||
// Character select profile images!1
|
// Character select profile images!1
|
||||||
M_DrawTextBox(0, my, 16, 20);
|
M_DrawTextBox(0, my, 16, 20);
|
||||||
|
@ -7783,7 +8027,6 @@ void M_DrawTimeAttackMenu(void)
|
||||||
INT32 i, x, y, cursory = 0;
|
INT32 i, x, y, cursory = 0;
|
||||||
UINT16 dispstatus;
|
UINT16 dispstatus;
|
||||||
patch_t *PictureOfUrFace;
|
patch_t *PictureOfUrFace;
|
||||||
menutype_t menutype = M_GetYoungestChildMenu();
|
|
||||||
|
|
||||||
M_ChangeMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback
|
M_ChangeMusic("_inter", true); // Eww, but needed for when user hits escape during demo playback
|
||||||
|
|
||||||
|
@ -7958,15 +8201,13 @@ static void M_TimeAttack(INT32 choice)
|
||||||
|
|
||||||
M_PatchSkinNameTable();
|
M_PatchSkinNameTable();
|
||||||
|
|
||||||
|
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
|
||||||
M_SetupNextMenu(&SP_TimeAttackDef);
|
M_SetupNextMenu(&SP_TimeAttackDef);
|
||||||
if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0])
|
if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0])
|
||||||
CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]);
|
CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]);
|
||||||
else
|
else
|
||||||
Nextmap_OnChange();
|
Nextmap_OnChange();
|
||||||
|
|
||||||
G_SetGamestate(GS_TIMEATTACK);
|
|
||||||
M_ChangeMusic("_inter", true);
|
|
||||||
|
|
||||||
itemOn = tastart; // "Start" is selected.
|
itemOn = tastart; // "Start" is selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8137,15 +8378,13 @@ static void M_NightsAttack(INT32 choice)
|
||||||
// This is really just to make sure Sonic is the played character, just in case
|
// This is really just to make sure Sonic is the played character, just in case
|
||||||
M_PatchSkinNameTable();
|
M_PatchSkinNameTable();
|
||||||
|
|
||||||
|
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
|
||||||
M_SetupNextMenu(&SP_NightsAttackDef);
|
M_SetupNextMenu(&SP_NightsAttackDef);
|
||||||
if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0])
|
if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0])
|
||||||
CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]);
|
CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]);
|
||||||
else
|
else
|
||||||
Nextmap_OnChange();
|
Nextmap_OnChange();
|
||||||
|
|
||||||
G_SetGamestate(GS_TIMEATTACK);
|
|
||||||
M_ChangeMusic("_inter", true);
|
|
||||||
|
|
||||||
itemOn = nastart; // "Start" is selected.
|
itemOn = nastart; // "Start" is selected.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8370,15 +8609,17 @@ static void M_ModeAttackEndGame(INT32 choice)
|
||||||
default:
|
default:
|
||||||
case ATTACKING_RECORD:
|
case ATTACKING_RECORD:
|
||||||
currentMenu = &SP_TimeAttackDef;
|
currentMenu = &SP_TimeAttackDef;
|
||||||
|
wipetypepost = menumeta[MN_SP_TIMEATTACK].enterwipe;
|
||||||
break;
|
break;
|
||||||
case ATTACKING_NIGHTS:
|
case ATTACKING_NIGHTS:
|
||||||
currentMenu = &SP_NightsAttackDef;
|
currentMenu = &SP_NightsAttackDef;
|
||||||
|
wipetypepost = menumeta[MN_SP_NIGHTSATTACK].enterwipe;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
itemOn = currentMenu->lastOn;
|
itemOn = currentMenu->lastOn;
|
||||||
G_SetGamestate(GS_TIMEATTACK);
|
G_SetGamestate(GS_TIMEATTACK);
|
||||||
modeattacking = ATTACKING_NONE;
|
modeattacking = ATTACKING_NONE;
|
||||||
M_ChangeMusic("_inter", true);
|
M_ChangeMusic("_title", true);
|
||||||
Nextmap_OnChange();
|
Nextmap_OnChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9556,6 +9797,10 @@ static void M_Setup1PJoystickMenu(INT32 choice)
|
||||||
{
|
{
|
||||||
setupcontrols_secondaryplayer = false;
|
setupcontrols_secondaryplayer = false;
|
||||||
OP_JoystickSetDef.prevMenu = &OP_Joystick1Def;
|
OP_JoystickSetDef.prevMenu = &OP_Joystick1Def;
|
||||||
|
OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS);
|
||||||
|
OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << (MENUBITS*2));
|
||||||
|
OP_JoystickSetDef.menuid |= MN_OP_P1CONTROLS << MENUBITS;
|
||||||
|
OP_JoystickSetDef.menuid |= MN_OP_P1JOYSTICK << (MENUBITS*2);
|
||||||
M_SetupJoystickMenu(choice);
|
M_SetupJoystickMenu(choice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9563,6 +9808,10 @@ static void M_Setup2PJoystickMenu(INT32 choice)
|
||||||
{
|
{
|
||||||
setupcontrols_secondaryplayer = true;
|
setupcontrols_secondaryplayer = true;
|
||||||
OP_JoystickSetDef.prevMenu = &OP_Joystick2Def;
|
OP_JoystickSetDef.prevMenu = &OP_Joystick2Def;
|
||||||
|
OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS);
|
||||||
|
OP_JoystickSetDef.menuid &= ~(((1 << MENUBITS) - 1) << (MENUBITS*2));
|
||||||
|
OP_JoystickSetDef.menuid |= MN_OP_P2CONTROLS << MENUBITS;
|
||||||
|
OP_JoystickSetDef.menuid |= MN_OP_P2JOYSTICK << (MENUBITS*2);
|
||||||
M_SetupJoystickMenu(choice);
|
M_SetupJoystickMenu(choice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9600,6 +9849,8 @@ static void M_Setup1PControlsMenu(INT32 choice)
|
||||||
OP_ChangeControlsMenu[23+3].status = IT_CALL|IT_STRING2;
|
OP_ChangeControlsMenu[23+3].status = IT_CALL|IT_STRING2;
|
||||||
|
|
||||||
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
|
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
|
||||||
|
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6)
|
||||||
|
OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6)
|
||||||
M_SetupNextMenu(&OP_ChangeControlsDef);
|
M_SetupNextMenu(&OP_ChangeControlsDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9625,6 +9876,8 @@ static void M_Setup2PControlsMenu(INT32 choice)
|
||||||
OP_ChangeControlsMenu[23+3].status = IT_GRAYEDOUT2;
|
OP_ChangeControlsMenu[23+3].status = IT_GRAYEDOUT2;
|
||||||
|
|
||||||
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
|
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
|
||||||
|
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6)
|
||||||
|
OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6)
|
||||||
M_SetupNextMenu(&OP_ChangeControlsDef);
|
M_SetupNextMenu(&OP_ChangeControlsDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,11 +132,16 @@ typedef struct
|
||||||
char musname[7]; ///< Music track to play. "" for no music.
|
char musname[7]; ///< Music track to play. "" for no music.
|
||||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||||
boolean muslooping; ///< Loop the music
|
boolean muslooping; ///< Loop the music
|
||||||
|
boolean musstop; ///< Don't play any music
|
||||||
|
boolean musignore; ///< Let the current music keep playing
|
||||||
|
|
||||||
SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined
|
SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined
|
||||||
boolean exitparents; // run exit line exec on parent menus when entering a child menu
|
boolean enterbubble; // run all entrance line execs after common ancestor and up to child. If false, only run the child's exec
|
||||||
|
boolean exitbubble; // run all exit line execs from child and up to before common ancestor. If false, only run the child's exec
|
||||||
INT32 entertag; // line exec to run on menu enter, if titlemap
|
INT32 entertag; // line exec to run on menu enter, if titlemap
|
||||||
INT32 exittag; // line exec to run on menu exit, if titlemap
|
INT32 exittag; // line exec to run on menu exit, if titlemap
|
||||||
|
INT16 enterwipe; // wipe type to run on menu enter, -1 means default
|
||||||
|
INT16 exitwipe; // wipe type to run on menu exit, -1 means default
|
||||||
} menumeta_t;
|
} menumeta_t;
|
||||||
|
|
||||||
extern menumeta_t menumeta[NUMMENUTYPES];
|
extern menumeta_t menumeta[NUMMENUTYPES];
|
||||||
|
@ -147,6 +152,7 @@ boolean M_GetHideTitlePics(void);
|
||||||
void MN_Ticker(boolean run);
|
void MN_Ticker(boolean run);
|
||||||
void MN_Start(void);
|
void MN_Start(void);
|
||||||
void MN_InitInfoTables(void);
|
void MN_InitInfoTables(void);
|
||||||
|
void M_ApplyMenuMetaState(void);
|
||||||
|
|
||||||
|
|
||||||
// Called by main loop,
|
// Called by main loop,
|
||||||
|
|
|
@ -2737,7 +2737,13 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||||
|
|
||||||
F_WipeEndScreen();
|
F_WipeEndScreen();
|
||||||
F_RunWipe(wipedefs[wipe_level_toblack], false);
|
// for titlemap: run a specific wipe if specified
|
||||||
|
// needed for exiting time attack
|
||||||
|
if (wipetypepre != INT16_MAX)
|
||||||
|
F_RunWipe(
|
||||||
|
(wipetypepre >= 0 && F_WipeExists(wipetypepre)) ? wipetypepre : wipedefs[wipe_level_toblack],
|
||||||
|
false);
|
||||||
|
wipetypepre = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
|
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
|
||||||
|
|
Loading…
Reference in New Issue