diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 18f0179f80e21629d875cc3221dda27c300a11e6..c2b19add8c29a9c0f38b8b11e949b8d0359d08ca 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2487,7 +2487,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { if (!snake) { - F_MenuPresTicker(true); // title sky + F_MenuPresTicker(); // title sky F_TitleScreenTicker(true); F_TitleScreenDrawer(); } diff --git a/src/f_finale.c b/src/f_finale.c index 929a08eaffe42b8e18d04eda3e384861e8a9796c..f529b4564723ea850d5d97b8a57a3b2c05f07177 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -63,7 +63,6 @@ static tic_t stoptimer; static boolean keypressed = false; // (no longer) De-Demo'd Title Screen -static INT32 menuanimtimer; // Title screen: background animation timing mobj_t *titlemapcameraref = NULL; // menu presentation state @@ -75,6 +74,8 @@ INT32 curbgyspeed; boolean curbghide; boolean hidetitlemap; // WARNING: set to false by M_SetupNextMenu and M_ClearMenus +static fixed_t curbgx = 0; +static fixed_t curbgy = 0; static UINT8 curDemo = 0; static UINT32 demoDelayLeft; static UINT32 demoIdleLeft; @@ -2242,7 +2243,8 @@ void F_GameEndTicker(void) void F_InitMenuPresValues(void) { - menuanimtimer = 0; + curbgx = 0; + curbgy = 0; prevMenuId = 0; activeMenuId = MainDef.menuid; @@ -2275,17 +2277,11 @@ void F_InitMenuPresValues(void) // // F_SkyScroll // -void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) +void F_SkyScroll(const 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 x, basey = 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; - fixed_t fracmenuanimtimer, xscrolltimer, yscrolltimer; if (rendermode == render_none) return; @@ -2296,43 +2292,34 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) return; } - if (!scrollxspeed && !scrollyspeed) + pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY); + + if (!curbgxspeed && !curbgyspeed) { - V_DrawPatchFill(W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY)); + V_DrawPatchFill(pat); + W_UnlockCachedPatch(pat); return; } - pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY); - - patwidth = pat->width; - patheight = pat->height; - pw = patwidth * dupz; - ph = patheight * dupz; + // Modulo the background scrolling to prevent jumps from integer overflows + // We already load the background patch here, so we can modulo it here + // to avoid also having to load the patch in F_MenuPresTicker + curbgx %= pat->width * 16; + curbgy %= pat->height * 16; - 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; + // Ooh, fancy frame interpolation + x = ((curbgx*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgxspeed*dupz)) / 16; + basey = ((curbgy*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgyspeed*dupz)) / 16; - fracmenuanimtimer = (menuanimtimer * FRACUNIT) - (FRACUNIT - rendertimefrac); - xscrolltimer = ((fracmenuanimtimer*scrollxspeed)/16 + patwidth*xneg*FRACUNIT) % (patwidth * FRACUNIT); - yscrolltimer = ((fracmenuanimtimer*scrollyspeed)/16 + patheight*yneg*FRACUNIT) % (patheight * FRACUNIT); + if (x > 0) // Make sure that we don't leave the left or top sides empty + x -= pat->width * dupz; + if (basey > 0) + basey -= pat->height * dupz; - // coordinate offsets - xscrolled = FixedInt(xscrolltimer * dupz); - yscrolled = FixedInt(yscrolltimer * dupz); - - for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0; - i < tilex; - x += pw, i++) + for (; x < vid.width; x += pat->width * dupz) { - 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); - } + for (INT32 y = basey; y < vid.height; y += pat->height * dupz) + V_DrawScaledPatch(x, y, V_NOSCALESTART, pat); } W_UnlockCachedPatch(pat); @@ -2655,7 +2642,7 @@ void F_TitleScreenDrawer(void) if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); // Don't draw outside of the title screen, or if the patch isn't there. if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) @@ -3410,10 +3397,10 @@ luahook: // separate animation timer for backgrounds, since we also count // during GS_TIMEATTACK -void F_MenuPresTicker(boolean run) +void F_MenuPresTicker(void) { - if (run) - menuanimtimer++; + curbgx += curbgxspeed; + curbgy += curbgyspeed; } // (no longer) De-Demo'd Title Screen diff --git a/src/f_finale.h b/src/f_finale.h index 6ea1b5537c46f8ab58ad9fb9c74d2d95c241d169..7f53bfbad59b18814693db553eb7d25815a082bd 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -40,7 +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, const char *patchname); +void F_SkyScroll(const char *patchname); void F_GameEvaluationDrawer(void); void F_StartGameEvaluation(void); @@ -131,7 +131,7 @@ extern UINT16 curtttics; #define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0]) void F_InitMenuPresValues(void); -void F_MenuPresTicker(boolean run); +void F_MenuPresTicker(void); // // WIPE diff --git a/src/g_game.c b/src/g_game.c index aafbdea76bdea9533ad355eab7deb0f225af41e2..b239800447972d1bf9e8931ddf6c5796e397824f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2391,7 +2391,8 @@ void G_Ticker(boolean run) break; case GS_TIMEATTACK: - F_MenuPresTicker(run); + if (run) + F_MenuPresTicker(); break; case GS_INTRO: @@ -2439,7 +2440,8 @@ void G_Ticker(boolean run) // then intentionally fall through /* FALLTHRU */ case GS_WAITINGPLAYERS: - F_MenuPresTicker(run); + if (run) + F_MenuPresTicker(); F_TitleScreenTicker(run); break; diff --git a/src/m_menu.c b/src/m_menu.c index c025ae2867929dc7098f8a9874d8da0ace9e706d..ae089e97ce419b0b75c948255d966ba68779ed6b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5981,7 +5981,7 @@ static void M_DrawLevelPlatterMenu(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) { - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); // Draw and animate foreground if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); @@ -6243,7 +6243,7 @@ static void M_DrawMessageMenu(void) } else { - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); } @@ -9938,7 +9938,7 @@ void M_DrawTimeAttackMenu(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) { - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); // Draw and animate foreground if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground();