diff --git a/src/d_main.c b/src/d_main.c index 35f1da7b8..ec9677173 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -732,6 +732,8 @@ void D_StartTitle(void) F_StartTitleScreen(); CON_ToggleOff(); + currentMenu = &MainDef; // reset the current menu ID + // Reset the palette if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); diff --git a/src/f_finale.c b/src/f_finale.c index 9c1d50993..6c2695a2c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -80,7 +80,7 @@ static patch_t *ttspop5; static patch_t *ttspop6; 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 @@ -182,111 +182,58 @@ static void F_NewCutscene(const char *basetext) 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 // -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 yscrolled, y, my, fakedheight; - patch_t *pat; + 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, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawFill(0, 0, vid.width, vid.height, 31); return; } - pat = W_CachePatchName("TITLESKY", PU_CACHE); + pat = W_CachePatchName(patchname, PU_CACHE); patwidth = SHORT(pat->width); - animtimer = ((finalecount*scrollxspeed)/16 + patwidth) % patwidth; - patheight = SHORT(pat->height); - skullAnimCounter = ((finalecount*scrollyspeed)/16 + patheight) % patheight; + pw = patwidth * dupz; + ph = patheight * dupz; - if (rendermode == render_soft && !scrollyspeed) - { // if only hardware rendering could be this elegant and complete - // 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); + 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; - 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. // Draw that sky! - if (!titlemapinaction) - F_SkyScroll(titlescrollxspeed, titlescrollyspeed, "TITLESKY"); + M_DrawScrollingBackground("TITLESKY"); // Don't draw outside of the title screewn, or if the patch isn't there. if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)) diff --git a/src/f_finale.h b/src/f_finale.h index d2cc4da07..0b84bd5b0 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -40,6 +40,7 @@ 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); diff --git a/src/m_menu.c b/src/m_menu.c index 661ce04a7..4b113e560 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2202,7 +2202,7 @@ menumeta_t menumeta[NUMMENUTYPES]; // return false - continue 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; UINT32 bitmask, menutype; @@ -2218,7 +2218,7 @@ static INT32 M_IterateMenuTree(menutree_iterator itfunc, void **input) return retval; } -static INT32 M_IterateMenuTreeFromTop(menutree_iterator itfunc, void **input) +static INT32 M_IterateMenuTreeFromTop(menutree_iterator itfunc, void *input) { INT32 i, retval = 0; UINT32 bitmask, menutype; @@ -2272,6 +2272,20 @@ static boolean MIT_DrawBackground(UINT32 menutype, INT32 level, INT32 *retval, v 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 // ==================================== @@ -2300,6 +2314,11 @@ static void M_DrawBackground(char *defaultname) M_IterateMenuTree(MIT_DrawBackground, defaultname); } +void M_DrawScrollingBackground(char *defaultname) +{ + M_IterateMenuTree(MIT_DrawScrollingBackground, defaultname); +} + // ========================================================================= // BASIC MENU HANDLING // ========================================================================= diff --git a/src/m_menu.h b/src/m_menu.h index 078b9bb23..e33642b0d 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -141,6 +141,8 @@ typedef struct extern menumeta_t menumeta[NUMMENUTYPES]; +void M_DrawScrollingBackground(char *defaultname); + // Called by main loop, // saves config file and calls I_Quit when user exits. // Even when the menu is not displayed,