Implement scrolling menu backgrounds
This commit is contained in:
parent
32dc47207d
commit
1e6369e8de
|
@ -732,6 +732,8 @@ void D_StartTitle(void)
|
||||||
F_StartTitleScreen();
|
F_StartTitleScreen();
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
|
|
||||||
|
currentMenu = &MainDef; // reset the current menu ID
|
||||||
|
|
||||||
// Reset the palette
|
// Reset the palette
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
V_SetPaletteLump("PLAYPAL");
|
V_SetPaletteLump("PLAYPAL");
|
||||||
|
|
130
src/f_finale.c
130
src/f_finale.c
|
@ -80,7 +80,7 @@ static patch_t *ttspop5;
|
||||||
static patch_t *ttspop6;
|
static patch_t *ttspop6;
|
||||||
static patch_t *ttspop7;
|
static patch_t *ttspop7;
|
||||||
|
|
||||||
static void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname);
|
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PROMPT STATE
|
// PROMPT STATE
|
||||||
|
@ -182,111 +182,58 @@ static void F_NewCutscene(const char *basetext)
|
||||||
cutscene_textcount = TICRATE/2;
|
cutscene_textcount = TICRATE/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// F_DrawPatchCol
|
|
||||||
//
|
|
||||||
static void F_DrawPatchCol(INT32 x, INT32 yoffs, patch_t *patch, INT32 col)
|
|
||||||
{
|
|
||||||
const column_t *column;
|
|
||||||
const UINT8 *source;
|
|
||||||
UINT8 *desttop, *dest = NULL;
|
|
||||||
const UINT8 *deststop, *destbottom;
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
desttop = screens[0] + x*vid.dupx;
|
|
||||||
deststop = screens[0] + vid.rowbytes * vid.height;
|
|
||||||
destbottom = desttop + vid.height*vid.width;
|
|
||||||
|
|
||||||
do {
|
|
||||||
INT32 topdelta, prevdelta = -1;
|
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col]));
|
|
||||||
|
|
||||||
// step through the posts in a column
|
|
||||||
while (column->topdelta != 0xff)
|
|
||||||
{
|
|
||||||
topdelta = column->topdelta;
|
|
||||||
if (topdelta <= prevdelta)
|
|
||||||
topdelta += prevdelta;
|
|
||||||
prevdelta = topdelta;
|
|
||||||
source = (const UINT8 *)column + 3;
|
|
||||||
dest = desttop + topdelta*vid.width;
|
|
||||||
count = column->length;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
{
|
|
||||||
INT32 dupycount = vid.dupy;
|
|
||||||
|
|
||||||
while (dupycount-- && dest < destbottom)
|
|
||||||
{
|
|
||||||
INT32 dupxcount = vid.dupx;
|
|
||||||
while (dupxcount-- && dest <= deststop)
|
|
||||||
*dest++ = *source;
|
|
||||||
|
|
||||||
dest += (vid.width - vid.dupx);
|
|
||||||
}
|
|
||||||
source++;
|
|
||||||
}
|
|
||||||
column = (const column_t *)((const UINT8 *)column + column->length + 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
desttop += SHORT(patch->height)*vid.dupy*vid.width;
|
|
||||||
} while(dest < destbottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// F_SkyScroll
|
// F_SkyScroll
|
||||||
//
|
//
|
||||||
static void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname)
|
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname)
|
||||||
{
|
{
|
||||||
INT32 scrolled, x, mx, fakedwidth;
|
INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex;
|
||||||
INT32 yscrolled, y, my, fakedheight;
|
INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley;
|
||||||
patch_t *pat;
|
boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0);
|
||||||
|
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||||
INT16 patwidth, patheight;
|
INT16 patwidth, patheight;
|
||||||
|
INT32 pw, ph; // scaled by dupz
|
||||||
|
patch_t *pat;
|
||||||
|
INT32 i, j;
|
||||||
|
|
||||||
|
if (rendermode == render_none)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!patchname || !patchname[0])
|
if (!patchname || !patchname[0])
|
||||||
{
|
{
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
V_DrawFill(0, 0, vid.width, vid.height, 31);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pat = W_CachePatchName("TITLESKY", PU_CACHE);
|
pat = W_CachePatchName(patchname, PU_CACHE);
|
||||||
|
|
||||||
patwidth = SHORT(pat->width);
|
patwidth = SHORT(pat->width);
|
||||||
animtimer = ((finalecount*scrollxspeed)/16 + patwidth) % patwidth;
|
|
||||||
|
|
||||||
patheight = SHORT(pat->height);
|
patheight = SHORT(pat->height);
|
||||||
skullAnimCounter = ((finalecount*scrollyspeed)/16 + patheight) % patheight;
|
pw = patwidth * dupz;
|
||||||
|
ph = patheight * dupz;
|
||||||
|
|
||||||
if (rendermode == render_soft && !scrollyspeed)
|
tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center
|
||||||
{ // if only hardware rendering could be this elegant and complete
|
tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2;
|
||||||
// keep the old behavior for non-vertical scrolling because *shrug*
|
|
||||||
fakedwidth = vid.width / vid.dupx;
|
|
||||||
fakedheight = vid.height / vid.dupy;
|
|
||||||
scrolled = (patwidth - animtimer) - 1;
|
|
||||||
yscrolled = (patheight - skullAnimCounter) - 1;
|
|
||||||
for (x = 0, mx = scrolled; x < fakedwidth; x++, mx = (mx+1)%patwidth)
|
|
||||||
{
|
|
||||||
for (y = 0, my = yscrolled; y < fakedheight; y++, my = (my+1)%patheight)
|
|
||||||
F_DrawPatchCol(x, y, pat, mx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rendermode != render_none)
|
|
||||||
{ // if only software rendering could be this simple and retarded
|
|
||||||
// but this does work! because post scrolling goes over my head :upside_down:
|
|
||||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
|
||||||
INT32 pw = patwidth * dupz, ph = patheight * dupz;
|
|
||||||
scrolled = animtimer * dupz;
|
|
||||||
yscrolled = skullAnimCounter * dupz;
|
|
||||||
CONS_Printf("XScroll %d> YScroll %d\n", scrolled, yscrolled);
|
|
||||||
for (x = 0; x < vid.width; x += pw)
|
|
||||||
{
|
|
||||||
for (y = 0; y < vid.height; y += ph)
|
|
||||||
{
|
|
||||||
if (scrolled > 0)
|
|
||||||
V_DrawScaledPatch(scrolled - pw, yscrolled - ph/2, V_NOSCALESTART, pat);
|
|
||||||
|
|
||||||
V_DrawScaledPatch(x + scrolled, yscrolled - ph/2, V_NOSCALESTART, pat);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,8 +1511,7 @@ void F_TitleScreenDrawer(void)
|
||||||
return; // We likely came here from retrying. Don't do a damn thing.
|
return; // We likely came here from retrying. Don't do a damn thing.
|
||||||
|
|
||||||
// Draw that sky!
|
// Draw that sky!
|
||||||
if (!titlemapinaction)
|
M_DrawScrollingBackground("TITLESKY");
|
||||||
F_SkyScroll(titlescrollxspeed, titlescrollyspeed, "TITLESKY");
|
|
||||||
|
|
||||||
// Don't draw outside of the title screewn, or if the patch isn't there.
|
// Don't draw outside of the title screewn, or if the patch isn't there.
|
||||||
if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS))
|
if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS))
|
||||||
|
|
|
@ -40,6 +40,7 @@ void F_TextPromptTicker(void);
|
||||||
void F_GameEndDrawer(void);
|
void F_GameEndDrawer(void);
|
||||||
void F_IntroDrawer(void);
|
void F_IntroDrawer(void);
|
||||||
void F_TitleScreenDrawer(void);
|
void F_TitleScreenDrawer(void);
|
||||||
|
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, char *patchname);
|
||||||
|
|
||||||
void F_GameEvaluationDrawer(void);
|
void F_GameEvaluationDrawer(void);
|
||||||
void F_StartGameEvaluation(void);
|
void F_StartGameEvaluation(void);
|
||||||
|
|
23
src/m_menu.c
23
src/m_menu.c
|
@ -2202,7 +2202,7 @@ menumeta_t menumeta[NUMMENUTYPES];
|
||||||
// return false - continue
|
// return false - continue
|
||||||
typedef boolean (*menutree_iterator)(UINT32, INT32, INT32 *, void **);
|
typedef boolean (*menutree_iterator)(UINT32, INT32, INT32 *, void **);
|
||||||
|
|
||||||
static INT32 M_IterateMenuTree(menutree_iterator itfunc, void **input)
|
static INT32 M_IterateMenuTree(menutree_iterator itfunc, void *input)
|
||||||
{
|
{
|
||||||
INT32 i, retval = 0;
|
INT32 i, retval = 0;
|
||||||
UINT32 bitmask, menutype;
|
UINT32 bitmask, menutype;
|
||||||
|
@ -2218,7 +2218,7 @@ static INT32 M_IterateMenuTree(menutree_iterator itfunc, void **input)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT32 M_IterateMenuTreeFromTop(menutree_iterator itfunc, void **input)
|
static INT32 M_IterateMenuTreeFromTop(menutree_iterator itfunc, void *input)
|
||||||
{
|
{
|
||||||
INT32 i, retval = 0;
|
INT32 i, retval = 0;
|
||||||
UINT32 bitmask, menutype;
|
UINT32 bitmask, menutype;
|
||||||
|
@ -2272,6 +2272,20 @@ static boolean MIT_DrawBackground(UINT32 menutype, INT32 level, INT32 *retval, v
|
||||||
return false;
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!level && defaultname && defaultname[0])
|
||||||
|
F_SkyScroll(titlescrollxspeed, titlescrollyspeed, defaultname);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ====================================
|
// ====================================
|
||||||
// TREE RETRIEVAL
|
// TREE RETRIEVAL
|
||||||
// ====================================
|
// ====================================
|
||||||
|
@ -2300,6 +2314,11 @@ static void M_DrawBackground(char *defaultname)
|
||||||
M_IterateMenuTree(MIT_DrawBackground, defaultname);
|
M_IterateMenuTree(MIT_DrawBackground, defaultname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M_DrawScrollingBackground(char *defaultname)
|
||||||
|
{
|
||||||
|
M_IterateMenuTree(MIT_DrawScrollingBackground, defaultname);
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// BASIC MENU HANDLING
|
// BASIC MENU HANDLING
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
|
@ -141,6 +141,8 @@ typedef struct
|
||||||
|
|
||||||
extern menumeta_t menumeta[NUMMENUTYPES];
|
extern menumeta_t menumeta[NUMMENUTYPES];
|
||||||
|
|
||||||
|
void M_DrawScrollingBackground(char *defaultname);
|
||||||
|
|
||||||
// Called by main loop,
|
// Called by main loop,
|
||||||
// saves config file and calls I_Quit when user exits.
|
// saves config file and calls I_Quit when user exits.
|
||||||
// Even when the menu is not displayed,
|
// Even when the menu is not displayed,
|
||||||
|
|
Loading…
Reference in New Issue