From 44200f8b741aa7fc53ec5cac136543b7c9a404ba Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Sun, 24 May 2009 14:53:00 +0200 Subject: [PATCH] Add support for displaying level names and authors Display the level's name and author if available at the beginning of the level. --- Font.cpp | 15 +++++++++------ Font.h | 1 + Game.cpp | 29 +++++++++++++++++++++++++++++ Overlay.cpp | 17 +++++++++++++++++ Overlay.h | 2 ++ Scene.cpp | 24 ++++++++++++++++++++++-- Scene.h | 7 +++++++ 7 files changed, 87 insertions(+), 8 deletions(-) diff --git a/Font.cpp b/Font.cpp index f71c949..1b4a386 100644 --- a/Font.cpp +++ b/Font.cpp @@ -43,16 +43,19 @@ Vec2 Font::metrics( const std::string& text ) const return m; } +Canvas* Font::renderFont(const std::string& text, int colour) const +{ + return new FontCanvas( TTF_RenderText_Blended( FONT(this), + text.c_str(), + SDL_Color() ) ); +} void Font::drawLeft( Canvas* canvas, Vec2 pt, const std::string& text, int colour ) const { - SDL_Surface *surf; - SDL_Color bg = { 0xff,0xff,0xff }; - FontCanvas temp( TTF_RenderText_Blended( FONT(this), - text.c_str(), - SDL_Color() ) ); - canvas->drawImage( &temp, pt.x, pt.y ); + Canvas* temp = renderFont(text, colour); + canvas->drawImage(temp, pt.x, pt.y); + delete temp; } void Font::drawCenter( Canvas* canvas, Vec2 pt, diff --git a/Font.h b/Font.h index 50d8872..ea0e6fb 100644 --- a/Font.h +++ b/Font.h @@ -29,6 +29,7 @@ class Font public: Font( const std::string& file, int ptsize=10 ); Vec2 metrics( const std::string& text ) const; + Canvas* renderFont(const std::string& text, int colour) const; void drawLeft( Canvas* canvas, Vec2 pt, const std::string& text, int colour ) const; void drawCenter( Canvas* canvas, Vec2 pt, diff --git a/Game.cpp b/Game.cpp index 904bcc4..1966644 100644 --- a/Game.cpp +++ b/Game.cpp @@ -297,6 +297,8 @@ class Game : public GameControl, public Widget Overlay *m_pauseOverlay; Overlay *m_editOverlay; Overlay *m_completedOverlay; + Overlay *m_levelnameOverlay; + int m_levelnameHideTime; // DemoOverlay m_demoOverlay; DemoRecorder m_recorder; DemoPlayer m_player; @@ -311,6 +313,8 @@ public: m_pauseOverlay( NULL ), m_editOverlay( NULL ), m_completedOverlay( NULL ), + m_levelnameOverlay( NULL ), + m_levelnameHideTime( 0 ), m_isCompleted(false), m_cselector( *this ), m_os( Os::get() ), @@ -358,6 +362,22 @@ public: } m_level = level; m_stats.reset(); + if (m_levelnameOverlay && m_levelnameHideTime) { + hideOverlay(m_levelnameOverlay); + delete m_levelnameOverlay; + m_levelnameHideTime = 0; + } + + std::string title = m_scene.getTitle(), author = m_scene.getAuthor(); + + /* Only show title if we have at least one of (title, author) specified */ + if (!title.empty() || !author.empty()) { + m_levelnameOverlay = createTextOverlay( *this, + ((title.empty())?(std::string("Untitled")):(title)) + + std::string(" by ") + + ((author.empty())?(std::string("Anonymous")):(author))); + m_levelnameHideTime = -1; /* in onTick, -1 means "show the overlay" */ + } } } } @@ -849,6 +869,15 @@ public: m_player.tick(); } + if (m_levelnameHideTime == -1 && m_levelnameOverlay) { + showOverlay(m_levelnameOverlay); + m_levelnameHideTime = tick + 4000; + } else if (m_levelnameHideTime != 0 && + m_levelnameHideTime m_hotSpots; }; +class TextOverlay: public OverlayBase +{ + private: + const std::string& m_text; + public: + TextOverlay(GameControl& game, const std::string& text, + int x=10, int y=10, bool dragging_allowed=false) + : OverlayBase(game, x, y, dragging_allowed) + , m_text(text) + { + m_canvas = Font::headingFont()->renderFont(m_text, 1); + } +}; class IconOverlay: public OverlayBase { @@ -649,6 +662,10 @@ public: +Overlay* createTextOverlay( GameControl& game, const std::string& text ) +{ + return new TextOverlay(game, text); +} Overlay* createIconOverlay( GameControl& game, const char* file, int x,int y, diff --git a/Overlay.h b/Overlay.h index df58d2c..3da685e 100644 --- a/Overlay.h +++ b/Overlay.h @@ -39,6 +39,8 @@ public: virtual void onSelection( int i, int ix, int iy ) { onSelection(i); }; }; +extern Overlay* createTextOverlay( GameControl& game, const std::string& text ); + extern Overlay* createIconOverlay( GameControl& game, const char* file, int x=100,int y=20, bool dragging_allowed=true); diff --git a/Scene.cpp b/Scene.cpp index 5a826c9..a1add37 100644 --- a/Scene.cpp +++ b/Scene.cpp @@ -806,13 +806,33 @@ bool Scene::load( std::istream& in ) return true; } +void Scene::trimWhitespace( std::string& s ) +{ + static const char* whitespace = " \t"; + size_t start = s.find_first_not_of(whitespace); + size_t end = s.find_last_not_of(whitespace); + + if (std::string::npos == start || std::string::npos == end) { + s = ""; + } else { + s = s.substr(start, end-start+1); + } +} + bool Scene::parseLine( const std::string& line ) { try { switch( line[0] ) { - case 'T': m_title = line.substr(line.find(':')+1); return true; + case 'T': m_title = line.substr(line.find(':')+1); + trimWhitespace(m_title); return true; case 'B': m_bg = line.substr(line.find(':')+1); return true; - case 'A': m_author = line.substr(line.find(':')+1); return true; + case 'A': m_author = line.substr(line.find(':')+1); + trimWhitespace(m_author); + /* The original levels have their author set + * to "test". Remove the author in that case. */ + if (m_author.compare("test") == 0) { + m_author = ""; + } return true; case 'S': { Stroke *s = new Stroke(line); m_strokes.append(s); diff --git a/Scene.h b/Scene.h index 974797e..6a66e8f 100644 --- a/Scene.h +++ b/Scene.h @@ -79,10 +79,17 @@ public: bool load( std::istream& in ); void protect( int n=-1 ); bool save( const std::string& file ); + const char* getTitle() { + return m_title.c_str(); + } + const char* getAuthor() { + return m_author.c_str(); + } private: void createJoints( Stroke *s ); + void trimWhitespace( std::string& s ); bool parseLine( const std::string& line ); // b2ContactListener callback when a new contact is detected -- 2.11.4.GIT