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) void Music_PauseAll(void)
{ {
g_tunes.for_each([](Tune& tune) { tune.pause(); }); g_tunes.for_each([](Tune& tune) { tune.pause(); });
@ -301,6 +323,12 @@ boolean Music_Paused(const char* id)
return tune && tune->paused(); 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) tic_t Music_Elapsed(const char* id)
{ {
const Tune* tune = g_tunes.find(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_PauseAll(void);
void Music_UnPauseAll(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. // 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. // Returns true if the tune is paused.
boolean Music_Paused(const char *id); 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 // Returns the number of tics elapsed since the start of the
// tune. // tune.
tic_t Music_Elapsed(const char *id); tic_t Music_Elapsed(const char *id);

View file

@ -49,7 +49,7 @@ void TuneManager::tick()
Tune* tune = current_tune(); Tune* tune = current_tune();
std::string old_song = current_song_; 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; bool changed = current_song_ != old_song;

View file

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