|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:22
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Feb 11 08:37:27 2012 +0200
Major cleanup of screen songs with some bugfixes.
- Update logic separated from drawing functions
- Browser would hang due to auto-advance when all the songs displayed had the same music files
- Only update songlist when idle (allows for smooth browsing during song loading)
- Various other small things and almost certainly new bugs...
---
game/screen_songs.cc | 76 +++++++++++++++++++++++++------------------------
game/screen_songs.hh | 16 ++--------
game/song.hh | 3 +-
3 files changed, 44 insertions(+), 51 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index bf8fa63..7dc98e8 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -17,7 +17,7 @@ ScreenSongs::ScreenSongs(std::string const& name, Audio& audio, Songs& songs, Da
Screen(name), m_audio(audio), m_songs(songs), m_database(database), m_covers(20), m_jukebox(), show_hiscores(), hiscore_start_pos()
{
m_songs.setAnimMargins(5.0, 5.0);
- m_playTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
+ m_idleTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
}
void ScreenSongs::enter() {
@@ -53,7 +53,6 @@ void ScreenSongs::exit() {
m_songbg_default.reset();
m_songbg_ground.reset();
m_playing.clear();
- m_playReq.clear();
}
/**Add actions here which should effect both the
@@ -77,6 +76,7 @@ void ScreenSongs::manageEvent(SDL_Event event) {
input::NavButton nav(input::getNav(event));
// Handle basic navigational input that is possible also with instruments
if (nav != input::NONE) {
+ m_idleTimer.setValue(0.0); // Reset idle timer
if (m_jukebox) {
if (nav == input::CANCEL || m_songs.empty()) m_jukebox = false;
else if (nav == input::UP) m_audio.seek(5);
@@ -128,6 +128,42 @@ void ScreenSongs::manageEvent(SDL_Event event) {
sm->showLogo(!m_jukebox);
}
+void ScreenSongs::update() {
+ if (m_idleTimer.get() < 0.3) return; // Only update when the user gives us a break
+ m_songs.update(); // Poll for new songs
+ bool songChange = false; // Do we need to switch songs?
+ // Automatic song browsing
+ if (!m_audio.isPaused() && m_idleTimer.get() > 1.0) {
+ // If playback has ended or hasn't started
+ if (!m_audio.isPlaying() || m_audio.getPosition() > m_audio.getLength()) {
+ songChange = true; // Force reload even if the music happens to stay the same
+ }
+ // If the above, or if in regular mode and idle too long, advance to next song
+ if (songChange || (!m_jukebox && m_idleTimer.get() > IDLE_TIMEOUT)) {
+ m_songs.advance(1);
+ m_idleTimer.setValue(0.0);
+ }
+ }
+ // Check out if the music has changed
+ boost::shared_ptr<Song> song = m_songs.currentPtr();
+ Song::Music music;
+ if (song) music = song->music;
+ if (m_playing != music) songChange = true;
+ // Switch songs if needed, only when the user is not browsing for a moment
+ if (!songChange) return;
+ m_playing = music;
+ // Clear the old content and load new content if available
+ m_songbg.reset(); m_video.reset();
+ double pstart = (!m_jukebox && song ? song->preview_start : 0.0);
+ m_audio.playMusic(music, true, 2.0, pstart);
+ if (song) {
+ std::string background = song->path + song->background;
+ std::string video = song->path + song->video;
+ if (!background.empty()) try { m_songbg.reset(new Surface(background)); } catch (std::exception const&) {}
+ if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, song->videoGap));
+ }
+}
+
void ScreenSongs::drawJukebox() {
double pos = m_audio.getPosition();
double len = m_audio.getLength();
@@ -166,27 +202,6 @@ void ScreenSongs::drawMultimedia() {
}
}
-void ScreenSongs::updateMultimedia(Song& song, ScreenSharedInfo& info) {
- if (!song.music.empty()) info.music = song.music; // TODO it is always empty?
- if (!song.background.empty()) info.songbg = song.path + song.background;
- if (!song.video.empty()) { info.video = song.path + song.video; info.videoGap = song.videoGap; }
-}
-
-void ScreenSongs::stopMultimedia(ScreenSharedInfo& info) {
- // Schedule playback change if the chosen song has changed
- if (info.music != m_playReq) { m_playReq = info.music; m_playTimer.setValue(0.0); }
- // Play/stop preview playback (if it is the time)
- if (info.music != m_playing && m_playTimer.get() > 0.3) {
- m_songbg.reset(); m_video.reset();
- double pstart = 0.0; // Playback starting time
- if (!m_songs.empty() && !m_jukebox) pstart = m_songs.current().preview_start; // In regular mode
- if (info.music.empty()) m_audio.fadeout(1.0); else m_audio.playMusic(info.music, true, 2.0, pstart);
- if (!info.songbg.empty()) try { m_songbg.reset(new Surface(info.songbg)); } catch (std::exception const&) {}
- if (!info.video.empty() && config["graphic/video"].b()) m_video.reset(new Video(info.video, info.videoGap));
- m_playing = info.music;
- }
-}
-
namespace {
float getIconTex(int i) {
static int iconcount = 8;
@@ -195,10 +210,7 @@ namespace {
}
void ScreenSongs::draw() {
- m_songs.update(); // Poll for new songs
- ScreenSharedInfo info;
- info.videoGap = 0.0;
-
+ update();
drawMultimedia();
std::ostringstream oss_song, oss_order, oss_has_hiscore;
// Test if there are no songs
@@ -226,7 +238,6 @@ void ScreenSongs::draw() {
// Get hiscores from database
m_database.queryPerSongHiscore_HiscoreDisplay(oss_order, m_songs.currentPtr(), hiscore_start_pos, 5);
}
- updateMultimedia(song, info);
}
if (m_jukebox) drawJukebox();
else {
@@ -238,15 +249,6 @@ void ScreenSongs::draw() {
} else theme->hiscores.draw(oss_order.str());
if (!show_hiscores) drawInstruments(Dimensions(m_instrumentList->ar()).fixedHeight(0.03).center(-0.04));
}
- stopMultimedia(info);
- if (m_jukebox) {
- // Switch if at song end
- if (!m_audio.isPlaying() || m_audio.getPosition() + 1.3 > m_audio.getLength()) {
- m_songs.advance(1);
- // Force reload of data
- m_playing.clear();
- }
- } else if (!m_audio.isPaused() && m_playTimer.get() > IDLE_TIMEOUT) m_songs.advance(1); // Switch if song hasn't changed for IDLE_TIMEOUT seconds
}
void ScreenSongs::drawCovers() {
diff --git a/game/screen_songs.hh b/game/screen_songs.hh
index 4fd16ff..a04d18e 100644
--- a/game/screen_songs.hh
+++ b/game/screen_songs.hh
@@ -15,14 +15,6 @@ class Song;
class Audio;
class Songs;
-struct ScreenSharedInfo
-{
- std::map<std::string,std::string> music;
- std::string songbg;
- std::string video;
- double videoGap;
-};
-
/// song chooser screen
class ScreenSongs : public Screen {
public:
@@ -41,8 +33,7 @@ public:
protected:
void drawInstruments(Dimensions const& dim, float alpha = 1.0f) const;
void drawMultimedia();
- void updateMultimedia(Song& song, ScreenSharedInfo& info);
- void stopMultimedia(ScreenSharedInfo& info);
+ void update();
Audio& m_audio;
Songs& m_songs;
@@ -50,9 +41,8 @@ protected:
boost::scoped_ptr<Surface> m_songbg, m_songbg_ground, m_songbg_default;
boost::scoped_ptr<Video> m_video;
boost::scoped_ptr<ThemeSongs> theme;
- std::map<std::string,std::string> m_playing;
- std::map<std::string,std::string> m_playReq;
- AnimValue m_playTimer;
+ Song::Music m_playing;
+ AnimValue m_idleTimer;
TextInput m_search;
boost::scoped_ptr<Surface> m_singCover;
boost::scoped_ptr<Surface> m_instrumentCover;
diff --git a/game/song.hh b/game/song.hh
index 726c0ca..a2b1b73 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -104,7 +104,8 @@ class Song: boost::noncopyable {
std::string text; ///< songtext
std::string creator; ///< creator
std::string language; ///< language
- std::map<std::string,std::string> music; ///< music files (background, guitar, rhythm/bass, drums, vocals)
+ typedef std::map<std::string,std::string> Music;
+ Music music; ///< music files (background, guitar, rhythm/bass, drums, vocals)
std::string cover; ///< cd cover
std::string background; ///< background image
std::string video; ///< video
|