diff --git a/.gitignore b/.gitignore index 8df9393e2..49bb7c60a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ *.lai *.la *.a + +#Compiled executable +emulationstation diff --git a/LinLibertine_R.ttf b/LinLibertine_R.ttf new file mode 100644 index 000000000..ab154440d Binary files /dev/null and b/LinLibertine_R.ttf differ diff --git a/Makefile b/Makefile index 9da5a4bc8..944c1a860 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=g++ CFLAGS=-c -Wall -LDFLAGS=-lSDL -SRCSOURCES=main.cpp Renderer.cpp Renderer_draw.cpp GuiComponent.cpp components/GuiTitleScreen.cpp +LDFLAGS=-lSDL -lSDL_ttf +SRCSOURCES=main.cpp Renderer.cpp Renderer_draw.cpp GuiComponent.cpp InputManager.cpp components/GuiTitleScreen.cpp components/GuiList.cpp components/GuiGameList.cpp SOURCES=$(addprefix src/,$(SRCSOURCES)) OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=emulationstation diff --git a/src/GuiComponent.h b/src/GuiComponent.h index 6219ce656..973d9435e 100644 --- a/src/GuiComponent.h +++ b/src/GuiComponent.h @@ -3,12 +3,14 @@ #include #include "Renderer.h" +#include "InputManager.h" class GuiComponent { public: void render(); virtual void onRender() { }; + virtual void onInput(InputManager::InputButton button, bool keyDown) { }; virtual unsigned int getLayer() { return BIT(0); }; void addChild(GuiComponent* comp); diff --git a/src/InputManager.cpp b/src/InputManager.cpp new file mode 100644 index 000000000..1e006fafa --- /dev/null +++ b/src/InputManager.cpp @@ -0,0 +1,73 @@ +#include "InputManager.h" +#include "GuiComponent.h" +#include + +std::vector InputManager::inputVector; + +void InputManager::registerComponent(GuiComponent* comp) +{ + inputVector.push_back(comp); +} + +void InputManager::unregisterComponent(GuiComponent* comp) +{ + for(unsigned int i = 0; i < inputVector.size(); i++) + { + if(inputVector.at(i) == comp) + { + inputVector.erase(inputVector.begin() + i); + break; + } + } +} + +void InputManager::processEvent(SDL_Event* event) +{ + bool keyDown = false; + if(event->key.state == SDL_PRESSED) + keyDown = true; + + std::cout << "Processing keyboard event\n"; + + //get InputButton from the event + InputButton button; + switch(event->key.keysym.sym) + { + case SDLK_LEFT: + button = LEFT; + break; + case SDLK_RIGHT: + button = RIGHT; + break; + case SDLK_UP: + button = UP; + break; + case SDLK_DOWN: + button = DOWN; + break; + case SDLK_SPACE: + button = BUTTON1; + break; + + //so the compiler doesn't complain + default: + break; + } + + + //catch emergency quit event + if(event->key.keysym.sym == SDLK_F4) + { + SDL_Event* quit = new SDL_Event(); + quit->type = SDL_QUIT; + SDL_PushEvent(quit); + std::cout << "Pushing quit event\n"; + } + + + for(unsigned int i = 0; i < inputVector.size(); i++) + { + inputVector.at(i)->onInput(button, keyDown); + } +} + diff --git a/src/InputManager.h b/src/InputManager.h new file mode 100644 index 000000000..eedc5b44c --- /dev/null +++ b/src/InputManager.h @@ -0,0 +1,23 @@ +#ifndef _INPUTMANAGER_H_ +#define _INPUTMANAGER_H_ + +#include +#include + +class GuiComponent; + +namespace InputManager { + void registerComponent(GuiComponent* comp); + void unregisterComponent(GuiComponent* comp); + + + //enum for identifying input type, regardless of configuration + enum InputButton { UP, DOWN, LEFT, RIGHT, BUTTON1, BUTTON2}; + + + void processEvent(SDL_Event* event); + + extern std::vector inputVector; +} + +#endif diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 30f666d93..0e00abf1a 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -3,6 +3,9 @@ std::vector renderVector; +unsigned int Renderer::getScreenWidth() { return 640; } +unsigned int Renderer::getScreenHeight() { return 480; } + void Renderer::registerComponent(GuiComponent* comp) { renderVector.push_back(comp); diff --git a/src/Renderer.h b/src/Renderer.h index 2d5ae1cab..88b9b7181 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -7,6 +7,8 @@ #include #include +#include +#include class GuiComponent; @@ -17,10 +19,18 @@ namespace Renderer void render(); - extern SDL_Surface* screen; + extern SDL_Surface* screen; + extern TTF_Font* font; + + unsigned int getScreenWidth(); + unsigned int getScreenHeight(); //drawing commands void drawRect(int x, int y, int w, int h, int color); + void drawText(std::string text, int x, int y, SDL_Color& color); + void drawCenteredText(std::string text, int y, SDL_Color& color); + + void loadFonts(); } #endif diff --git a/src/Renderer_draw.cpp b/src/Renderer_draw.cpp index 63bf6a538..7bfad84ef 100644 --- a/src/Renderer_draw.cpp +++ b/src/Renderer_draw.cpp @@ -1,10 +1,59 @@ #include "Renderer.h" #include +#include +#include SDL_Surface* Renderer::screen; +TTF_Font* Renderer::font; + void Renderer::drawRect(int x, int y, int h, int w, int color) { SDL_Rect rect = {x, y, h, w}; SDL_FillRect(Renderer::screen, &rect, color); } + +void Renderer::loadFonts() +{ + font = TTF_OpenFont("LinLibertine_R.ttf", 72); + if(!font) + { + std::cerr << "Error - could not load font!\n"; + std::cerr << TTF_GetError() << "\n"; + return; + } +} + +void Renderer::drawText(std::string text, int x, int y, SDL_Color& color) +{ + if(!font) + loadFonts(); + + //color = {255, 0, 0}; + + SDL_Surface* textSurf = TTF_RenderText_Blended(font, text.c_str(), color); + if(textSurf == NULL) + { + std::cerr << "Error - could not render text \"" << text << "\" to surface!\n"; + std::cerr << TTF_GetError() << "\n"; + return; + } + + SDL_Rect dest = {x, y}; + SDL_BlitSurface(textSurf, NULL, screen, &dest); + SDL_FreeSurface(textSurf); +} + +void Renderer::drawCenteredText(std::string text, int y, SDL_Color& color) +{ + if(!font) + loadFonts(); + + int w, h; + TTF_SizeText(font, text.c_str(), &w, &h); + + int x = (int)getScreenWidth() - w; + x *= 0.5; + + drawText(text, x, y, color); +} diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp new file mode 100644 index 000000000..8ce6b4f6d --- /dev/null +++ b/src/components/GuiGameList.cpp @@ -0,0 +1,16 @@ +#include "GuiGameList.h" + +GuiGameList::GuiGameList(std::string systemName) +{ + mSystemName = systemName; + + mList = new GuiList(); + + addChild(mList); +} + +void GuiGameList::onRender() +{ + SDL_Color color = {0, 0, 255}; + Renderer::drawCenteredText(mSystemName, 2, color); +} diff --git a/src/components/GuiGameList.h b/src/components/GuiGameList.h new file mode 100644 index 000000000..5d8802abc --- /dev/null +++ b/src/components/GuiGameList.h @@ -0,0 +1,19 @@ +#ifndef _GUIGAMELIST_H_ +#define _GUIGAMELIST_H_ + +#include "../GuiComponent.h" +#include "GuiList.h" +#include + +class GuiGameList : GuiComponent +{ +public: + GuiGameList(std::string systemName); + + void onRender(); +private: + std::string mSystemName; + GuiList* mList; +}; + +#endif diff --git a/src/components/GuiList.cpp b/src/components/GuiList.cpp new file mode 100644 index 000000000..54ea632fb --- /dev/null +++ b/src/components/GuiList.cpp @@ -0,0 +1,33 @@ +#include "GuiList.h" + +GuiList::GuiList() +{ + mSelection = 0; +} + +void GuiList::onRender() +{ + +} + +void GuiList::addObject(std::string name, void* obj) +{ + mNameVector.push_back(name); + mPointerVector.push_back(obj); +} + +void GuiList::clearObjects() +{ + mNameVector.clear(); + mPointerVector.clear(); +} + +std::string GuiList::getSelectedName() +{ + return mNameVector.at(mSelection); +} + +void* GuiList::getSelectedObject() +{ + return mPointerVector.at(mSelection); +} diff --git a/src/components/GuiList.h b/src/components/GuiList.h new file mode 100644 index 000000000..5da5ba3c1 --- /dev/null +++ b/src/components/GuiList.h @@ -0,0 +1,27 @@ +#ifndef _GUILIST_H_ +#define _GUILIST_H_ + +#include "../Renderer.h" +#include "../GuiComponent.h" +#include +#include + +class GuiList : public GuiComponent +{ +public: + GuiList(); + + void onRender(); + + void addObject(std::string name, void* obj); + void clearObjects(); + + std::string getSelectedName(); + void* getSelectedObject(); +private: + std::vector mNameVector; + std::vector mPointerVector; + unsigned int mSelection; +}; + +#endif diff --git a/src/components/GuiTitleScreen.cpp b/src/components/GuiTitleScreen.cpp index 8218ee9f4..bc170a4d3 100644 --- a/src/components/GuiTitleScreen.cpp +++ b/src/components/GuiTitleScreen.cpp @@ -12,5 +12,6 @@ GuiTitleScreen::GuiTitleScreen() void GuiTitleScreen::onRender() { Renderer::drawRect(0, 0, 640, 480, 0xFFFFFF); - std::cout << "rendering guititlescreen\n"; + SDL_Color color = {255, 0, 0}; + Renderer::drawCenteredText("EmulationStation", 5, color); } diff --git a/src/main.cpp b/src/main.cpp index bb4a0f830..58f8e9ce7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,16 +1,21 @@ #include #include +#include #include "Renderer.h" #include "components/GuiTitleScreen.h" int main() { - //if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) if(SDL_Init(SDL_INIT_EVERYTHING) != 0) { std::cerr << "Error - could not initialize SDL!\n"; return 1; } + if(TTF_Init() != 0) + { + std::cerr << "Error - could not initialize SDL_ttf!\n"; + return 1; + } Renderer::screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if(Renderer::screen == NULL) @@ -19,9 +24,11 @@ int main() return 1; } + SDL_ShowCursor(false); GuiTitleScreen* testGui = new GuiTitleScreen(); + bool running = true; while(running) { @@ -31,8 +38,12 @@ int main() switch(event.type) { case SDL_KEYDOWN: - running = false; + InputManager::processEvent(&event); break; + case SDL_KEYUP: + InputManager::processEvent(&event); + break; + case SDL_QUIT: running = false; break; @@ -45,6 +56,9 @@ int main() delete testGui; + std::cout << "EmulationStation cleanly shutting down...\n"; + + TTF_Quit(); SDL_Quit(); return 0; }