More work.

I really am nuts.
This commit is contained in:
Aloshi 2013-04-08 11:52:40 -05:00
parent 4a35c34dc0
commit 04841ca436
26 changed files with 230 additions and 353 deletions

View file

@ -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);
}

View file

@ -2,16 +2,14 @@
#define _FONT_H_
#include <string>
#include "GuiComponent.h"
#include "platform.h"
#include GLHEADER
#include <ft2build.h>
#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();

View file

@ -11,9 +11,9 @@ 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;
};

View file

@ -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;
}

View file

@ -4,6 +4,7 @@
#include <SDL.h>
#include <vector>
#include <map>
#include <string>
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);

View file

@ -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)

View file

@ -4,6 +4,7 @@
#include <vector>
#include <string>
#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();

View file

@ -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);
}
}

View file

@ -1,9 +1,11 @@
#ifndef _GUIANIMATION_H_
#define _GUIANIMATION_H_
#include "../GuiComponent.h"
#include "../Gui.h"
#include "GuiImage.h"
#include <vector>
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<GuiImage*> mChildren;
void moveChildren(int offsetx, int offsety);
void setChildrenOpacity(unsigned char opacity);

View file

@ -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();

View file

@ -1,11 +1,12 @@
#ifndef _GUIBOX_H_
#define _GUIBOX_H_
#include "../GuiComponent.h"
#include "../Gui.h"
#include "GuiImage.h"
#include <string>
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();

View file

@ -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<FileData*>* list, char startLetter, GuiBoxData data, int textcolor, Sound* scrollsound, Font* font)
GuiFastSelect::GuiFastSelect(Window* window, GuiComponent* parent, GuiList<FileData*>* 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<FileData*>* 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)
{

View file

@ -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<FileData*>* list, char startLetter, GuiBoxData data, int textcolor, Sound* scrollsound, Font* font);
GuiFastSelect(Window* window, GuiComponent* parent, GuiList<FileData*>* 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;

View file

@ -6,44 +6,36 @@
#include <boost/filesystem.hpp>
#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<FileData*>(Renderer::getScreenWidth() * mTheme->getFloat("listOffsetX"), Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::MEDIUM));
mList = new GuiList<FileData*>(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<FileData*>(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);
}

View file

@ -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:

View file

@ -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; }

View file

@ -1,19 +1,19 @@
#ifndef _GUIIMAGE_H_
#define _GUIIMAGE_H_
#include "../GuiComponent.h"
#include "../Gui.h"
#include <string>
#include <FreeImage.h>
#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

View file

@ -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<int, InputManager::InputButton>::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";
}

View file

@ -1,30 +1,23 @@
#ifndef _GUIINPUTCONFIG_H_
#define _GUIINPUTCONFIG_H_
#include "../GuiComponent.h"
#include "../InputManager.h"
#include "../Gui.h"
#include <map>
#include <SDL/SDL.h>
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<int, InputManager::InputButton> mButtonMap;
std::map<int, InputManager::InputButton> mAxisPosMap;
std::map<int, InputManager::InputButton> mAxisNegMap;
void writeConfig();
};
#endif

View file

@ -4,15 +4,15 @@
#include <iostream>
template <typename listType>
GuiList<listType>::GuiList(int offsetX, int offsetY, Font* font)
GuiList<listType>::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<listType>::GuiList(int offsetX, int offsetY, Font* font)
mSelectedTextColorOverride = 0;
mScrollSound = NULL;
mDrawCentered = true;
InputManager::registerComponent(this);
}
template <typename listType>
GuiList<listType>::~GuiList()
{
InputManager::unregisterComponent(this);
}
template <typename listType>
void GuiList<listType>::onRender()
void GuiList<listType>::render()
{
const int cutoff = getOffsetY();
const int entrySize = mFont->getHeight() + 5;
@ -84,36 +81,37 @@ void GuiList<listType>::onRender()
}
template <typename listType>
void GuiList<listType>::onInput(InputManager::InputButton button, bool keyDown)
void GuiList<listType>::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<listType>::stopScrolling()
}
template <typename listType>
void GuiList<listType>::onTick(int deltaTime)
void GuiList<listType>::update(int deltaTime)
{
if(mScrollDir != 0)
{
@ -228,18 +226,6 @@ bool GuiList<listType>::isScrolling()
return mScrollDir != 0;
}
template <typename listType>
void GuiList<listType>::onPause()
{
InputManager::unregisterComponent(this);
}
template <typename listType>
void GuiList<listType>::onResume()
{
InputManager::registerComponent(this);
}
template <typename listType>
void GuiList<listType>::setSelectorColor(unsigned int selectorColor)
{
@ -293,3 +279,15 @@ void GuiList<listType>::setFont(Font* font)
{
mFont = font;
}
template <typename listType>
int GuiList<listType>::getOffsetX()
{
return mOffsetX;
}
template <typename listType>
int GuiList<listType>::getOffsetY()
{
return mOffsetY;
}

View file

@ -3,7 +3,7 @@
#include "../Renderer.h"
#include "../Font.h"
#include "../GuiComponent.h"
#include "../Gui.h"
#include "../InputManager.h"
#include <vector>
#include <string>
@ -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 <typename listType>
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;

View file

@ -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<std::string>(0, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2, Renderer::getDefaultFont(Renderer::LARGE));
mList = new GuiList<std::string>(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();
}

View file

@ -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

View file

@ -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);

View file

@ -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<GuiComponent*> mComponentVector;
std::vector<Gui*> mComponentVector;
std::string mPath;
bool mDetailed;

View file

@ -10,7 +10,7 @@
#include "AudioManager.h"
#include "platform.h"
#include "Log.h"
#include "InputManager.h"
#include "Window.h"
#ifdef _RPI_
#include <bcm_host.h>
@ -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();