From 04841ca436992f12d35810b6e39056d0ab49afa1 Mon Sep 17 00:00:00 2001 From: Aloshi Date: Mon, 8 Apr 2013 11:52:40 -0500 Subject: [PATCH] More work. I really am nuts. --- src/Font.cpp | 5 -- src/Font.h | 4 +- src/Gui.h | 8 +-- src/InputManager.cpp | 31 ++++++-- src/InputManager.h | 6 +- src/SystemData.cpp | 11 +-- src/SystemData.h | 3 +- src/components/GuiAnimation.cpp | 23 +++--- src/components/GuiAnimation.h | 15 +++- src/components/GuiBox.cpp | 3 +- src/components/GuiBox.h | 9 +-- src/components/GuiFastSelect.cpp | 27 +++---- src/components/GuiFastSelect.h | 12 ++-- src/components/GuiGameList.cpp | 93 +++++++++--------------- src/components/GuiGameList.h | 13 ++-- src/components/GuiImage.cpp | 14 ++-- src/components/GuiImage.h | 16 +++-- src/components/GuiInputConfig.cpp | 116 ++---------------------------- src/components/GuiInputConfig.h | 19 ++--- src/components/GuiList.cpp | 52 +++++++------- src/components/GuiList.h | 20 +++--- src/components/GuiMenu.cpp | 38 ++++------ src/components/GuiMenu.h | 14 ++-- src/components/GuiTheme.cpp | 4 +- src/components/GuiTheme.h | 8 +-- src/main.cpp | 19 ++--- 26 files changed, 230 insertions(+), 353 deletions(-) diff --git a/src/Font.cpp b/src/Font.cpp index 43413a243..ab5848637 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -44,9 +44,6 @@ void Font::initLibrary() Font::Font(std::string path, int size) { - //register to receive init/deinit callbacks - Renderer::registerComponent(this); - mPath = path; mSize = size; @@ -183,8 +180,6 @@ void Font::buildAtlas() Font::~Font() { - Renderer::unregisterComponent(this); - if(textureID) glDeleteTextures(1, &textureID); } diff --git a/src/Font.h b/src/Font.h index f296c0928..6d7044b19 100644 --- a/src/Font.h +++ b/src/Font.h @@ -2,16 +2,14 @@ #define _FONT_H_ #include -#include "GuiComponent.h" #include "platform.h" #include GLHEADER #include #include FT_FREETYPE_H //A TrueType Font renderer that uses FreeType and OpenGL. -//Subclass of GuiComponent to catch ::onInit and ::onDeinit. //The library is automatically initialized when it's needed. -class Font : GuiComponent +class Font { public: static void initLibrary(); diff --git a/src/Gui.h b/src/Gui.h index 8b4d0d7c8..9053f4ae9 100644 --- a/src/Gui.h +++ b/src/Gui.h @@ -11,11 +11,11 @@ public: Gui(Window* window); virtual ~Gui(); - virtual void input(InputConfig* config, Input input) = 0; - virtual void update(int deltaTime) = 0; - virtual void render() = 0; + virtual void input(InputConfig* config, Input input) { }; + virtual void update(int deltaTime) { }; + virtual void render() { }; protected: Window* mWindow; }; -#endif \ No newline at end of file +#endif diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 0086475c8..f5aef98d3 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -100,8 +100,9 @@ InputConfig* InputManager::getInputConfigByPlayer(int player) return NULL; } -void InputManager::parseEvent(const SDL_Event& ev) +bool InputManager::parseEvent(const SDL_Event& ev) { + bool causedEvent = false; switch(ev.type) { case SDL_JOYAXISMOTION: @@ -118,19 +119,20 @@ void InputManager::parseEvent(const SDL_Event& ev) normValue = -1; mWindow->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which, TYPE_AXIS, ev.jaxis.axis, normValue, false)); + causedEvent = true; } mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = ev.jaxis.value; - break; + return causedEvent; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: mWindow->input(getInputConfigByDevice(ev.jbutton.which), Input(ev.jbutton.which, TYPE_BUTTON, ev.jbutton.button, ev.jbutton.state == SDL_PRESSED, false)); - break; + return true; case SDL_JOYHATMOTION: mWindow->input(getInputConfigByDevice(ev.jhat.which), Input(ev.jhat.which, TYPE_HAT, ev.jhat.hat, ev.jhat.value, false)); - break; + return true; case SDL_KEYDOWN: if(ev.key.keysym.sym == SDLK_F4) @@ -138,14 +140,29 @@ void InputManager::parseEvent(const SDL_Event& ev) SDL_Event* quit = new SDL_Event(); quit->type = SDL_QUIT; SDL_PushEvent(quit); - return; + return false; } mWindow->input(getInputConfigByDevice(DEVICE_KEYBOARD), Input(DEVICE_KEYBOARD, TYPE_KEY, ev.key.keysym.sym, 1, false)); - break; + return true; case SDL_KEYUP: mWindow->input(getInputConfigByDevice(DEVICE_KEYBOARD), Input(DEVICE_KEYBOARD, TYPE_KEY, ev.key.keysym.sym, 0, false)); - break; + return true; } + + return false; } + +void InputManager::loadConfig() +{ + +} + +std::string InputManager::getConfigPath() +{ + std::string path = getenv("HOME"); + path += "/.emulationstation/es_input.cfg"; + return path; +} + diff --git a/src/InputManager.h b/src/InputManager.h index 274bf355b..cfb8fb674 100644 --- a/src/InputManager.h +++ b/src/InputManager.h @@ -4,6 +4,7 @@ #include #include #include +#include class InputConfig; class Window; @@ -15,6 +16,9 @@ public: InputManager(Window* window); ~InputManager(); + void loadConfig(); + static std::string getConfigPath(); + void init(); void deinit(); @@ -23,7 +27,7 @@ public: int getNumJoysticks(); - void parseEvent(const SDL_Event& ev); + bool parseEvent(const SDL_Event& ev); InputConfig* getInputConfigByPlayer(int player); diff --git a/src/SystemData.cpp b/src/SystemData.cpp index 41f719b08..8d6b5eb77 100644 --- a/src/SystemData.cpp +++ b/src/SystemData.cpp @@ -63,14 +63,12 @@ std::string strreplace(std::string& str, std::string replace, std::string with) return str; } -void SystemData::launchGame(GameData* game) +void SystemData::launchGame(Window* window, GameData* game) { LOG(LogInfo) << "Attempting to launch game..."; - //suspend SDL joystick events (these'll pile up even while something else is running) - SDL_JoystickEventState(0); - AudioManager::deinit(); + window->getInputManager()->deinit(); Renderer::deinit(); std::string command = mLaunchCommand; @@ -89,11 +87,8 @@ void SystemData::launchGame(GameData* game) } Renderer::init(0, 0); - InputManager::openJoystick(); + window->getInputManager()->init(); AudioManager::init(); - - //re-enable SDL joystick events - SDL_JoystickEventState(1); } void SystemData::populateFolder(FolderData* folder) diff --git a/src/SystemData.h b/src/SystemData.h index 15e6417eb..e3c6755d2 100644 --- a/src/SystemData.h +++ b/src/SystemData.h @@ -4,6 +4,7 @@ #include #include #include "FolderData.h" +#include "Window.h" class GameData; @@ -21,7 +22,7 @@ public: std::string getGamelistPath(); bool hasGamelist(); - void launchGame(GameData* game); + void launchGame(Window* window, GameData* game); static void deleteSystems(); static void loadConfig(); diff --git a/src/components/GuiAnimation.cpp b/src/components/GuiAnimation.cpp index fd23650e0..379bdc08b 100644 --- a/src/components/GuiAnimation.cpp +++ b/src/components/GuiAnimation.cpp @@ -17,7 +17,7 @@ void GuiAnimation::move(int x, int y, int speed) void GuiAnimation::fadeIn(int time) { - setOpacity(0); + mOpacity = 0; setChildrenOpacity(0); mFadeRate = time; @@ -25,13 +25,13 @@ void GuiAnimation::fadeIn(int time) void GuiAnimation::fadeOut(int time) { - setOpacity(255); + mOpacity = 255; setChildrenOpacity(255); mFadeRate = -time; } -void GuiAnimation::onTick(int deltaTime) +void GuiAnimation::update(int deltaTime) { float mult = deltaTime * 0.05; @@ -51,7 +51,7 @@ void GuiAnimation::onTick(int deltaTime) if(mFadeRate != 0) { - int opacity = getOpacity() + mFadeRate; + int opacity = (int)mOpacity + mFadeRate; if(opacity > 255) { mFadeRate = 0; @@ -64,24 +64,29 @@ void GuiAnimation::onTick(int deltaTime) opacity = 0; } - setOpacity((unsigned char)opacity); + mOpacity = (unsigned char)opacity; setChildrenOpacity((unsigned char)opacity); } } +void GuiAnimation::addChild(GuiImage* gui) +{ + mChildren.push_back(gui); +} + void GuiAnimation::moveChildren(int offsetx, int offsety) { - for(unsigned int i = 0; i < getChildCount(); i++) + for(unsigned int i = 0; i < mChildren.size(); i++) { - GuiComponent* comp = getChild(i); + GuiImage* comp = mChildren.at(i); comp->setOffset(comp->getOffsetX() + offsetx, comp->getOffsetY() + offsety); } } void GuiAnimation::setChildrenOpacity(unsigned char opacity) { - for(unsigned int i = 0; i < getChildCount(); i++) + for(unsigned int i = 0; i < mChildren.size(); i++) { - getChild(i)->setOpacity(opacity); + mChildren.at(i)->setOpacity(opacity); } } diff --git a/src/components/GuiAnimation.h b/src/components/GuiAnimation.h index 1ad674ff0..767ca2ffc 100644 --- a/src/components/GuiAnimation.h +++ b/src/components/GuiAnimation.h @@ -1,9 +1,11 @@ #ifndef _GUIANIMATION_H_ #define _GUIANIMATION_H_ -#include "../GuiComponent.h" +#include "../Gui.h" +#include "GuiImage.h" +#include -class GuiAnimation : public GuiComponent +class GuiAnimation { public: GuiAnimation(); @@ -12,8 +14,15 @@ public: void fadeIn(int time); void fadeOut(int time); - void onTick(int deltaTime); + void update(int deltaTime); + + void addChild(GuiImage* gui); + private: + unsigned char mOpacity; + + std::vector mChildren; + void moveChildren(int offsetx, int offsety); void setChildrenOpacity(unsigned char opacity); diff --git a/src/components/GuiBox.cpp b/src/components/GuiBox.cpp index da4f4baf3..07200f97d 100644 --- a/src/components/GuiBox.cpp +++ b/src/components/GuiBox.cpp @@ -54,7 +54,7 @@ void GuiBox::setCornerImage(std::string path) mCornerImage.setImage(path); } -void GuiBox::onRender() +void GuiBox::render() { mBackgroundImage.render(); @@ -122,7 +122,6 @@ void GuiBox::onDeinit() mVerticalImage.deinit(); } - int GuiBox::getHorizontalBorderWidth() { return mHorizontalImage.getWidth(); diff --git a/src/components/GuiBox.h b/src/components/GuiBox.h index f4a21bbd4..5e781c5a6 100644 --- a/src/components/GuiBox.h +++ b/src/components/GuiBox.h @@ -1,11 +1,12 @@ #ifndef _GUIBOX_H_ #define _GUIBOX_H_ -#include "../GuiComponent.h" +#include "../Gui.h" #include "GuiImage.h" #include -struct GuiBoxData { +struct GuiBoxData +{ std::string backgroundPath; bool backgroundTiled; std::string horizontalPath; @@ -15,7 +16,7 @@ struct GuiBoxData { std::string cornerPath; }; -class GuiBox : public GuiComponent +class GuiBox { public: GuiBox(int offsetX, int offsetY, unsigned int width, unsigned int height); @@ -29,7 +30,7 @@ public: bool hasBackground(); - void onRender(); + void render(); void onInit(); void onDeinit(); diff --git a/src/components/GuiFastSelect.cpp b/src/components/GuiFastSelect.cpp index 261c8430b..75f1f7f43 100644 --- a/src/components/GuiFastSelect.cpp +++ b/src/components/GuiFastSelect.cpp @@ -6,15 +6,13 @@ const std::string GuiFastSelect::LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const int GuiFastSelect::SCROLLSPEED = 100; const int GuiFastSelect::SCROLLDELAY = 507; -GuiFastSelect::GuiFastSelect(GuiComponent* parent, GuiList* list, char startLetter, GuiBoxData data, int textcolor, Sound* scrollsound, Font* font) +GuiFastSelect::GuiFastSelect(Window* window, GuiComponent* parent, GuiList* list, char startLetter, GuiBoxData data, + int textcolor, Sound* scrollsound, Font* font) : Gui(window) { mLetterID = LETTERS.find(toupper(startLetter)); if(mLetterID == std::string::npos) mLetterID = 0; - Renderer::registerComponent(this); - InputManager::registerComponent(this); - mParent = parent; mList = list; mScrollSound = scrollsound; @@ -29,21 +27,14 @@ GuiFastSelect::GuiFastSelect(GuiComponent* parent, GuiList* list, cha mBox->setData(data); mTextColor = textcolor; - - mParent->pause(); } GuiFastSelect::~GuiFastSelect() { - Renderer::unregisterComponent(this); - InputManager::unregisterComponent(this); - delete mBox; - - mParent->resume(); } -void GuiFastSelect::onRender() +void GuiFastSelect::render() { unsigned int sw = Renderer::getScreenWidth(), sh = Renderer::getScreenHeight(); @@ -55,28 +46,28 @@ void GuiFastSelect::onRender() Renderer::drawCenteredText(LETTERS.substr(mLetterID, 1), 0, sh * 0.5 - (mFont->getHeight() * 0.5), mTextColor, mFont); } -void GuiFastSelect::onInput(InputManager::InputButton button, bool keyDown) +void GuiFastSelect::input(InputConfig* config, Input input) { - if(button == InputManager::UP && keyDown) + if(config->isMappedTo("up", input) && input.value != 0) { mScrollOffset = -1; scroll(); } - if(button == InputManager::DOWN && keyDown) + if(config->isMappedTo("down", input) && input.value != 0) { mScrollOffset = 1; scroll(); } - if((button == InputManager::UP || button == InputManager::DOWN) && !keyDown) + if((config->isMappedTo("up", input) || config->isMappedTo("down", input)) && input.value == 0) { mScrolling = false; mScrollTimer = 0; mScrollOffset = 0; } - if(button == InputManager::SELECT && !keyDown) + if(config->isMappedTo("select", input) && input.value == 0) { setListPos(); delete this; @@ -84,7 +75,7 @@ void GuiFastSelect::onInput(InputManager::InputButton button, bool keyDown) } } -void GuiFastSelect::onTick(int deltaTime) +void GuiFastSelect::update(int deltaTime) { if(mScrollOffset != 0) { diff --git a/src/components/GuiFastSelect.h b/src/components/GuiFastSelect.h index b46a86cb3..37d73996c 100644 --- a/src/components/GuiFastSelect.h +++ b/src/components/GuiFastSelect.h @@ -1,22 +1,22 @@ #ifndef _GUIFASTSELECT_H_ #define _GUIFASTSELECT_H_ -#include "../GuiComponent.h" +#include "../Gui.h" #include "../SystemData.h" #include "../FolderData.h" #include "../Sound.h" #include "GuiList.h" #include "GuiBox.h" -class GuiFastSelect : GuiComponent +class GuiFastSelect : Gui { public: - GuiFastSelect(GuiComponent* parent, GuiList* list, char startLetter, GuiBoxData data, int textcolor, Sound* scrollsound, Font* font); + GuiFastSelect(Window* window, GuiComponent* parent, GuiList* list, char startLetter, GuiBoxData data, int textcolor, Sound* scrollsound, Font* font); ~GuiFastSelect(); - void onRender(); - void onInput(InputManager::InputButton button, bool keyDown); - void onTick(int deltaTime); + void input(InputConfig* config, Input input); + void update(int deltaTime); + void render(); private: static const std::string LETTERS; static const int SCROLLSPEED; diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index 8f97464f5..c317f05ca 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -6,44 +6,36 @@ #include #include "../Log.h" -GuiGameList::GuiGameList(bool useDetail) +GuiGameList::GuiGameList(Window* window, bool useDetail) : Gui(window) { mDetailed = useDetail; - mTheme = new GuiTheme(mDetailed); //not a child because it's rendered manually by GuiGameList::onRender (to make sure it's rendered first) + mTheme = new GuiTheme(mWindow, mDetailed); //The GuiGameList can use the older, simple game list if so desired. //The old view only shows a list in the center of the screen; the new view can display an image and description. //Those with smaller displays may prefer the older view. if(mDetailed) { - mList = new GuiList(Renderer::getScreenWidth() * mTheme->getFloat("listOffsetX"), Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM)); + mList = new GuiList(mWindow, Renderer::getScreenWidth() * mTheme->getFloat("listOffsetX"), Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM)); - mScreenshot = new GuiImage(Renderer::getScreenWidth() * mTheme->getFloat("gameImageOffsetX"), Renderer::getScreenHeight() * mTheme->getFloat("gameImageOffsetY"), "", mTheme->getFloat("gameImageWidth"), mTheme->getFloat("gameImageHeight"), false); + mScreenshot = new GuiImage(mWindow, Renderer::getScreenWidth() * mTheme->getFloat("gameImageOffsetX"), Renderer::getScreenHeight() * mTheme->getFloat("gameImageOffsetY"), "", mTheme->getFloat("gameImageWidth"), mTheme->getFloat("gameImageHeight"), false); mScreenshot->setOrigin(mTheme->getFloat("gameImageOriginX"), mTheme->getFloat("gameImageOriginY")); - //addChild(mScreenshot); //the animation renders the screenshot mImageAnimation = new GuiAnimation(); mImageAnimation->addChild(mScreenshot); - addChild(mImageAnimation); }else{ mList = new GuiList(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM)); mScreenshot = NULL; mImageAnimation = NULL; } - addChild(mList); - setSystemId(0); - - Renderer::registerComponent(this); - InputManager::registerComponent(this); } GuiGameList::~GuiGameList() { - Renderer::unregisterComponent(this); delete mList; if(mDetailed) @@ -52,8 +44,6 @@ GuiGameList::~GuiGameList() delete mScreenshot; delete mTheme; } - - InputManager::unregisterComponent(this); } void GuiGameList::setSystemId(int id) @@ -83,7 +73,7 @@ void GuiGameList::setSystemId(int id) updateDetailData(); } -void GuiGameList::onRender() +void GuiGameList::render() { if(mTheme) mTheme->render(); @@ -110,34 +100,31 @@ void GuiGameList::onRender() } } -void GuiGameList::onInput(InputManager::InputButton button, bool keyDown) +void GuiGameList::input(InputConfig* config, Input input) { - if(button == InputManager::BUTTON1 && mFolder->getFileCount() > 0) + if(config->isMappedTo("a", input) && mFolder->getFileCount() > 0 && input.value != 0) { - if(!keyDown) + //play select sound + mTheme->getSound("menuSelect")->play(); + + FileData* file = mList->getSelectedObject(); + if(file->isFolder()) //if you selected a folder, add this directory to the stack, and use the selected one { - //play select sound - mTheme->getSound("menuSelect")->play(); + mFolderStack.push(mFolder); + mFolder = (FolderData*)file; + updateList(); + }else{ + mList->stopScrolling(); - FileData* file = mList->getSelectedObject(); - if(file->isFolder()) //if you selected a folder, add this directory to the stack, and use the selected one - { - mFolderStack.push(mFolder); - mFolder = (FolderData*)file; - updateList(); - }else{ - mList->stopScrolling(); + //wait for the sound to finish or we'll never hear it... + while(mTheme->getSound("menuSelect")->isPlaying()); - //wait for the sound to finish or we'll never hear it... - while(mTheme->getSound("menuSelect")->isPlaying()); - - mSystem->launchGame((GameData*)file); - } + mSystem->launchGame((GameData*)file); } } //if there's something on the directory stack, return to it - if(button == InputManager::BUTTON2 && keyDown && mFolderStack.size()) + if(config->isMappedTo("b", input) && input.value != 0 && mFolderStack.size()) { mFolder = mFolderStack.top(); mFolderStack.pop(); @@ -149,35 +136,35 @@ void GuiGameList::onInput(InputManager::InputButton button, bool keyDown) } //only allow switching systems if more than one exists (otherwise it'll reset your position when you switch and it's annoying) - if(SystemData::sSystemVector.size() > 1) + if(SystemData::sSystemVector.size() > 1 && input.value != 0) { - if(button == InputManager::RIGHT && keyDown) + if(config->isMappedTo("right", input)) { setSystemId(mSystemId + 1); } - if(button == InputManager::LEFT && keyDown) + if(config->isMappedTo("left", input)) { setSystemId(mSystemId - 1); } } //open the "start menu" - if(button == InputManager::MENU && keyDown) + if(config->isMappedTo("menu", input) && input.value != 0) { new GuiMenu(this); } //open the fast select menu - if(button == InputManager::SELECT && keyDown) + if(config->isMappedTo("select", input) && input.value != 0) { - new GuiFastSelect(this, mList, mList->getSelectedObject()->getName()[0], mTheme->getBoxData(), mTheme->getColor("fastSelect"), mTheme->getSound("menuScroll"), mTheme->getFastSelectFont()); + new GuiFastSelect(mWindow, this, mList, mList->getSelectedObject()->getName()[0], mTheme->getBoxData(), mTheme->getColor("fastSelect"), mTheme->getSound("menuScroll"), mTheme->getFastSelectFont()); } if(mDetailed) { - if(button == InputManager::UP || button == InputManager::DOWN || button == InputManager::PAGEUP || button == InputManager::PAGEDOWN) + if(config->isMappedTo("up", input) || config->isMappedTo("down", input) || config->isMappedTo("pageup", input) || config->isMappedTo("pagedown", input)) { - if(!keyDown) + if(input.value == 0) updateDetailData(); else clearDetailData(); @@ -203,8 +190,8 @@ void GuiGameList::updateList() } } -std::string GuiGameList::getThemeFile() { - +std::string GuiGameList::getThemeFile() +{ std::string themePath; themePath = getenv("HOME"); @@ -281,20 +268,6 @@ void GuiGameList::clearDetailData() } } -//these are called when the menu opens/closes -void GuiGameList::onPause() -{ - mList->stopScrolling(); - mTheme->getSound("menuOpen")->play(); - InputManager::unregisterComponent(this); -} - -void GuiGameList::onResume() -{ - updateDetailData(); - InputManager::registerComponent(this); -} - //called when the renderer shuts down/returns //we have to manually call init/deinit on mTheme because it is not our child void GuiGameList::onDeinit() @@ -308,7 +281,7 @@ void GuiGameList::onInit() } extern bool IGNOREGAMELIST; //defined in main.cpp (as a command line argument) -GuiGameList* GuiGameList::create() +GuiGameList* GuiGameList::create(Window* window) { bool detailed = false; @@ -324,5 +297,5 @@ GuiGameList* GuiGameList::create() } } - return new GuiGameList(detailed); + return new GuiGameList(window, detailed); } diff --git a/src/components/GuiGameList.h b/src/components/GuiGameList.h index a6cefda90..1aa9f0cd5 100644 --- a/src/components/GuiGameList.h +++ b/src/components/GuiGameList.h @@ -1,7 +1,7 @@ #ifndef _GUIGAMELIST_H_ #define _GUIGAMELIST_H_ -#include "../GuiComponent.h" +#include "../Gui.h" #include "GuiList.h" #include "GuiImage.h" #include "GuiTheme.h" @@ -14,7 +14,7 @@ //This is where the magic happens - GuiGameList is the parent of almost every graphical element in ES at the moment. //It has a GuiList child that handles the game list, a GuiTheme that handles the theming system, and a GuiImage for game images. -class GuiGameList : public GuiComponent +class GuiGameList : public Gui { public: GuiGameList(bool useDetail = false); @@ -22,14 +22,13 @@ public: void setSystemId(int id); - void onRender(); - void onInput(InputManager::InputButton button, bool keyDown); - void onPause(); - void onResume(); + void render(); + void input(InputConfig* config, Input input); + void onInit(); void onDeinit(); - static GuiGameList* create(); + static GuiGameList* create(Window* window); static const float sInfoWidth; private: diff --git a/src/components/GuiImage.cpp b/src/components/GuiImage.cpp index da52dbda7..bc261c7ae 100644 --- a/src/components/GuiImage.cpp +++ b/src/components/GuiImage.cpp @@ -7,12 +7,12 @@ unsigned int GuiImage::getWidth() { return mDrawWidth; } unsigned int GuiImage::getHeight() { return mDrawHeight; } -GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool resizeExact) +GuiImage::GuiImage(GuiWindow* window, int offsetX, int offsetY, std::string path, unsigned int resizeWidth, unsigned int resizeHeight, bool resizeExact) : Gui(window) { mTextureID = 0; - setOffsetX(offsetX); - setOffsetY(offsetY); + mOffsetX = offsetX; + mOffsetY = offsetY; //default origin is the center of image mOriginX = 0.5; @@ -260,7 +260,7 @@ void GuiImage::setFlipY(bool flip) mFlipY = flip; } -void GuiImage::onRender() +void GuiImage::render() { if(mTextureID && getOpacity() > 0) { @@ -368,3 +368,9 @@ bool GuiImage::hasImage() { return !mPath.empty(); } + +int GuiImage::getOffsetX() { return mOffsetX; } +int GuiImage::getOffsetY() { return mOffsetY; } +unsigned char GuiImage::getOpacity() { return mOpacity; } +void GuiImage::setOffset(int x, int y) { mOffsetX = x; mOffsetY = y; } +void GuiImage::setOpacity(unsigned char opacity) { mOpacity = opacity; } diff --git a/src/components/GuiImage.h b/src/components/GuiImage.h index 8747b4fb9..ff7291700 100644 --- a/src/components/GuiImage.h +++ b/src/components/GuiImage.h @@ -1,19 +1,19 @@ #ifndef _GUIIMAGE_H_ #define _GUIIMAGE_H_ -#include "../GuiComponent.h" +#include "../Gui.h" #include #include #include "../platform.h" #include GLHEADER -class GuiImage : public GuiComponent +class GuiImage : public Gui { public: //Creates a new GuiImage at the given location. If given an image, it will be loaded. If maxWidth and/or maxHeight are nonzero, the image will be //resized to fix. If only one axis is specified, the other will be resized in accordance with the image's aspect ratio. If resizeExact is false, //the image will only be downscaled, never upscaled (the image's size must surpass at least one nonzero bound). - GuiImage(int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool resizeExact = false); + GuiImage(Window* window, int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool resizeExact = false); ~GuiImage(); void setImage(std::string path); //Loads the image at the given filepath. @@ -29,17 +29,25 @@ public: bool hasImage(); - void onRender(); + void render(); //Image textures will be deleted on renderer deinitialization, and recreated on reinitialization (if mPath is not empty). void onInit(); void onDeinit(); + int getOffsetX(); + int getOffsetY(); + unsigned char getOpacity(); + void setOpacity(unsigned char opacity); + void setOffset(int x, int y); private: unsigned int mResizeWidth, mResizeHeight; float mOriginX, mOriginY; bool mResizeExact, mTiled, mFlipX, mFlipY; + int mOffsetX, mOffsetY; + unsigned char mOpacity; + void loadImage(std::string path); void resize(); void buildImageArray(int x, int y, GLfloat* points, GLfloat* texs, float percentageX = 1, float percentageY = 1); //writes 12 GLfloat points and 12 GLfloat texture coordinates to a given array at a given position diff --git a/src/components/GuiInputConfig.cpp b/src/components/GuiInputConfig.cpp index 6632fe397..f8fe4d681 100644 --- a/src/components/GuiInputConfig.cpp +++ b/src/components/GuiInputConfig.cpp @@ -6,17 +6,13 @@ extern bool DEBUG; //defined in main.cpp -std::string GuiInputConfig::sInputs[] = { "UNKNOWN", "UP", "DOWN", "LEFT", "RIGHT", "BUTTON1 (Accept)", "BUTTON2 (Back)", "START (Menu)", "SELECT (Jump-to-letter)", "PAGE UP", "PAGE DOWN" }; //must be same order as InputManager::InputButton enum; only add to the end to preserve backwards compatibility -int GuiInputConfig::sInputCount = 11; +std::string GuiInputConfig::sInputs[] = { "UP", "DOWN", "LEFT", "RIGHT", "A", "B", "START", "SELECT", "PAGEUP", "PAGEDOWN" }; //must be same order as InputManager::InputButton enum; only add to the end to preserve backwards compatibility +int GuiInputConfig::sInputCount = 10; -GuiInputConfig::GuiInputConfig() +GuiInputConfig::GuiInputConfig(Window* window) : Gui(window) { - mInputNum = 1; + mInputNum = 0; mDone = false; - mLastAxis = -1; - - Renderer::registerComponent(this); - InputManager::registerComponent(this); if(SDL_NumJoysticks() < 1) { @@ -34,8 +30,6 @@ GuiInputConfig::GuiInputConfig() GuiInputConfig::~GuiInputConfig() { - Renderer::unregisterComponent(this); - InputManager::unregisterComponent(this); } void GuiInputConfig::onRender() @@ -60,106 +54,6 @@ void GuiInputConfig::onRender() Renderer::drawCenteredText("Please press the axis/button for " + sInputs[mInputNum], 0, height * 5, 0x00C000FF, font); } -void GuiInputConfig::onInput(InputManager::InputButton button, bool keyDown) +void GuiInputConfig::input(InputConfig* config, Input input) { - if(mDone) - { - if(InputManager::lastEvent->type == SDL_KEYUP || InputManager::lastEvent->type == SDL_JOYBUTTONDOWN) - { - LOG(LogDebug) << " finishing configuration..."; - - writeConfig(); - - if(mJoystick) - SDL_JoystickClose(mJoystick); - - LOG(LogDebug) << "Config complete. Closed joystick, loading input then opening GuiGameList."; - - InputManager::loadConfig(); - delete this; - GuiGameList::create(); - } - return; - } - - SDL_Event* event = InputManager::lastEvent; - if(event->type == SDL_KEYUP) - { - LOG(LogDebug) << " [KEYUP] (skipping)"; - - //keyboard key pressed; skip and continue - mInputNum++; - } - - if(event->type == SDL_JOYBUTTONDOWN) - { - LOG(LogDebug) << " [JOYBUTTONDOWN] button " << event->jbutton.button; - - mButtonMap[event->jbutton.button] = (InputManager::InputButton)mInputNum; - LOG(LogInfo) << " Mapping " << sInputs[mInputNum] << " to button " << (int)event->jbutton.button; - mInputNum++; - } - - if(event->type == SDL_JOYAXISMOTION) - { - LOG(LogDebug) << " [JOYAXISMOTION] axis " << event->jaxis.axis << ", value " << event->jaxis.value; - - if(event->jaxis.axis == mLastAxis) - { - if(event->jaxis.value < InputManager::deadzone && event->jaxis.value > -InputManager::deadzone) - mLastAxis = -1; - return; - } - if(event->jaxis.value > InputManager::deadzone) - { - mAxisPosMap[event->jaxis.axis] = (InputManager::InputButton)mInputNum; - mInputNum++; - mLastAxis = event->jaxis.axis; - LOG(LogInfo) << " Mapping " << sInputs[mInputNum - 1] << " to axis+ " << mLastAxis; - }else if(event->jaxis.value < -InputManager::deadzone) - { - mAxisNegMap[event->jaxis.axis] = (InputManager::InputButton)mInputNum; - mInputNum++; - mLastAxis = event->jaxis.axis; - LOG(LogInfo) << " Mapping " << sInputs[mInputNum - 1] << " to axis- " << mLastAxis; - } - } - - if(mInputNum >= sInputCount) - { - mDone = true; - return; - } -} - -void GuiInputConfig::writeConfig() -{ - LOG(LogDebug) << " Writing config..."; - - std::string path = InputManager::getConfigPath(); - - std::ofstream file(path.c_str()); - - if(SDL_JoystickName(0)) - file << "JOYNAME " << SDL_JoystickName(0) << "\n"; - - typedef std::map::iterator it_type; - for(it_type iter = mButtonMap.begin(); iter != mButtonMap.end(); iter++) - { - file << "BUTTON " << iter->first << " " << iter->second << "\n"; - } - - for(it_type iter = mAxisPosMap.begin(); iter != mAxisPosMap.end(); iter++) - { - file << "AXISPOS " << iter->first << " " << iter->second << "\n"; - } - - for(it_type iter = mAxisNegMap.begin(); iter != mAxisNegMap.end(); iter++) - { - file << "AXISNEG " << iter->first << " " << iter->second << "\n"; - } - - file.close(); - - LOG(LogDebug) << " Write complete.\n"; } diff --git a/src/components/GuiInputConfig.h b/src/components/GuiInputConfig.h index 49cd0f073..eb24c5b19 100644 --- a/src/components/GuiInputConfig.h +++ b/src/components/GuiInputConfig.h @@ -1,30 +1,23 @@ #ifndef _GUIINPUTCONFIG_H_ #define _GUIINPUTCONFIG_H_ -#include "../GuiComponent.h" -#include "../InputManager.h" +#include "../Gui.h" #include #include -class GuiInputConfig : GuiComponent { +class GuiInputConfig : public Gui +{ public: - GuiInputConfig(); + GuiInputConfig(Window* window); ~GuiInputConfig(); - void onRender(); - void onInput(InputManager::InputButton button, bool keyDown); + void render(); + void input(InputConfig* config, Input input); private: bool mDone; int mInputNum; - int mLastAxis; - SDL_Joystick* mJoystick; static std::string sInputs[]; static int sInputCount; - - std::map mButtonMap; - std::map mAxisPosMap; - std::map mAxisNegMap; - void writeConfig(); }; #endif diff --git a/src/components/GuiList.cpp b/src/components/GuiList.cpp index d42067f09..112e3fdd3 100644 --- a/src/components/GuiList.cpp +++ b/src/components/GuiList.cpp @@ -4,15 +4,15 @@ #include template -GuiList::GuiList(int offsetX, int offsetY, Font* font) +GuiList::GuiList(Window* window, int offsetX, int offsetY, Font* font) : Gui(window) { mSelection = 0; mScrollDir = 0; mScrolling = 0; mScrollAccumulator = 0; - setOffsetX(offsetX); - setOffsetY(offsetY); + mOffsetX = offsetX; + mOffsetY = offsetY; mTextOffsetX = 0; @@ -21,18 +21,15 @@ GuiList::GuiList(int offsetX, int offsetY, Font* font) mSelectedTextColorOverride = 0; mScrollSound = NULL; mDrawCentered = true; - - InputManager::registerComponent(this); } template GuiList::~GuiList() { - InputManager::unregisterComponent(this); } template -void GuiList::onRender() +void GuiList::render() { const int cutoff = getOffsetY(); const int entrySize = mFont->getHeight() + 5; @@ -84,36 +81,37 @@ void GuiList::onRender() } template -void GuiList::onInput(InputManager::InputButton button, bool keyDown) +void GuiList::input(InputConfig* config, Input input) { if(mRowVector.size() > 0) { - if(keyDown) + if(input.value != 0) { - if(button == InputManager::DOWN) + if(config->isMappedTo("down", input)) { mScrollDir = 1; scroll(); } - if(button == InputManager::UP) + if(config->isMappedTo("up", input)) { mScrollDir = -1; scroll(); } - if(button == InputManager::PAGEDOWN) + if(config->isMappedTo("pagedown", input)) { mScrollDir = 10; scroll(); } - if(button == InputManager::PAGEUP) + if(config->isMappedTo("pageup", input)) { mScrollDir = -10; scroll(); } }else{ - if((button == InputManager::DOWN && mScrollDir > 0) || (button == InputManager::PAGEDOWN && mScrollDir > 0) || (button == InputManager::UP && mScrollDir < 0) || (button == InputManager::PAGEUP && mScrollDir < 0)) + //if((button == InputManager::DOWN && mScrollDir > 0) || (button == InputManager::PAGEDOWN && mScrollDir > 0) || (button == InputManager::UP && mScrollDir < 0) || (button == InputManager::PAGEUP && mScrollDir < 0)) + if(config->isMappedTo("down", input) || config->isMappedTo("up", input) || config->isMappedTo("pagedown", input) || config->isMappedTo("pageup", input)) { stopScrolling(); } @@ -130,7 +128,7 @@ void GuiList::stopScrolling() } template -void GuiList::onTick(int deltaTime) +void GuiList::update(int deltaTime) { if(mScrollDir != 0) { @@ -228,18 +226,6 @@ bool GuiList::isScrolling() return mScrollDir != 0; } -template -void GuiList::onPause() -{ - InputManager::unregisterComponent(this); -} - -template -void GuiList::onResume() -{ - InputManager::registerComponent(this); -} - template void GuiList::setSelectorColor(unsigned int selectorColor) { @@ -293,3 +279,15 @@ void GuiList::setFont(Font* font) { mFont = font; } + +template +int GuiList::getOffsetX() +{ + return mOffsetX; +} + +template +int GuiList::getOffsetY() +{ + return mOffsetY; +} diff --git a/src/components/GuiList.h b/src/components/GuiList.h index 3323aa5bc..fc68d39aa 100644 --- a/src/components/GuiList.h +++ b/src/components/GuiList.h @@ -3,7 +3,7 @@ #include "../Renderer.h" #include "../Font.h" -#include "../GuiComponent.h" +#include "../Gui.h" #include "../InputManager.h" #include #include @@ -12,22 +12,19 @@ //A graphical list. Supports multiple colors for rows and scrolling. //TODO - add truncation to text rendering if name exceeds a maximum width (a trailing elipses, perhaps). template -class GuiList : public GuiComponent +class GuiList : public Gui { public: - GuiList(int offsetX, int offsetY, Font* font); + GuiList(Window* window, int offsetX, int offsetY, Font* font); ~GuiList(); - void onRender(); - void onTick(int deltaTime); - void onInput(InputManager::InputButton button, bool keyDown); + void input(InputConfig* config, Input input); + void update(int deltaTime); + void render(); void addObject(std::string name, listType obj, unsigned int color = 0xFF0000); void clear(); - void onPause(); - void onResume(); - std::string getSelectedName(); listType getSelectedObject(); int getSelection(); @@ -45,10 +42,15 @@ public: void setSelection(int i); void setFont(Font* f); + + int getOffsetX(); + int getOffsetY(); private: static const int SCROLLDELAY = 507; static const int SCROLLTIME = 200; + int mOffsetX, mOffsetY; + void scroll(); //helper method, scrolls in whatever direction scrollDir is int mScrollDir, mScrollAccumulator; diff --git a/src/components/GuiMenu.cpp b/src/components/GuiMenu.cpp index 70fd19135..2740669a9 100644 --- a/src/components/GuiMenu.cpp +++ b/src/components/GuiMenu.cpp @@ -8,45 +8,29 @@ //defined in main.cpp extern bool DONTSHOWEXIT; -GuiMenu::GuiMenu(GuiGameList* parent) +GuiMenu::GuiMenu(Window* window, GuiGameList* parent) : Gui(window) { mParent = parent; - parent->pause(); - mList = new GuiList(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::LARGE)); + mList = new GuiList(mWindow, 0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::LARGE)); mList->setSelectedTextColor(0x0000FFFF); populateList(); - addChild(mList); - - mSkippedMenuClose = false; - - Renderer::registerComponent(this); - InputManager::registerComponent(this); } GuiMenu::~GuiMenu() { - Renderer::unregisterComponent(this); - InputManager::unregisterComponent(this); - delete mList; - mParent->resume(); } -void GuiMenu::onInput(InputManager::InputButton button, bool keyDown) +void GuiMenu::input(InputConfig* config, Input input) { - if(button == InputManager::MENU && !keyDown) + if(config->isMappedTo("menu", input) && input.value != 0) { - if(!mSkippedMenuClose) - { - mSkippedMenuClose = true; - }else{ - delete this; - return; - } + delete this; + return; } - if(button == InputManager::BUTTON1 && keyDown) + if(config->isMappedTo("a", input) && input.value != 0) { executeCommand(mList->getSelectedObject()); } @@ -91,7 +75,13 @@ void GuiMenu::populateList() mList->addObject("Exit", "exit", 0xFF0000FF); //a special case; pushes an SDL quit event to the event stack instead of being called by system() } -void GuiMenu::onRender() +void GuiMenu::update(int deltaTime) +{ + mList->update(deltaTime); +} + +void GuiMenu::render() { Renderer::drawRect(Renderer::getScreenWidth() * 0.25, 0, Renderer::getScreenWidth() * 0.5, Renderer::getScreenHeight(), 0x999999); + mList->render(); } diff --git a/src/components/GuiMenu.h b/src/components/GuiMenu.h index b919c9bad..58fc2395b 100644 --- a/src/components/GuiMenu.h +++ b/src/components/GuiMenu.h @@ -1,20 +1,20 @@ #ifndef _GUIMENU_H_ #define _GUIMENU_H_ -#include "../GuiComponent.h" +#include "../Gui.h" #include "GuiList.h" class GuiGameList; -//This is a very simple menu that is opened by pressing the Menu key. -class GuiMenu : public GuiComponent +class GuiMenu : public Gui { public: - GuiMenu(GuiGameList* parent); + GuiMenu(Window* window, GuiGameList* parent); ~GuiMenu(); - void onInput(InputManager::InputButton button, bool keyDown); - void onRender(); + void input(InputConfig* config, Input input); + void update(int deltaTime); + void render(); private: GuiGameList* mParent; @@ -22,8 +22,6 @@ private: void populateList(); void executeCommand(std::string command); - - bool mSkippedMenuClose; }; #endif diff --git a/src/components/GuiTheme.cpp b/src/components/GuiTheme.cpp index 874946926..4981d2b30 100644 --- a/src/components/GuiTheme.cpp +++ b/src/components/GuiTheme.cpp @@ -59,7 +59,7 @@ Font* GuiTheme::getFastSelectFont() return mFastSelectFont; } -GuiTheme::GuiTheme(bool detailed, std::string path) +GuiTheme::GuiTheme(Window* window, bool detailed, std::string path) : Gui(window) { mDetailed = detailed; @@ -311,7 +311,7 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent) float ox = strToFloat(originX); float oy = strToFloat(originY); - GuiImage* comp = new GuiImage(x, y, "", w, h, true); + GuiImage* comp = new GuiImage(mWindow, x, y, "", w, h, true); comp->setOrigin(ox, oy); comp->setTiling(tiled); comp->setImage(path); diff --git a/src/components/GuiTheme.h b/src/components/GuiTheme.h index 9e9fbc8ae..23563ab89 100644 --- a/src/components/GuiTheme.h +++ b/src/components/GuiTheme.h @@ -1,17 +1,17 @@ #ifndef _GUITHEME_H_ #define _GUITHEME_H_ -#include "../GuiComponent.h" +#include "../Gui.h" #include "../pugiXML/pugixml.hpp" #include "GuiBox.h" #include "../Sound.h" #include "../Font.h" //This class loads an XML-defined list of GuiComponents. -class GuiTheme : public GuiComponent +class GuiTheme : Gui { public: - GuiTheme(bool detailed, std::string path = ""); + GuiTheme(Window* window, bool detailed, std::string path = ""); ~GuiTheme(); void readXML(std::string path); @@ -41,7 +41,7 @@ private: float strToFloat(std::string str, float defaultVal = 0.0f); Font* resolveFont(pugi::xml_node node, std::string defaultPath, unsigned int defaultSize); - std::vector mComponentVector; + std::vector mComponentVector; std::string mPath; bool mDetailed; diff --git a/src/main.cpp b/src/main.cpp index c5eed1012..c417f4af2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,7 @@ #include "AudioManager.h" #include "platform.h" #include "Log.h" -#include "InputManager.h" +#include "Window.h" #ifdef _RPI_ #include @@ -114,6 +114,8 @@ int main(int argc, char* argv[]) //initialize audio AudioManager::init(); + Window window; + //try loading the system config file if(!fs::exists(SystemData::getConfigPath())) //if it doesn't exist, create the example and quit { @@ -136,8 +138,8 @@ int main(int argc, char* argv[]) LOG(LogDebug) << "Found input config in " << InputManager::getConfigPath() << "\n"; //an input config already exists - load it and proceed to the gamelist as usual. - InputManager::loadConfig(); - GuiGameList::create(); + window.getInputManager()->loadConfig(); + GuiGameList::create(&window); }else{ if(DEBUG) @@ -147,10 +149,10 @@ int main(int argc, char* argv[]) if(SDL_NumJoysticks() > 0) { LOG(LogDebug) << " at least one joystick detected, launching config GUI...\n"; - new GuiInputConfig(); + window.pushGui(new GuiInputConfig(&window)); }else{ LOG(LogDebug) << " no joystick detected, ignoring...\n"; - GuiGameList::create(); + GuiGameList::create(&window); } } @@ -174,7 +176,7 @@ int main(int argc, char* argv[]) case SDL_KEYDOWN: case SDL_KEYUP: case SDL_JOYAXISMOTION: - if(InputManager::processEvent(&event) != InputManager::UNKNOWN) + if(window.getInputManager()->parseEvent(event)) { sleeping = false; timeSinceLastEvent = 0; @@ -198,8 +200,8 @@ int main(int argc, char* argv[]) int deltaTime = curTime - lastTime; lastTime = curTime; - GuiComponent::processTicks(deltaTime); - Renderer::render(); + window.update(deltaTime); + window.render(); if(DRAWFRAMERATE) { @@ -227,7 +229,6 @@ int main(int argc, char* argv[]) } AudioManager::deinit(); - Renderer::deleteAll(); Renderer::deinit(); SystemData::deleteSystems();