From fed42c4cd6afa598650ee9e4be1b7f0d42aeaec4 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 29 Dec 2023 04:23:03 -0800 Subject: [PATCH] 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. --- src/music.cpp | 28 ++++++++++++++++++++++++++++ src/music.h | 10 ++++++++++ src/music_manager.cpp | 2 +- src/music_tune.hpp | 8 ++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/music.cpp b/src/music.cpp index 304948964..ea6e772f0 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -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); diff --git a/src/music.h b/src/music.h index 5b53b4ba1..9d3b5200e 100644 --- a/src/music.h +++ b/src/music.h @@ -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); diff --git a/src/music_manager.cpp b/src/music_manager.cpp index 05d02d855..a0696e1a3 100644 --- a/src/music_manager.cpp +++ b/src/music_manager.cpp @@ -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; diff --git a/src/music_tune.hpp b/src/music_tune.hpp index ec9aac6dd..b7c800058 100644 --- a/src/music_tune.hpp +++ b/src/music_tune.hpp @@ -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()