Doom: blinking Tower of Babel
JNechaevsky opened this issue · 4 comments
@fabiangreffrath, @rfomin, @bradharding,
Colleagues, I'm seeing things... And issue this happens across all our ports. Have a look at the tower, it's blinking for one frame, right before intermission screen goes to next stage, i.e. to WI_initShowNextLoc()
and drawing "you are here":
bandicam.2024-03-06.23-22-54-759.mp4
Easiest way to see it is to finish E2M7. If I'm getting it right, this is happened because of this line - it re-sets animation elements. And in fact, it shouldn't be called again in WI_initShowNextLoc()
, since all animations are set on initial initializations of single player, deathmatch and coop. So the fix in this case should be as simple as:
+++ wi_stuff.c
@@ -791,15 +791,15 @@
return;
}
state = ShowNextLoc;
acceleratestage = 0;
cnt = SHOWNEXTLOCDELAY * TICRATE;
- WI_initAnimatedBack();
+ // WI_initAnimatedBack();
Nice find Julia! Thanks! I'll be sure to make this change in DR.
My pleasure! But please, do not use my suggested approach - I just woke up with a though, that this way Fortress of Mystery will not be able to appear when entering E2M9, and yes, it didn't happen. 😕
Safest way will be to use some kind in incoming boolean for WI_initShowNextLoc
to see if E2's animations should be reset or not. But most likely it will not fix 100% of issue, since if animation will be reset/reinitialized upon entering only Fortress of Mystery (to make it possible to appear), Tower of Babel's icon will blink, but only when entering E2M9. Totally mind blowing stuff!
I'll investigate it deeply today, pardon me for being too fast on suggestion.
This seems to be working, but I have to check it carefully:
+++ src/doom/wi_stuff.c Thu Mar 7 20:04:22 2024
@@ -511,15 +511,15 @@
// DEBUG
printf("Could not place patch on level %d", n+1);
}
}
-void WI_initAnimatedBack(void)
+void WI_initAnimatedBack(boolean firstcall)
{
int i;
anim_t* a;
if (gamemode == commercial)
return;
@@ -527,14 +527,15 @@
return;
for (i=0;i<NUMANIMS[wbs->epsd];i++)
{
a = &anims[wbs->epsd][i];
// init variables
+ if (firstcall)
a->ctr = -1;
// specify the next time to draw it
if (a->type == ANIM_ALWAYS)
a->nexttic = bcnt + 1 + (M_Random()%a->period);
else if (a->type == ANIM_RANDOM)
a->nexttic = bcnt + 1 + a->data2+(M_Random()%a->data1);
@@ -791,15 +792,15 @@
return;
}
state = ShowNextLoc;
acceleratestage = 0;
cnt = SHOWNEXTLOCDELAY * TICRATE;
- WI_initAnimatedBack();
+ WI_initAnimatedBack(false);
}
void WI_updateShowNextLoc(void)
{
WI_updateAnimatedBack();
if (!--cnt || acceleratestage)
@@ -916,15 +917,15 @@
if (playeringame[j])
dm_frags[i][j] = 0;
dm_totals[i] = 0;
}
}
- WI_initAnimatedBack();
+ WI_initAnimatedBack(true);
}
void WI_updateDeathmatchStats(void)
{
@@ -1135,15 +1136,15 @@
cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0;
dofrags += WI_fragSum(i);
}
dofrags = !!dofrags;
- WI_initAnimatedBack();
+ WI_initAnimatedBack(true);
}
void WI_updateNetgameStats(void)
{
@@ -1361,15 +1362,15 @@
state = StatCount;
acceleratestage = 0;
sp_state = 1;
cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1;
cnt_time = cnt_par = -1;
cnt_pause = TICRATE;
- WI_initAnimatedBack();
+ WI_initAnimatedBack(true);
}
void WI_updateStats(void)
{
WI_updateAnimatedBack();
In other words: when entering intermission screen (WI_initDeathmatchStats
/ WI_initNetgameStats
/ WI_initStats
), do a full init of animations. When entering "next location" intermission screen (WI_initShowNextLoc
) - do not reset animation variables.
And done! This correction should also fix animation reset for other graphics upon switching to "Entering" state, like:
- Blinking lights on episode 1, though it is extremely hard to notice.
- Red sky scrolling on episode 3. This is much easier to see on taking a closer look.
And yes, it is demo-safe, as there is nothing happening with "skipping" states. Hooray! 🥳