|
From: Markus R. <god...@us...> - 2009-07-29 15:35:42
|
Module: performous
Branch: master
Commit: 6b162bf37606b759910a7be814a470c611005e3f
Author: Markus Raab <un...@ma...>
Date: Sat Jul 25 15:53:57 2009 +0200
Try for Party...
END shows highscore...
---
game/highscore.cc | 15 +++++
game/highscore.hh | 4 +
game/main.cc | 2 +
game/screen_highscore.cc | 139 ++++++++++++++++++++++++++++++++++++++++++++++
game/screen_highscore.hh | 49 ++++++++++++++++
game/screen_songs.cc | 10 +++
6 files changed, 219 insertions(+), 0 deletions(-)
diff --git a/game/highscore.cc b/game/highscore.cc
index 17768f0..e799fd7 100644
--- a/game/highscore.cc
+++ b/game/highscore.cc
@@ -113,6 +113,21 @@ void HighScore::save()
out << "E" << std::endl;
}
+void HighScore::getInfo (std::ostream & out)
+{
+ for (size_t i=0; i<m_scores.size();i++)
+ {
+ if (m_scores[i].score <= 0) break; // maybe change to 500?
+
+ try {
+ out << i+1 << ".\t" << m_scores[i].name
+ << "\t" << m_scores[i].score << std::endl;
+ } catch (std::ofstream::failure const&) {
+ throw HighScoreException("Unexpected I/O error", i);
+ }
+ }
+}
+
void HighScore::addNewHighscore(std::string name, int score)
{
// do not allow invalid name
diff --git a/game/highscore.hh b/game/highscore.hh
index bed7ab8..7f186da 100644
--- a/game/highscore.hh
+++ b/game/highscore.hh
@@ -4,6 +4,8 @@
#include <vector>
#include <stdexcept>
+#include <ostream>
+
/**Exception which will be thrown when loading or
saving a HighScore fails.*/
struct HighScoreException: public std::runtime_error {
@@ -39,6 +41,8 @@ class HighScore {
void load();
void save();
+ void getInfo (std::ostream & os);
+
/**Check if you reached a new highscore.
@param score is a value between 0 and 10000
values below 500 will lead to returning false
diff --git a/game/main.cc b/game/main.cc
index dd7f5be..3a04405 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -7,6 +7,7 @@
#include "screen_practice.hh"
#include "screen_configuration.hh"
#include "screen_players.hh"
+#include "screen_highscore.hh"
#include "video_driver.hh"
#include "xtime.hh"
#include <boost/format.hpp>
@@ -142,6 +143,7 @@ void mainLoop() {
sm.addScreen(new ScreenPractice("Practice", audio, capture));
sm.addScreen(new ScreenConfiguration("Configuration", audio));
sm.addScreen(new ScreenPlayers("Players", audio, players));
+ sm.addScreen(new ScreenHighscore("Highscore", audio, players));
sm.activateScreen("Intro");
// Main loop
boost::xtime time = now();
diff --git a/game/screen_highscore.cc b/game/screen_highscore.cc
new file mode 100644
index 0000000..bc51118
--- /dev/null
+++ b/game/screen_highscore.cc
@@ -0,0 +1,139 @@
+#include "screen_highscore.hh"
+#include "util.hh"
+#include "xtime.hh"
+#include <iostream>
+#include <sstream>
+
+static const double IDLE_TIMEOUT = 45.0; // seconds
+
+ScreenHighscore::ScreenHighscore(std::string const& name, Audio& audio, Players& players):
+ Screen(name), m_audio(audio), m_players(players), m_covers(20)
+{
+ m_players.setAnimMargins(5.0, 5.0);
+ m_playTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
+}
+
+void ScreenHighscore::enter() {
+ m_highscore.reset(new HighScore(m_song->path, "High.sco"));
+ try {
+ m_highscore->load();
+ } catch (HighScoreException const& hi) {
+ std::cerr << "high.sco:" << hi.line() << " " << hi.what() << std::endl;
+ }
+
+ m_score_text[0].reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
+ m_score_text[1].reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
+ m_score_text[2].reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
+ m_score_text[3].reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
+ m_player_icon.reset(new Surface(getThemePath("sing_pbox.svg")));
+ theme.reset(new ThemeSongs());
+ m_emptyCover.reset(new Surface(getThemePath("no_cover.svg"))); // TODO use persons head
+ m_search.text.clear();
+ m_players.setFilter(m_search.text);
+ m_audio.fadeout();
+}
+
+void ScreenHighscore::exit() {
+ m_player_icon.reset();
+ m_score_text[0].reset();
+ m_score_text[1].reset();
+ m_score_text[2].reset();
+ m_score_text[3].reset();
+
+ m_covers.clear();
+ m_emptyCover.reset();
+ theme.reset();
+ m_video.reset();
+ m_songbg.reset();
+ m_playing.clear();
+ m_playReq.clear();
+
+ try {
+ m_highscore->save();
+ } catch (HighScoreException const& hi) {
+ std::cerr << "high.sco:" << hi.line() << " " << hi.what() << std::endl;
+ }
+ m_highscore.reset();
+}
+
+void ScreenHighscore::manageEvent(SDL_Event event) {
+ ScreenManager* sm = ScreenManager::getSingletonPtr();
+ if (event.type != SDL_KEYDOWN) return;
+ SDL_keysym keysym = event.key.keysym;
+ int key = keysym.sym;
+ SDLMod mod = event.key.keysym.mod;
+
+ if (key == SDLK_r && mod & KMOD_CTRL) { m_players.reload(); m_players.setFilter(m_search.text); }
+ if (m_search.process(keysym)) m_players.setFilter(m_search.text);
+ else if (key == SDLK_ESCAPE) {
+ if (m_search.text.empty()) sm->activateScreen("Songs");
+ else { m_search.text.clear(); m_players.setFilter(m_search.text); }
+ }
+ // The rest are only available when there are songs available
+ else if (m_players.empty()) return;
+ else if (key == SDLK_SPACE || (key == SDLK_PAUSE || (key == SDLK_p && mod & KMOD_CTRL))) m_audio.togglePause();
+ else if (key == SDLK_RETURN)
+ {
+ sm->activateScreen("Songs");
+ }
+ else if (key == SDLK_LEFT) m_players.advance(-1);
+ else if (key == SDLK_RIGHT) m_players.advance(1);
+ else if (key == SDLK_PAGEUP) m_players.advance(-10);
+ else if (key == SDLK_PAGEDOWN) m_players.advance(10);
+}
+
+/**Draw the scores in the bottom*/
+void ScreenHighscore::drawScores() {
+ // Score display
+ {
+ unsigned int i = 0;
+ for (std::list<Player>::const_iterator p = m_players.cur.begin(); p != m_players.cur.end(); ++p, ++i) {
+ float act = p->activity();
+ if (act == 0.0f) continue;
+ glColor4f(p->m_color.r, p->m_color.g, p->m_color.b,act);
+ m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075)
+ .screenBottom(-0.025);
+ m_player_icon->draw();
+ m_score_text[i%4]->render((boost::format("%04d") % p->getScore()).str());
+ m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.075)
+ .screenBottom(-0.025);
+ m_score_text[i%4]->draw();
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ }
+ }
+}
+
+void ScreenHighscore::draw() {
+ m_players.update(); // Poll for new players
+ double length = m_audio.getLength();
+ double time = clamp(m_audio.getPosition() - config["audio/video_delay"].f(), 0.0, length);
+ if (m_songbg.get()) m_songbg->draw();
+ if (m_video.get()) m_video->render(time);
+ theme->bg.draw();
+ std::string music, songbg, video;
+ double videoGap = 0.0;
+ std::ostringstream oss_song, oss_order;
+
+ // Format the player information text
+ oss_song << "Highscore for " << m_song->title << "!\n";
+
+ m_highscore->getInfo (oss_order);
+
+ // Draw song and order texts
+ theme->song.draw(oss_song.str());
+ theme->order.draw(oss_order.str());
+
+ // Schedule playback change if the chosen song has changed
+ if (music != m_playReq) { m_playReq = music; m_playTimer.setValue(0.0); }
+ // Play/stop preview playback (if it is the time)
+ if (music != m_playing && m_playTimer.get() > 0.4) {
+ m_songbg.reset(); m_video.reset();
+ if (music.empty()) m_audio.fadeout(); else m_audio.playPreview(music, 30.0);
+ if (!songbg.empty()) try { m_songbg.reset(new Surface(songbg)); } catch (std::exception const&) {}
+ if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, videoGap));
+ m_playing = music;
+ } else if (!m_audio.isPaused() && m_playTimer.get() > IDLE_TIMEOUT) { // Switch if song hasn't changed for IDLE_TIMEOUT seconds
+ if (!m_search.text.empty()) { m_search.text.clear(); m_players.setFilter(m_search.text); }
+ }
+}
+
diff --git a/game/screen_highscore.hh b/game/screen_highscore.hh
new file mode 100644
index 0000000..60f29ca
--- /dev/null
+++ b/game/screen_highscore.hh
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <boost/scoped_ptr.hpp>
+#include "animvalue.hh"
+#include "cachemap.hh"
+#include "opengl_text.hh"
+#include "screen.hh"
+#include "surface.hh"
+#include "textinput.hh"
+#include "theme.hh"
+#include "video.hh"
+#include "players.hh"
+#include "highscore.hh"
+
+class CAudio;
+
+/// song chooser screen
+class ScreenHighscore : public Screen {
+ public:
+ /// constructor
+ ScreenHighscore(std::string const& name, Audio& audio, Players& players);
+ void enter();
+ void exit();
+ void manageEvent(SDL_Event event);
+ void draw();
+ void drawScores();
+
+ void setSong (boost::shared_ptr<Song> song_)
+ {
+ m_song = song_;
+ }
+
+ private:
+ Audio& m_audio;
+ Players& m_players;
+ boost::shared_ptr<Song> m_song; /// Pointer to the current song
+ boost::scoped_ptr<HighScore> m_highscore;
+ boost::scoped_ptr<Surface> m_songbg;
+ boost::scoped_ptr<Video> m_video;
+ boost::scoped_ptr<ThemeSongs> theme;
+ std::string m_playing;
+ std::string m_playReq;
+ AnimValue m_playTimer;
+ TextInput m_search;
+ boost::scoped_ptr<Surface> m_emptyCover;
+ Cachemap<std::string, Surface> m_covers;
+ boost::scoped_ptr<Surface> m_player_icon;
+ boost::scoped_ptr<SvgTxtThemeSimple> m_score_text[4];
+};
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index 63917bc..c60b357 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -1,5 +1,6 @@
#include "screen_songs.hh"
#include "screen_sing.hh"
+#include "screen_highscore.hh"
#include "configuration.hh"
#include "util.hh"
#include "xtime.hh"
@@ -50,6 +51,15 @@ void ScreenSongs::manageSharedKey(int key, SDLMod mod)
}
else if (key == SDLK_LEFT) m_songs.advance(-1);
else if (key == SDLK_RIGHT) m_songs.advance(1);
+ else if (key == SDLK_END)
+ {
+ ScreenManager* sm = ScreenManager::getSingletonPtr();
+ Screen* s = sm->getScreen("Highscore");
+ ScreenHighscore* ss = dynamic_cast<ScreenHighscore*> (s);
+ assert(ss);
+ ss->setSong(m_songs.currentPtr());
+ sm->activateScreen("Highscore");
+ }
}
void ScreenSongs::manageEvent(SDL_Event event) {
|