diff --git a/Bin/VC10/VC10.vcxproj b/Bin/VC10/VC10.vcxproj
index 3336f69..6107e44 100644
--- a/Bin/VC10/VC10.vcxproj
+++ b/Bin/VC10/VC10.vcxproj
@@ -100,6 +100,7 @@
+
@@ -128,6 +129,8 @@
+
+
@@ -145,6 +148,7 @@
+
@@ -167,6 +171,8 @@
+
+
diff --git a/Bin/VC10/VC10.vcxproj.filters b/Bin/VC10/VC10.vcxproj.filters
index 52683a1..8424bb1 100644
--- a/Bin/VC10/VC10.vcxproj.filters
+++ b/Bin/VC10/VC10.vcxproj.filters
@@ -46,6 +46,9 @@
{2826112d-5f07-4ee2-b4b4-2be9289c6811}
+
+ {da9ad984-368f-4f6f-8f68-648733ae3a44}
+
@@ -183,6 +186,15 @@
Animation
+
+ UI
+
+
+ Main
+
+
+ UI
+
@@ -296,5 +308,14 @@
Animation
+
+ UI
+
+
+ Main
+
+
+ UI
+
\ No newline at end of file
diff --git a/src/Font/Font.cpp b/src/Font/Font.cpp
index f06b2f6..247ddd5 100644
--- a/src/Font/Font.cpp
+++ b/src/Font/Font.cpp
@@ -19,8 +19,8 @@ Font::~Font(void) {
}
}
-bool Font::Load(const std::string& filename) {
- TTF_Font* font = TTF_OpenFont(filename.c_str(), 16);
+bool Font::Load(const std::string& filename, int size) {
+ TTF_Font* font = TTF_OpenFont(filename.c_str(), size);
if(!font) {
Debug::logger->message("Error loading %s: %s", filename.c_str(), TTF_GetError());
return false;
@@ -94,7 +94,7 @@ bool Font::Load(const std::string& filename) {
return true;
}
-void Font::DrawText(int xOffset, int yOffset, const char* text) {
+void Font::RenderText(int xOffset, int yOffset, const char* text) {
glEnable(GL_TEXTURE_2D);
BindTexture(_texture);
@@ -159,3 +159,24 @@ void Font::DrawText(int xOffset, int yOffset, const char* text) {
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
+
+void Font::TextSize(const char* text, int& width, int& height) {
+ width = 0;
+ height = _lineSkip;
+
+ int textLength = strlen(text);
+ for(int i = 0; i < textLength; i++) {
+ char c = text[i];
+ if(c == '\n') {
+ height += _lineSkip;
+ continue;
+ } else if(c == ' ') {
+ width += _spaceWidth;
+ continue;
+ } else if(c == '\t') {
+ width += _tabWidth;
+ continue;
+ }
+ width += _characters[(int)c].advance;
+ }
+}
diff --git a/src/Font/Font.h b/src/Font/Font.h
index 28356f6..5c85738 100644
--- a/src/Font/Font.h
+++ b/src/Font/Font.h
@@ -16,16 +16,15 @@ struct FontChar {
int advance;
};
-class Font : public Resource {
- template friend class ResourceManager;
-
+class Font {
public:
Font(void);
~Font(void);
- bool Load(const std::string& filename);
+ bool Load(const std::string& filename, int size);
- void DrawText(int xOffset, int yOffset, const char* text);
+ void RenderText(int xOffset, int yOffset, const char* text);
+ void TextSize(const char* text, int& width, int& height);
int GetLineSkip() const { return _lineSkip; }
float* GetColor() { return _color; }
diff --git a/src/Main/Game.cpp b/src/Main/Game.cpp
index 36a032e..80e95a5 100644
--- a/src/Main/Game.cpp
+++ b/src/Main/Game.cpp
@@ -12,8 +12,10 @@
#include "../System/Debug.h"
#include "../Sprite/Sprite.h"
#include "../Texture/Texture.h"
+
#include "../Level/Level.h"
#include "Game.h"
+#include "TitleScreen.h"
Game::Game(void) {
_level = new Level();
@@ -23,8 +25,13 @@ Game::Game(void) {
_NPC->SetXY(30.0f, 30.0f);
_testFont = new Font();
- _testFont->Load("../Data/Font/Fairydust.ttf");
+ _testFont->Load("../Data/Font/Fairydust.ttf", 24);
_testFont->SetColor(0.0f, 1.0f, 1.0f, 1.0f);
+
+ _titleScreen = new TitleScreen();
+ _inTitleScreen = true;
+
+ _running = true;
}
Game::~Game(void) {
@@ -56,7 +63,80 @@ void Game::Prepare(float dt) {
void Game::Render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ if(_inTitleScreen) {
+ RenderTitle();
+ } else {
+ RenderGame();
+ }
+}
+void Game::Shutdown(void) {
+ Debug::logger->message("\n ----- Cleaning Engine -----");
+ delete _testFont;
+ delete _NPC;
+ delete _player;
+ delete _level;
+ delete _titleScreen;
+}
+
+void Game::ProcessEvents(float dt) {
+ if(_inTitleScreen) {
+ UpdateTitle(dt);
+ } else {
+ UpdateGame(dt);
+ }
+}
+
+void Game::OnResize(int width, int height) {
+ glViewport(0, 0, width, height);
+
+ windowWidth = width;
+ windowHeight = height;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, (GLdouble)windowWidth, (GLdouble)windowHeight, 0.0, 0.0, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+void Game::UpdateTitle(float dt) {
+ _titleScreen->Update(dt);
+
+ if(!_titleScreen->IsAlive()) {
+ switch(_titleScreen->GetResult()) {
+ case TitleScreen::QUIT:
+ _running = false;
+ break;
+
+ case TitleScreen::NEW_GAME:
+ _inTitleScreen = false;
+ break;
+ }
+ }
+}
+
+void Game::UpdateGame(float dt) {
+ _player->Update(dt);
+ _NPC->Update(dt);
+ _level->Update(dt);
+}
+
+void Game::RenderTitle(void) {
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_ALPHA_TEST);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ _titleScreen->Render();
+}
+
+void Game::RenderGame(void) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@@ -80,35 +160,8 @@ void Game::Render(void) {
_level->Draw(xOffset, yOffset);
_player->Render();
_NPC->Render();
- _testFont->DrawText(
+ _testFont->RenderText(
_player->GetX() - 5,
_player->GetY() - _testFont->GetLineSkip() - 2,
"Miss D");
}
-
-void Game::Shutdown(void) {
- Debug::logger->message("\n ----- Cleaning Engine -----");
- delete _testFont;
- delete _NPC;
- delete _player;
- delete _level;
-}
-
-void Game::ProcessEvents(float dt) {
- _player->Update(dt);
- _NPC->Update(dt);
-}
-
-void Game::OnResize(int width, int height) {
- glViewport(0, 0, width, height);
-
- windowWidth = width;
- windowHeight = height;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, (GLdouble)windowWidth, (GLdouble)windowHeight, 0.0, 0.0, 1.0);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-}
diff --git a/src/Main/Game.h b/src/Main/Game.h
index d80066b..254b83b 100644
--- a/src/Main/Game.h
+++ b/src/Main/Game.h
@@ -6,6 +6,8 @@
class Sprite;
class Level;
+class Button;
+class TitleScreen;
class Game {
public:
@@ -21,9 +23,22 @@ public:
void OnResize(int width, int height);
+ bool IsRunning() { return _running; }
+ void SetRunning(bool running) { _running = running; }
+
private:
+ void UpdateTitle(float dt);
+ void UpdateGame(float dt);
+ void RenderTitle(void);
+ void RenderGame(void);
+
Font* _testFont;
Player* _player;
NPC* _NPC;
Level* _level;
+
+ TitleScreen* _titleScreen;
+ bool _inTitleScreen;
+
+ bool _running;
};
diff --git a/src/Main/TitleScreen.cpp b/src/Main/TitleScreen.cpp
new file mode 100644
index 0000000..b67108d
--- /dev/null
+++ b/src/Main/TitleScreen.cpp
@@ -0,0 +1,61 @@
+#include "TitleScreen.h"
+#include "../Font/Font.h"
+#include "../UI/Button.h"
+#include "../Global/Globals.h"
+
+TitleScreen::TitleScreen(void) {
+ _alive = true;
+ _result = TitleScreen::QUIT;
+
+ _font = new Font();
+ _font->Load("../Data/Font/fairydust.ttf", 24);
+
+ Button* newGameButton = new Button();
+ Button* loadGameButton = new Button();
+ Button* quitButton = new Button();
+
+ newGameButton->SetFont(_font);
+ loadGameButton->SetFont(_font);
+ quitButton->SetFont(_font);
+
+ newGameButton->SetText("New Game");
+ loadGameButton->SetText("Load Game");
+ quitButton->SetText("Quit");
+
+ _menu.AddButton(newGameButton);
+ _menu.AddButton(loadGameButton);
+ _menu.AddButton(quitButton);
+ _menu.AlignButtons(Menu::ALIGN_VERTICALLY);
+ _menu.SetXY(32, windowHeight - 128);
+}
+
+TitleScreen::~TitleScreen(void) {
+ if(_font) {
+ delete _font;
+ _font = NULL;
+ }
+}
+
+void TitleScreen::Update(float dt) {
+ _menu.Update();
+ switch(_menu.GetTriggeredButton()) {
+ case 0:
+ _alive = false;
+ _result = TitleScreen::NEW_GAME;
+ break;
+
+ case 1:
+ _alive = false;
+ _result = TitleScreen::LOAD_GAME;
+ break;
+
+ case 2:
+ _alive = false;
+ _result = TitleScreen::QUIT;
+ break;
+ }
+}
+
+void TitleScreen::Render(void) {
+ _menu.Render();
+}
diff --git a/src/Main/TitleScreen.h b/src/Main/TitleScreen.h
new file mode 100644
index 0000000..7555bc9
--- /dev/null
+++ b/src/Main/TitleScreen.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "../UI/Menu.h"
+
+class Font;
+
+class TitleScreen {
+public:
+ enum {
+ NEW_GAME,
+ LOAD_GAME,
+ QUIT
+ };
+
+ TitleScreen(void);
+ ~TitleScreen(void);
+
+ void Update(float dt);
+ void Render(void);
+
+ bool IsAlive(void) { return _alive; }
+ int GetResult(void) { return _result; }
+
+private:
+ bool _alive;
+ int _result;
+
+ Font* _font;
+ Menu _menu;
+};
\ No newline at end of file
diff --git a/src/Main/main.cpp b/src/Main/main.cpp
index 19ac5d3..3a01324 100644
--- a/src/Main/main.cpp
+++ b/src/Main/main.cpp
@@ -99,12 +99,11 @@ int main(int argc, char** argv) {
// screws up for me. -- Allanis.
game.OnResize(windowWidth, windowHeight);
- bool isRunning = true;
- while(isRunning) {
+ while(game.IsRunning()) {
while(SDL_PollEvent(&event)) {
if((event.type == SDL_QUIT) || KeyStillDown(SDLK_ESCAPE)) {
- isRunning = false;
+ game.SetRunning(false);
break;
}
if(event.type == SDL_VIDEORESIZE) {
diff --git a/src/UI/Button.cpp b/src/UI/Button.cpp
new file mode 100644
index 0000000..34f160c
--- /dev/null
+++ b/src/UI/Button.cpp
@@ -0,0 +1,58 @@
+#include "Button.h"
+#include "../Font/Font.h"
+#include "../IO/Input.h"
+
+Button::Button(void) {
+ _text = "";
+ _font = NULL;
+ _highlighted = false;
+ _triggered = false;
+ x = 0;
+ y = 0;
+ w = 0;
+ h = 0;
+}
+
+void Button::Update(void) {
+ _triggered = false;
+
+ int mouseX = ::GetX();
+ int mouseY = ::GetY();
+
+ if((mouseX >= x) && (mouseX < (x + w)) &&
+ (mouseY >= y) && (mouseY < (y + h)))
+ {
+ _highlighted = true;
+ if(MouseUp(SDL_BUTTON(1))) {
+ _triggered = true;
+ }
+ } else {
+ _highlighted = false;
+ }
+}
+
+void Button::Render(void) {
+ if(_font) {
+ if(_highlighted) {
+ _font->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
+ } else {
+ _font->SetColor(0.5f, 0.5f, 0.5f, 1.0f);
+ }
+ _font->RenderText(x, y, _text.GetPointer());
+ _font->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
+ }
+}
+
+void Button::SetFont(Font* font) {
+ _font = font;
+ if(_text.Length() > 0) {
+ font->TextSize(_text.GetPointer(), w, h);
+ }
+}
+
+void Button::SetText(const String& text) {
+ _text = text;
+ if((_text.Length() > 0) && _font) {
+ _font->TextSize(text.GetPointer(), w, h);
+ }
+}
diff --git a/src/UI/Button.h b/src/UI/Button.h
new file mode 100644
index 0000000..31b7deb
--- /dev/null
+++ b/src/UI/Button.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "../System/String.h"
+#include "../Font/Font.h"
+
+class Button {
+public:
+ Button(void);
+
+ void Update(void);
+ void Render(void);
+
+ Font* GetFont(void) { return _font; }
+ void SetFont(Font* font);
+
+ const String& GetText(void) const { return _text;}
+ void SetText(const String& text);
+
+ bool IsHighlighted(void) const { return _highlighted; }
+ void SetHighlighted(bool highlighted) { _highlighted = highlighted; }
+
+ bool Triggered(void) const { return _triggered; }
+
+ int GetX(void) const { return x; }
+ int GetY(void) const { return y; }
+ void SetX(int x) { this->x = x; }
+ void SetY(int y) { this->y = y; }
+ void SetXY(int x, int y) { SetX(x); SetY(y); }
+
+ int GetWidth(void) const { return w; }
+ int GetHeight(void) const { return h; }
+
+private:
+ Font* _font;
+ String _text;
+
+ bool _highlighted;
+ bool _triggered;
+
+ int x;
+ int y;
+ int w;
+ int h;
+};
diff --git a/src/UI/Menu.cpp b/src/UI/Menu.cpp
new file mode 100644
index 0000000..58baf71
--- /dev/null
+++ b/src/UI/Menu.cpp
@@ -0,0 +1,67 @@
+#include "Menu.h"
+#include "Button.h"
+
+Menu::Menu(void) {
+ _triggeredButton = -1;
+ x = 0;
+ y = 0;
+}
+
+Menu::~Menu(void) {
+ for(std::list