Implemented features

* M_SkyScroll optimization with still speeds; refactor background drawing
* Music (in time attack screens so far)
* FadeStrength
* HideTitlePics
* Scrolling backgrounds in Time Attack (moved F_SkyScroll to m_menu)
This commit is contained in:
mazmazz 2018-11-17 01:21:21 -05:00
parent 1e6369e8de
commit d2bbddbed4
7 changed files with 221 additions and 104 deletions

View File

@ -1096,6 +1096,9 @@ void D_SRB2Main(void)
// adapt tables to SRB2's needs, including extra slots for dehacked file support
P_PatchInfoTables();
// initiate menu metadata before SOCcing them
MN_InitInfoTables();
//---------------------------------------------------- READY TIME
// we need to check for dedicated before initialization of some subsystems

View File

@ -1963,6 +1963,7 @@ static void readmenu(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "HIDEPICS"))
{
// true by default, except MM_MAIN
menumeta[num].hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
titlechanged = true;
}
@ -2004,12 +2005,14 @@ static void readmenu(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "MUSICLOOP"))
{
// true by default except MM_MAIN
menumeta[num].muslooping = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
titlechanged = true;
}
else if (fastcmp(word, "FADESCREEN"))
else if (fastcmp(word, "FADESTRENGTH"))
{
menumeta[num].fadescreen = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
// one-based, <= 0 means use default value. 1-32
menumeta[num].fadestrength = value-1;
titlechanged = true;
}
else if (fastcmp(word, "EXITPARENTS"))

View File

@ -80,8 +80,6 @@ static patch_t *ttspop5;
static patch_t *ttspop6;
static patch_t *ttspop7;
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname);
//
// PROMPT STATE
//
@ -182,64 +180,6 @@ static void F_NewCutscene(const char *basetext)
cutscene_textcount = TICRATE/2;
}
//
// F_SkyScroll
//
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname)
{
INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex;
INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley;
boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0);
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT16 patwidth, patheight;
INT32 pw, ph; // scaled by dupz
patch_t *pat;
INT32 i, j;
if (rendermode == render_none)
return;
if (!patchname || !patchname[0])
{
V_DrawFill(0, 0, vid.width, vid.height, 31);
return;
}
pat = W_CachePatchName(patchname, PU_CACHE);
patwidth = SHORT(pat->width);
patheight = SHORT(pat->height);
pw = patwidth * dupz;
ph = patheight * dupz;
tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center
tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2;
animtimer = ((finalecount*scrollxspeed)/16 + patwidth*xneg) % (patwidth);
skullAnimCounter = ((finalecount*scrollyspeed)/16 + patheight*yneg) % (patheight);
// coordinate offsets
xscrolled = animtimer * dupz;
yscrolled = skullAnimCounter * dupz;
for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0;
i < tilex;
x += pw, i++)
{
for (y = (yispos) ? -ph*(tiley-1)+ph : 0, j = 0;
j < tiley;
y += ph, j++)
{
V_DrawScaledPatch(
(xispos) ? xscrolled - x : x + xscrolled,
(yispos) ? yscrolled - y : y + yscrolled,
V_NOSCALESTART, pat);
}
}
W_UnlockCachedPatch(pat);
}
// =============
// INTRO SCENE
// =============
@ -670,7 +610,7 @@ static void F_IntroDrawScene(void)
}
else
{
F_SkyScroll(80*4, 0, "TITLESKY");
M_SkyScroll(80*4, 0, "TITLESKY");
if (timetonext == 6)
{
stoptimer = finalecount;
@ -1413,6 +1353,8 @@ void F_GameEndTicker(void)
// ==============
void F_StartTitleScreen(void)
{
MN_Start();
if (menumeta[MN_MAIN].musname[0])
S_ChangeMusic(menumeta[MN_MAIN].musname, menumeta[MN_MAIN].mustrack, menumeta[MN_MAIN].muslooping);
else
@ -1507,6 +1449,8 @@ void F_StartTitleScreen(void)
// (no longer) De-Demo'd Title Screen
void F_TitleScreenDrawer(void)
{
boolean hidepics;
if (modeattacking)
return; // We likely came here from retrying. Don't do a damn thing.
@ -1518,7 +1462,8 @@ void F_TitleScreenDrawer(void)
return;
// rei|miru: use title pics?
if (hidetitlepics)
hidepics = M_GetHideTitlePics();
if (hidepics)
#ifdef HAVE_BLUA
goto luahook;
#else

View File

@ -40,7 +40,6 @@ void F_TextPromptTicker(void);
void F_GameEndDrawer(void);
void F_IntroDrawer(void);
void F_TitleScreenDrawer(void);
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname);
void F_GameEvaluationDrawer(void);
void F_StartGameEvaluation(void);

View File

@ -1954,6 +1954,7 @@ void G_Ticker(boolean run)
break;
case GS_TIMEATTACK:
MN_Ticker(run);
break;
case GS_INTRO:
@ -1993,6 +1994,7 @@ void G_Ticker(boolean run)
if (titlemapinaction) P_Ticker(run); // then intentionally fall through
/* FALLTHRU */
case GS_WAITINGPLAYERS:
MN_Ticker(run);
F_TitleScreenTicker(run);
break;

View File

@ -2192,6 +2192,16 @@ menu_t *currentMenu = &MainDef;
// =========================================================================
menumeta_t menumeta[NUMMENUTYPES];
static tic_t xscrolltimer;
static tic_t yscrolltimer;
static INT32 menuanimtimer;
typedef struct
{
char musname[7];
UINT16 mustrack;
boolean muslooping;
} menumetamusic_t;
// UINT32 menutype - current menutype_t
// INT32 level - current level up the tree, higher means younger
@ -2258,31 +2268,58 @@ static boolean MIT_GetEdgeLevel(UINT32 menutype, INT32 level, INT32 *retval, voi
return false;
}
static boolean MIT_DrawBackground(UINT32 menutype, INT32 level, INT32 *retval, void **input)
{
char *defaultname = (char*)*input;
if (menumeta[menutype].bgname[0])
{
V_DrawPatchFill(W_CachePatchName(menumeta[menutype].bgname, PU_CACHE));
return true;
}
else if (!level && defaultname && defaultname[0])
V_DrawPatchFill(W_CachePatchName(defaultname, PU_CACHE));
return false;
}
static boolean MIT_DrawScrollingBackground(UINT32 menutype, INT32 level, INT32 *retval, void **input)
{
char *defaultname = (char*)*input;
if (menumeta[menutype].bgname[0])
{
F_SkyScroll(menumeta[menutype].titlescrollxspeed, menumeta[menutype].titlescrollyspeed, menumeta[menutype].bgname);
M_SkyScroll(menumeta[menutype].titlescrollxspeed, menumeta[menutype].titlescrollyspeed, menumeta[menutype].bgname);
return true;
}
else if (!level && defaultname && defaultname[0])
F_SkyScroll(titlescrollxspeed, titlescrollyspeed, defaultname);
M_SkyScroll(titlescrollxspeed, titlescrollyspeed, defaultname);
return false;
}
static boolean MIT_ChangeMusic(UINT32 menutype, INT32 level, INT32 *retval, void **input)
{
menumetamusic_t *defaultmusic = (menumetamusic_t*)*input;
if (menumeta[menutype].musname[0])
{
S_ChangeMusic(menumeta[menutype].musname, menumeta[menutype].mustrack, menumeta[menutype].muslooping);
return true;
}
else if (!level && defaultmusic && defaultmusic->musname[0])
S_ChangeMusic(defaultmusic->musname, defaultmusic->mustrack, defaultmusic->muslooping);
return false;
}
static boolean MIT_FadeScreen(UINT32 menutype, INT32 level, INT32 *retval, void **input)
{
UINT8 defaultvalue = *(UINT8*)*input;
if (menumeta[menutype].fadestrength >= 0)
{
if (menumeta[menutype].fadestrength % 32)
V_DrawFadeScreen(0xFF00, menumeta[menutype].fadestrength % 32);
return true;
}
else if (!level && (defaultvalue % 32))
V_DrawFadeScreen(0xFF00, defaultvalue % 32);
return false;
}
static boolean MIT_GetHideTitlePics(UINT32 menutype, INT32 level, INT32 *retval, void **input)
{
(void)input;
if (menumeta[menutype].hidetitlepics >= 0)
{
*retval = menumeta[menutype].hidetitlepics;
return true;
}
else if (!level)
*retval = -1;
return false;
}
@ -2309,16 +2346,37 @@ static UINT8 M_GetYoungestChildLevel() // aka the active menu
// EFFECTS
// ====================================
static void M_DrawBackground(char *defaultname)
{
M_IterateMenuTree(MIT_DrawBackground, defaultname);
}
void M_DrawScrollingBackground(char *defaultname)
{
M_IterateMenuTree(MIT_DrawScrollingBackground, defaultname);
}
static void M_ChangeMusic(char *defaultmusname, boolean defaultmuslooping)
{
menumetamusic_t defaultmusic;
if (!defaultmusname)
defaultmusname = "";
strncpy(defaultmusic.musname, defaultmusname, 7);
defaultmusic.musname[6] = 0;
defaultmusic.mustrack = 0;
defaultmusic.muslooping = defaultmuslooping;
M_IterateMenuTree(MIT_ChangeMusic, &defaultmusic);
}
static void M_DrawFadeScreen(UINT8 defaultvalue)
{
M_IterateMenuTree(MIT_FadeScreen, &defaultvalue);
}
boolean M_GetHideTitlePics(void)
{
INT32 retval = M_IterateMenuTree(MIT_GetHideTitlePics, NULL);
return (retval >= 0 ? retval : hidetitlepics);
}
// =========================================================================
// BASIC MENU HANDLING
// =========================================================================
@ -2807,7 +2865,7 @@ void M_Drawer(void)
{
// now that's more readable with a faded background (yeah like Quake...)
if (!WipeInAction)
V_DrawFadeScreen(0xFF00, 16);
M_DrawFadeScreen(16);
if (currentMenu->drawroutine)
currentMenu->drawroutine(); // call current menu Draw routine
@ -3108,6 +3166,103 @@ void M_Init(void)
#endif
}
// ==========================================================================
// 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)
{
menuanimtimer = 0;
}
void MN_Ticker(boolean run)
{
if (run)
menuanimtimer++;
}
//
// M_SkyScroll
//
void M_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname)
{
INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex;
INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley;
boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0);
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT16 patwidth, patheight;
INT32 pw, ph; // scaled by dupz
patch_t *pat;
INT32 i, j;
if (rendermode == render_none)
return;
if (!patchname || !patchname[0])
{
V_DrawFill(0, 0, vid.width, vid.height, 31);
return;
}
if (!scrollxspeed && !scrollyspeed)
{
V_DrawPatchFill(W_CachePatchName(patchname, PU_CACHE));
return;
}
pat = W_CachePatchName(patchname, PU_CACHE);
patwidth = SHORT(pat->width);
patheight = SHORT(pat->height);
pw = patwidth * dupz;
ph = patheight * dupz;
tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center
tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2;
xscrolltimer = ((menuanimtimer*scrollxspeed)/16 + patwidth*xneg) % (patwidth);
yscrolltimer = ((menuanimtimer*scrollyspeed)/16 + patheight*yneg) % (patheight);
// coordinate offsets
xscrolled = xscrolltimer * dupz;
yscrolled = yscrolltimer * dupz;
for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0;
i < tilex;
x += pw, i++)
{
for (y = (yispos) ? -ph*(tiley-1)+ph : 0, j = 0;
j < tiley;
y += ph, j++)
{
V_DrawScaledPatch(
(xispos) ? xscrolled - x : x + xscrolled,
(yispos) ? yscrolled - y : y + yscrolled,
V_NOSCALESTART, pat);
}
}
W_UnlockCachedPatch(pat);
}
// ==========================================================================
// SPECIAL MENU OPTION DRAW ROUTINES GO HERE
// ==========================================================================
@ -4646,7 +4801,10 @@ static void M_DrawLevelPlatterMenu(void)
const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation));
if (gamestate == GS_TIMEATTACK)
M_DrawBackground("SRB2BACK");
{
M_DrawScrollingBackground("SRB2BACK");
M_DrawFadeScreen(0);
}
// finds row at top of the screen
while (y > -8)
@ -4848,7 +5006,7 @@ static void M_DrawMessageMenu(void)
// hack: draw RA background in RA menus
if (gamestate == GS_TIMEATTACK)
M_DrawBackground("SRB2BACK");
M_DrawScrollingBackground("SRB2BACK");
M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines);
@ -7142,12 +7300,8 @@ static void M_SetupChoosePlayer(INT32 choice)
return;
}
if (Playing() == false)
{
S_StopMusic();
S_ChangeMusicInternal("_chsel", true);
}
M_ChangeMusic("_chsel", true);
SP_PlayerDef.prevMenu = currentMenu;
M_SetupNextMenu(&SP_PlayerDef);
@ -7242,7 +7396,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Black BG
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
//M_DrawBackground("SRB2BACK");
//M_DrawScrollingBackground("SRB2BACK");
// Character select profile images!1
M_DrawTextBox(0, my, 16, 20);
@ -7629,10 +7783,13 @@ void M_DrawTimeAttackMenu(void)
INT32 i, x, y, cursory = 0;
UINT16 dispstatus;
patch_t *PictureOfUrFace;
menutype_t menutype = M_GetYoungestChildMenu();
S_ChangeMusicInternal("_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
M_DrawBackground("SRB2BACK");
M_DrawScrollingBackground("SRB2BACK");
M_DrawFadeScreen(0);
M_DrawMenuTitle();
@ -7808,7 +7965,7 @@ static void M_TimeAttack(INT32 choice)
Nextmap_OnChange();
G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusicInternal("_inter", true);
M_ChangeMusic("_inter", true);
itemOn = tastart; // "Start" is selected.
}
@ -7819,9 +7976,11 @@ void M_DrawNightsAttackMenu(void)
INT32 i, x, y, cursory = 0;
UINT16 dispstatus;
S_ChangeMusicInternal("_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
M_DrawBackground("SRB2BACK");
M_DrawScrollingBackground("SRB2BACK");
M_DrawFadeScreen(0);
M_DrawMenuTitle();
@ -7985,7 +8144,7 @@ static void M_NightsAttack(INT32 choice)
Nextmap_OnChange();
G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusicInternal("_inter", true);
M_ChangeMusic("_inter", true);
itemOn = nastart; // "Start" is selected.
}
@ -8219,7 +8378,7 @@ static void M_ModeAttackEndGame(INT32 choice)
itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE;
S_ChangeMusicInternal("_inter", true);
M_ChangeMusic("_inter", true);
Nextmap_OnChange();
}

View File

@ -125,7 +125,7 @@ typedef enum
typedef struct
{
char bgname[8]; // name for background gfx lump; lays over titlemap if this is set
boolean hidetitlepics; // hide title gfx per menu; inherits global setting
SINT8 hidetitlepics; // hide title gfx per menu; -1 means undefined, inherits global setting
INT32 titlescrollxspeed; // background gfx scroll per menu; inherits global setting
INT32 titlescrollyspeed; // y scroll
@ -133,7 +133,7 @@ typedef struct
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 fadescreen; // darken background when displaying this menu
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
INT32 entertag; // line exec to run on menu enter, if titlemap
INT32 exittag; // line exec to run on menu exit, if titlemap
@ -142,6 +142,12 @@ typedef struct
extern menumeta_t menumeta[NUMMENUTYPES];
void M_DrawScrollingBackground(char *defaultname);
void M_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname);
boolean M_GetHideTitlePics(void);
void MN_Ticker(boolean run);
void MN_Start(void);
void MN_InitInfoTables(void);
// Called by main loop,
// saves config file and calls I_Quit when user exits.