Merge branch 'fix-stereo-fade' into 'master'

Stereo Mode: fix unsequenced track fading at the end

Closes #811

See merge request KartKrew/Kart!1746
This commit is contained in:
Oni 2023-12-29 21:45:59 +00:00
commit fd7c08395f
8 changed files with 122 additions and 42 deletions

View file

@ -7475,6 +7475,8 @@ void M_DrawSoundTest(void)
patch_t *btn = W_CachePatchName("STER_BTN", PU_CACHE);
const char *tune = S_SoundTestTune(0);
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("STER_BG", PU_CACHE), NULL);
x = 24;
@ -7548,7 +7550,7 @@ void M_DrawSoundTest(void)
}
{
UINT32 currenttime = min(Music_Elapsed(soundtest.tune), Music_TotalDuration(soundtest.tune));
UINT32 currenttime = min(Music_Elapsed(tune), Music_TotalDuration(tune));
V_DrawRightAlignedString(x + 272-1, 18+32, 0,
va("%02u:%02u",
@ -7562,7 +7564,7 @@ void M_DrawSoundTest(void)
&& (soundtest.current->basenoloop[soundtest.currenttrack] == true
|| soundtest.autosequence == true))
{
UINT32 exittime = Music_TotalDuration(soundtest.tune);
UINT32 exittime = Music_TotalDuration(tune);
V_DrawRightAlignedString(x + 272-1, 18+32+10, 0,
va("%02u:%02u",
@ -7616,12 +7618,12 @@ void M_DrawSoundTest(void)
// The following are springlocks.
else if (currentMenu->menuitems[i].mvar2 == stereospecial_pause) // pause
{
if (Music_Paused(soundtest.tune) == true)
if (Music_Paused(tune) == true)
y = currentMenu->y + 6;
}
else if (currentMenu->menuitems[i].mvar2 == stereospecial_play) // play
{
if (soundtest.playing == true && Music_Paused(soundtest.tune) == false)
if (soundtest.playing == true && Music_Paused(tune) == false)
y = currentMenu->y + 6;
}
else if (currentMenu->menuitems[i].mvar2 == stereospecial_seq) // seq

View file

@ -37,11 +37,11 @@ static void M_SoundTestMainControl(INT32 choice)
if (currentMenu->menuitems[itemOn].mvar1 == 1) // Play
{
if (Music_Paused(soundtest.tune) == true)
if (Music_Paused(S_SoundTestTune(0)) == true)
{
S_SoundTestTogglePause();
}
else if (Music_Paused(soundtest.tune) == false)
else
{
S_SoundTestPlay();
}
@ -50,7 +50,7 @@ static void M_SoundTestMainControl(INT32 choice)
{
if (currentMenu->menuitems[itemOn].mvar1 == 2) // Pause
{
if (Music_Paused(soundtest.tune) == false)
if (Music_Paused(S_SoundTestTune(0)) == false)
{
S_SoundTestTogglePause();
}
@ -80,6 +80,26 @@ static void M_SoundTestSeq(INT32 choice)
(void)choice;
soundtest.autosequence ^= true;
if (soundtest.playing && S_SoundTestCanSequenceFade())
{
// 1) You cannot cancel a fade once it has started
// 2) However, if the fade wasn't heard, switching
// over just skips to the next song
if (Music_DurationLeft("stereo_fade") <= Music_FadeOutDuration("stereo_fade") * TICRATE / 1000)
{
if (Music_Suspended("stereo_fade"))
{
S_UpdateSoundTestDef((currentMenu->menuitems[itemOn].mvar1 < 0), true, false);
}
}
else
{
soundtest.tune ^= 1;
Music_UnSuspend(S_SoundTestTune(0));
Music_Suspend(S_SoundTestTune(1));
}
}
}
static void M_SoundTestShf(INT32 choice)

View file

@ -261,6 +261,28 @@ void Music_UnPause(const char* id)
}
}
void Music_Suspend(const char* id)
{
Tune* tune = g_tunes.find(id);
if (tune)
{
tune->suspend = true;
g_tunes.tick();
}
}
void Music_UnSuspend(const char* id)
{
Tune* tune = g_tunes.find(id);
if (tune)
{
tune->suspend = false;
g_tunes.tick();
}
}
void Music_PauseAll(void)
{
g_tunes.for_each([](Tune& tune) { tune.pause(); });
@ -301,6 +323,12 @@ boolean Music_Paused(const char* id)
return tune && tune->paused();
}
boolean Music_Suspended(const char* id)
{
const Tune* tune = g_tunes.find(id);
return tune && tune->suspend;
}
tic_t Music_Elapsed(const char* id)
{
const Tune* tune = g_tunes.find(id);
@ -319,6 +347,12 @@ tic_t Music_TotalDuration(const char* id)
return tune ? tune->duration() : 0u;
}
unsigned int Music_FadeOutDuration(const char* id)
{
const Tune* tune = g_tunes.find(id);
return tune ? tune->fade_out : 0;
}
void Music_Loop(const char* id, boolean loop)
{
Tune* tune = g_tunes.find(id);

View file

@ -75,6 +75,13 @@ void Music_UnPause(const char *id);
void Music_PauseAll(void);
void Music_UnPauseAll(void);
// Suspend a tune. The manager will switch to a tune that is
// not suspended. Upon unsuspending, the tune resumes from
// the position it would have reached normally (so the
// duration is not extended like with pausing).
void Music_Suspend(const char *id);
void Music_UnSuspend(const char *id);
//
// Change properties. May be called before calling Music_Play.
@ -117,6 +124,9 @@ boolean Music_Playing(const char *id);
// Returns true if the tune is paused.
boolean Music_Paused(const char *id);
// Returns true if the tune is suspended.
boolean Music_Suspended(const char *id);
// Returns the number of tics elapsed since the start of the
// tune.
tic_t Music_Elapsed(const char *id);
@ -127,6 +137,10 @@ tic_t Music_DurationLeft(const char *id);
// Returns the total duration of the tune, in tics.
tic_t Music_TotalDuration(const char *id);
// Returns the number of milliseconds a tune is configured to
// fade for.
unsigned int Music_FadeOutDuration(const char *id);
// Returns the song name mapped to a tune.
const char *Music_Song(const char *id);

View file

@ -49,7 +49,7 @@ void TuneManager::tick()
Tune* tune = current_tune();
std::string old_song = current_song_;
current_song_ = tune && tune->playing() ? tune->song : std::string{};
current_song_ = tune && tune->playing() && !tune->suspend ? tune->song : std::string{};
bool changed = current_song_ != old_song;

View file

@ -75,6 +75,7 @@ public:
bool needs_seek = false;
bool resume = false;
bool ending = false;
bool suspend = false;
tic_t elapsed() const { return std::max(pause_.value_or(detail::tic_time()), begin_) - begin_; }
tic_t time_remaining() const { return end_ - std::min(pause_.value_or(detail::tic_time()), end_); }
@ -108,14 +109,14 @@ public:
{
// If this song is not playing, it has lowest
// priority.
if (!playing())
if (!playing() || suspend)
{
return true;
}
// If the other song is not playing, we automatically
// have higher priority.
if (!b.playing())
if (!b.playing() || b.suspend)
{
return false;
}
@ -142,6 +143,7 @@ public:
needs_seek = true;
resume = false;
ending = false;
suspend = false;
begin_ = detail::tic_time();
end_ = INFTICS;
@ -162,6 +164,8 @@ public:
can_fade_out = true;
ending = false;
}
suspend = false;
}
void stop()

View file

@ -1227,7 +1227,7 @@ void S_AttemptToRestoreMusic(void)
musicdef_t *musicdefstart = NULL;
struct cursongcredit cursongcredit; // Currently displayed song credit info
struct soundtest soundtest = {.tune = ""}; // Sound Test (sound test)
struct soundtest soundtest; // Sound Test (sound test)
static void S_InsertMusicAtSoundTestSequenceTail(const char *musname, UINT16 map, UINT8 altref, musicdef_t ***tail)
{
@ -1644,10 +1644,28 @@ updatetrackonly:
}
}
const char *S_SoundTestTune(UINT8 invert)
{
return soundtest.tune ^ invert ? "stereo_fade" : "stereo";
}
boolean S_SoundTestCanSequenceFade(void)
{
return
soundtest.current->basenoloop[soundtest.currenttrack] == false &&
// Only fade out if we're the last track for this song.
soundtest.currenttrack == soundtest.current->numtracks-1;
}
static void S_SoundTestReconfigure(const char *tune)
{
Music_Remap(tune, soundtest.current->name[soundtest.currenttrack]);
Music_Play(tune);
}
void S_SoundTestPlay(void)
{
UINT32 sequencemaxtime = 0;
boolean dosequencefadeout = false;
if (soundtest.current == NULL)
{
@ -1656,23 +1674,10 @@ void S_SoundTestPlay(void)
}
soundtest.playing = true;
soundtest.tune = (soundtest.autosequence == true && S_SoundTestCanSequenceFade() == true);
soundtest.tune = "stereo";
if (soundtest.current->basenoloop[soundtest.currenttrack] == false)
{
// Only fade out if we're the last track for this song.
dosequencefadeout = (soundtest.currenttrack == soundtest.current->numtracks-1);
if (dosequencefadeout)
{
soundtest.tune = "stereo_fade";
}
}
Music_Remap(soundtest.tune, soundtest.current->name[soundtest.currenttrack]);
Music_Loop(soundtest.tune, !soundtest.current->basenoloop[soundtest.currenttrack]);
Music_Play(soundtest.tune);
S_SoundTestReconfigure("stereo");
S_SoundTestReconfigure("stereo_fade");
// Assuming this song is now actually playing
sequencemaxtime = I_GetSongLength();
@ -1701,8 +1706,12 @@ void S_SoundTestPlay(void)
}
}
// ms to TICRATE conversion
Music_DelayEnd(soundtest.tune, (TICRATE*sequencemaxtime)/1000);
Music_DelayEnd(
S_SoundTestCanSequenceFade() ? "stereo_fade" : "stereo",
(TICRATE*sequencemaxtime)/1000 // ms to TICRATE conversion
);
Music_Suspend(S_SoundTestTune(1));
}
void S_SoundTestStop(void)
@ -1712,7 +1721,7 @@ void S_SoundTestStop(void)
return;
}
soundtest.tune = "";
soundtest.tune = 0;
soundtest.playing = false;
soundtest.autosequence = false;
@ -1730,13 +1739,14 @@ void S_SoundTestTogglePause(void)
return;
}
if (Music_Paused(soundtest.tune))
const char *tune = S_SoundTestTune(0);
if (Music_Paused(tune))
{
Music_UnPause(soundtest.tune);
Music_UnPause(tune);
}
else
{
Music_Pause(soundtest.tune);
Music_Pause(tune);
}
}
@ -1754,13 +1764,7 @@ void S_TickSoundTest(void)
goto handlenextsong;
}
if (soundtest.autosequence == false)
{
// There's nothing else for us here.
return;
}
if (Music_DurationLeft(soundtest.tune) == 0)
if (Music_DurationLeft(S_SoundTestTune(0)) == 0)
{
goto handlenextsong;
}

View file

@ -186,7 +186,7 @@ extern struct cursongcredit
extern struct soundtest
{
const char *tune; // Tune used for music system
UINT8 tune; // Tune used for music system
boolean playing; // Music is playing?
boolean justopened; // Menu visual assist
@ -208,6 +208,8 @@ void S_SoundTestPlay(void);
void S_SoundTestStop(void);
void S_SoundTestTogglePause(void);
void S_TickSoundTest(void);
const char *S_SoundTestTune(UINT8 invert);
boolean S_SoundTestCanSequenceFade(void);
extern musicdef_t *musicdefstart;