TR1X
TR1X copied to clipboard
T1M bug: Atlantis flicker doesn't trigger if there are no sound devices
This is a bit esoteric, but if all sound output devices are disabled in Windows, the lights never turn on at the beginning of Atlantis.
is this because it is waiting for a sound to end that will never end?
Hm FX_Flicker seems fine:
void FX_Flicker(ITEM_INFO *item)
{
if (g_FlipTimer > 125) {
Room_FlipMap();
g_FlipEffect = -1;
} else if (
g_FlipTimer == 90 || g_FlipTimer == 92 || g_FlipTimer == 105
|| g_FlipTimer == 107) {
Room_FlipMap();
}
g_FlipTimer++;
}
I think it's a music trigger that can't fire and thus prevents other triggers from working?
@rr- I think this is because of the effect routines running in sound.c.
https://github.com/rr-/Tomb1Main/blob/4432f86bdb2b6cf1935bc76ba7b78804a06cc46b/src/game/sound.c#L220
before it's checked:
if (!m_SoundIsActive) {
return;
}
The bug affects flip effect routines caused by triggers: https://github.com/rr-/Tomb1Main/blob/7afb2b9db068f074a2ab556a9bd4e1adedcf71d9/src/game/room.c#L906
I also tested Flip Effect 5 (earthquake) in Palace Midas and it does not bounce the camera with sound devices disabled, so this bug is not limited to the Atlantis flicker. I think the flip effects were called in sound.c because a lot of them play sound effects? I'm not sure where we would move this to.
Also I went to test if this happens in TombATI, and the game doesn't even start if sound devices are disabled. So I'd say this is an OG bug.
I'd say we should move this code:
if (g_FlipEffect != -1) {
g_EffectRoutines[g_FlipEffect](NULL);
}
to Effect_Control() and remove it from Sound_UpdateEffects.
Something like this:
diff --git a/src/game/effects.c b/src/game/effects.c
index ff6f4bc4..306cc389 100644
--- a/src/game/effects.c
+++ b/src/game/effects.c
@@ -34,6 +34,11 @@ void Effect_Control(void)
}
fx_num = fx->next_active;
}
+
+ // XXX: Some of the FX routines rely on the item to be not null!
+ if (g_FlipEffect != -1) {
+ g_EffectRoutines[g_FlipEffect](NULL);
+ }
}
int16_t Effect_Create(int16_t room_num)
diff --git a/src/game/sound.c b/src/game/sound.c
index 6f16c30f..0ca557de 100644
--- a/src/game/sound.c
+++ b/src/game/sound.c
@@ -217,12 +217,6 @@ void Sound_UpdateEffects(void)
}
}
- // XXX: Why are we firing this here? Some of the FX routines rely on the
- // item to be not null!
- if (g_FlipEffect != -1) {
- g_EffectRoutines[g_FlipEffect](NULL);
- }
-
for (int i = 0; i < MAX_PLAYING_FX; i++) {
SOUND_SLOT *slot = &m_SFXPlaying[i];
if (!(slot->flags & SOUND_FLAG_USED)) {
We're already calling Effect_Control near Sound_UpdateEffects in game.c, what would be backwards incompatible is that currently inventory.c calls Sound_UpdateEffects but does not call Effects_Control. In my opinion this is good and shouldn't cause problems.
Ok. And call it / check it where?
See my edit
Ok I'll ask around if that will break anything since it moves where the effect routines are called in Game_Control:
Item_Control();
Effect_Control(); // g_EffectRoutines now here
Lara_Control();
Lara_Hair_Control(false);
Camera_Update();
Sound_UpdateEffects(); // g_EffectRoutines used to be here
g_GameInfo.current[g_CurrentLevel].stats.timer++;
Overlay_BarHealthTimerTick();
I discussed this a bit with ChocolateFan. What about separating it into its own function but call it just before the sound code? I think moving it into Effect_Control before Lara_Control could potentially break things for a small benefit since most people are playing with sound devices and don't see this bug. It makes sense to move it since it's not really related to sound code, but we don't want to introduce bugs.
Item_Control();
Effect_Control();
Lara_Control();
Lara_Hair_Control(false);
Camera_Update();
Effect_Routines(); // g_EffectRoutines now here
Sound_UpdateEffects(); // g_EffectRoutines used to be here
g_GameInfo.current[g_CurrentLevel].stats.timer++;
Overlay_BarHealthTimerTick();
Sounds good.