diff --git a/asteroids/AsteroidsEnums.h b/asteroids/AsteroidsEnums.h index 0481f09..e8ccf50 100644 --- a/asteroids/AsteroidsEnums.h +++ b/asteroids/AsteroidsEnums.h @@ -31,6 +31,7 @@ BEGIN_ENUM(ViewState) DECL_ENUM_ELEMENT(ViewStateEnterPlayername), DECL_ENUM_ELEMENT(ViewStateEditor), DECL_ENUM_ELEMENT(ViewStateOptions), + DECL_ENUM_ELEMENT(ViewStateCredits), DECL_ENUM_ELEMENT(ViewStateGameOver), DECL_ENUM_LAST(ViewState) } diff --git a/asteroids/View.cc b/asteroids/View.cc index e5e11a7..ef355ae 100644 --- a/asteroids/View.cc +++ b/asteroids/View.cc @@ -83,6 +83,8 @@ int View::OnInit (int argc, char* argv[]) { PushViewState (ViewStateMainMenu); + mCreditsPageIndex = 0; + return 0; } @@ -446,6 +448,9 @@ void View::DrawUi () { case ViewStateEditor: DrawUiEditor(); break; + case ViewStateCredits: + DrawUiCredits(); + break; default: Engine::LogWarning ("Trying to draw unknown ViewState: %s (%d)", GetStringViewState (game_state), game_state); @@ -494,6 +499,11 @@ void View::DrawUiMainMenu() { PushViewState(ViewStateShowHighscore); } + if (Engine::GUI::Button (4, "Credits", screen_right * 0.5 - 100, 350, button_width, button_height)) { + mCreditsPageIndex = 0; + PushViewState(ViewStateCredits); + } + /* if (Engine::GUI::Button (6, "E", screen_right - 48, 20, 32, button_height)) { PushViewState(ViewStateEditor); @@ -501,7 +511,7 @@ void View::DrawUiMainMenu() { } */ - if (Engine::GUI::Button (4, "Quit", screen_right * 0.5 - 100, 380, button_width, button_height)) { + if (Engine::GUI::Button (5, "Quit", screen_right * 0.5 - 100, 430, button_width, button_height)) { Engine::RunCommand("quit"); } } @@ -747,6 +757,115 @@ void View::DrawUiOptions() { } } +void View::DrawUiCredits() { +// DrawPageTitle ("Credits"); + SelectFont ("console.ttf size=23"); + + static std::string credits_content ( +"_Programming,\r\ +_ Design, and Graphics\r\ + Martin Felis\r\ +\r\ +_Level Design\r\ + Martin Felis\r\ +\r\ +_Music\r\ + DJad - Space Exploration\r\ +\r\ +_Sounds\r\ + Marcus Zetterquist\r\ +\r\ +_Libraries\r\ + libSDL\r\ + SDL_mixer\r\ + OGLFT\r\ + freetype2\r\ + boost\r\ + libpng\r\ +\r\ +_Tools\r\ + GIMP\r\ + Blender\r\ + CMake\r\ +\r\ +_Special Thanks\r\ + to my wonderful wife Katrina\r\ +\r\ + \r\ + \r\ + \r\ + \r\ + \r\ +_http://www.fysx.org\r\ + \r\ + \r\ + \r\ + \r\ + \r\ + \r\ + \r\ +:created with vim.\r\ +::wq\r\ +\r\ +EOF\r\ +"); + static float page_duration = 4.; + static float page_draw_duration = page_duration; + + if (page_draw_duration < 0.) { + mCreditsPageIndex ++; + page_draw_duration = page_duration; + } + + stringstream credits_stream (credits_content); + std::string line; + + float xpos = 270, ypos = 200.f; + float dy = 20.f; + + unsigned int index = 0; + bool first_content_line = false; + while (getline (credits_stream, line, '\r')) { + if (line.size() == 0) { + index ++; + continue; + } + + if (index == mCreditsPageIndex) { + if (line[0] == '_') { + SelectFont ("console.ttf size=23 color=#e8d500"); + line = line.substr (1, line.size()); + first_content_line = true; + } else if (line[0] == ':') { + SelectFont ("console.ttf size=23 color=#ffffff"); + line = line.substr (1, line.size()); + } else { + if (first_content_line) { + ypos += 20; + first_content_line = false; + } + SelectFont ("console.ttf size=23 color=#ffffff"); + } + + DrawGLString (xpos, ypos, line.c_str()); + ypos += dy; + } else { + continue; + } + + if (index == mCreditsPageIndex && line == std::string("EOF")) { + PopViewState(); + } + } + + page_draw_duration -= Engine::GetFrameDuration(); + + if (Engine::GUI::CheckKeyPressed(SDLK_ESCAPE) + || Engine::GUI::CheckKeyPressed(SDLK_SPACE) ) { + PopViewState(); + } +} + void View::DrawUiEnterPlayername() { DrawPageTitle ("Asteroids"); SelectFont ("console.ttf size=23"); diff --git a/asteroids/View.h b/asteroids/View.h index 58f9cfd..5cc41fa 100644 --- a/asteroids/View.h +++ b/asteroids/View.h @@ -56,7 +56,8 @@ class View : public Engine::ViewBase { if (mViewStateStack.size() > 0) current_name = GetStringViewState(mViewStateStack.top()); - Engine::LogDebug("Popped ViewState: %s current %s remaining: %u", popped_name.c_str(), current_name.c_str(), mViewStateStack.size()); + Engine::LogDebug("Popped ViewState: %s current %s remaining: %u", + popped_name.c_str(), current_name.c_str(), mViewStateStack.size()); if (mViewStateStack.size() == 0) { Engine::LogDebug ("No ViewState on the stack! Quitting."); @@ -88,10 +89,12 @@ class View : public Engine::ViewBase { void DrawUiLevelComplete(); void DrawUiGamePaused(); void DrawUiPlayerDied(); - void DrawHighscoreEntry(float x, float y, float entry_width, const std::string &name, unsigned int points); + void DrawHighscoreEntry(float x, float y, float entry_width, + const std::string &name, unsigned int points); void DrawUiHighscore(); void DrawUiOptions(); void DrawUiEnterPlayername(); + void DrawUiCredits(); void DrawUiEditor(); @@ -154,6 +157,8 @@ class View : public Engine::ViewBase { EditorState mEditorState; unsigned int mEditorEntityId; + unsigned int mCreditsPageIndex; + /// \brief can be used to perform some fading, etc. float mFadeTimerSecValue; diff --git a/engine/IMGUIControls.cc b/engine/IMGUIControls.cc index 32b5396..c552c0d 100644 --- a/engine/IMGUIControls.cc +++ b/engine/IMGUIControls.cc @@ -530,7 +530,6 @@ bool LineEdit (int id, int x, int y, std::string &text_value, const int &maxleng } } break; - } } @@ -652,8 +651,10 @@ bool CheckKeyPress (int keycode) { } bool CheckKeyPressed (int keycode) { - if (controller->uistate.keypressed_set.find(keycode) != controller->uistate.keypressed_set.end()) + if (controller->uistate.keypressed_set.find(keycode) != controller->uistate.keypressed_set.end()) { + controller->uistate.keypressed_set.erase(keycode); return true; + } return false; } diff --git a/engine/ModelBase.cc b/engine/ModelBase.cc index 9516697..8ad40f2 100644 --- a/engine/ModelBase.cc +++ b/engine/ModelBase.cc @@ -293,12 +293,21 @@ void SetPlayerEntityId(unsigned int entity_id) { float GetFrameDuration () { if (!ModelInstance) { - LogError ("Couldn't create Entity: Model not initialized!"); + LogError ("Couldn't get frame duration: Model not initialized!"); } return ModelInstance->GetFrameDuration (); } +float GetDurationApplicationStart () { + if (!ModelInstance) { + LogError ("Couldn't get application runtime: Model not initialized!"); + } + + return ModelInstance->GetDurationApplicationStart (); +} + + EntityBase * CreateEntity (int type) { if (!ModelInstance) { LogError ("Couldn't create Entity: Model not initialized!"); diff --git a/engine/ModelBase.h b/engine/ModelBase.h index 4e3a864..1735988 100644 --- a/engine/ModelBase.h +++ b/engine/ModelBase.h @@ -3,7 +3,6 @@ #include "Engine.h" #include "EntityBase.h" -// #include "Timer.h" namespace Engine { @@ -13,10 +12,6 @@ class Events; class EntityFactoryBase; class OverlayManager; -#ifdef max -#undef max -#endif - const unsigned int NullEntityId = std::numeric_limits::max() - 1; struct EntityBase; @@ -44,12 +39,16 @@ class ModelBase : public Module { void UpdateTimer () { static float last_frame = 0; float current_frame = static_cast (SDL_GetTicks ()) * 1.0e-3; + mDurationApplicationStart = current_frame; mDeltaSec = current_frame - last_frame; last_frame = current_frame; } float GetFrameDuration () { return mDeltaSec; } + float GetDurationApplicationStart () { + return mDurationApplicationStart; + } /** Adds the given Entity to the Model */ void RegisterEntity (EntityBase *entity); @@ -86,7 +85,8 @@ class ModelBase : public Module { /** Returns the id of the entity the player is currently controlling */ unsigned int GetPlayerEntityId (); - /** \brief Assigns the player to an Entity. All controls will be redirected to that player + /** \brief Assigns the player to an Entity. All controls will be redirected + * \brief to that player * * This can be used to disable the controls of of the player by assinging * the special entity id of NullEntityId */ @@ -94,7 +94,8 @@ class ModelBase : public Module { /** Notifies the gamelogic of a collision event */ void SendEntityCollisionEvent (const unsigned int reference_entity_id, - const unsigned int incidence_entity_id, float collision_time, vector3d point, vector3d normal); + const unsigned int incidence_entity_id, float collision_time, + vector3d point, vector3d normal); virtual void SetGameState (const unsigned int &state) { mLastGameState = mGameState; @@ -164,6 +165,7 @@ class ModelBase : public Module { unsigned int mLastGameState; float mDeltaSec; + float mDurationApplicationStart; friend class ViewBase; friend class OverlayManager; diff --git a/engine/ModelBaseGlobal.h b/engine/ModelBaseGlobal.h index af0e6e6..a5842d8 100644 --- a/engine/ModelBaseGlobal.h +++ b/engine/ModelBaseGlobal.h @@ -19,6 +19,12 @@ void SetPlayerEntityId(unsigned int entity_id); /** \brief Returns the duration of the frame in seconds */ float GetFrameDuration (); +/** \brief Returns the number of seconds the application is running + * + * \todo [low] rename GetTimeApplicationStart to a proper name! + */ +float GetDurationApplicationStart (); + // /** \brief Starts a timer with the given id that expires after sec seconds */ // void StartTimer(const std::string &id, float sec); // diff --git a/engine/ViewBase.cc b/engine/ViewBase.cc index fc69333..01b5514 100644 --- a/engine/ViewBase.cc +++ b/engine/ViewBase.cc @@ -316,7 +316,8 @@ bool ViewBase::LoadFont (const std::string &font_spec_string) { return false; } - font->setForegroundColor(font_color[0], font_color[1], font_color[2]); + font->setForegroundColor(font_color[0], font_color[1], font_color[2], 1.); + font->setBackgroundColor(0., 0., 0., 0.); mFonts.insert(std::make_pair(font_spec_string, font));