Music Manager: add suspension functionality

Suspending a tune makes it inaudible, but doesn't change
its timing. During suspension, other tunes may come into
priority. After un-suspending, the tune plays from the
point where it would be if it had not been suspended at
all.
This commit is contained in:
James R 2023-12-29 04:23:03 -08:00
parent 7d35c0db4b
commit fed42c4cd6
4 changed files with 45 additions and 3 deletions

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);

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);

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()