mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Began refactoring away the GuiComponent system in favor of ES-config's Gui system.
Man, I'm nuts.
This commit is contained in:
parent
3e6adf7be4
commit
4a35c34dc0
|
@ -2,7 +2,7 @@ CXX=g++
|
|||
CXXFLAGS=-Wall -g -O2
|
||||
LDFLAGS=
|
||||
|
||||
SRC_SOURCES=AudioManager.cpp InputConfig.cpp Log.cpp FolderData.cpp Font.cpp GameData.cpp GuiComponent.cpp InputManager.cpp main.cpp MathExp.cpp Renderer.cpp Renderer_draw_gl.cpp Renderer_init.cpp Sound.cpp SystemData.cpp XMLReader.cpp components/GuiAnimation.cpp components/GuiBox.cpp components/GuiFastSelect.cpp components/GuiGameList.cpp components/GuiImage.cpp components/GuiInputConfig.cpp components/GuiMenu.cpp components/GuiTheme.cpp pugiXML/pugixml.cpp
|
||||
SRC_SOURCES=AudioManager.cpp InputConfig.cpp Log.cpp FolderData.cpp Font.cpp GameData.cpp Gui.cpp InputManager.cpp main.cpp MathExp.cpp Renderer_draw_gl.cpp Renderer_init.cpp Sound.cpp SystemData.cpp XMLReader.cpp components/GuiAnimation.cpp components/GuiBox.cpp components/GuiFastSelect.cpp components/GuiGameList.cpp components/GuiImage.cpp components/GuiInputConfig.cpp components/GuiMenu.cpp components/GuiTheme.cpp pugiXML/pugixml.cpp
|
||||
SOURCES=$(addprefix src/,$(SRC_SOURCES))
|
||||
OBJECTS=$(SOURCES:.cpp=.o)
|
||||
DEPS=$(SOURCES:.cpp=.d)
|
||||
|
|
11
src/Gui.cpp
Normal file
11
src/Gui.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "Gui.h"
|
||||
#include "Window.h"
|
||||
|
||||
Gui::Gui(Window* window) : mWindow(window)
|
||||
{
|
||||
}
|
||||
|
||||
Gui::~Gui()
|
||||
{
|
||||
mWindow->removeGui(this);
|
||||
}
|
21
src/Gui.h
Normal file
21
src/Gui.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef _GUI_H_
|
||||
#define _GUI_H_
|
||||
|
||||
#include "InputConfig.h"
|
||||
|
||||
class Window;
|
||||
|
||||
class Gui
|
||||
{
|
||||
public:
|
||||
Gui(Window* window);
|
||||
virtual ~Gui();
|
||||
|
||||
virtual void input(InputConfig* config, Input input) = 0;
|
||||
virtual void update(int deltaTime) = 0;
|
||||
virtual void render() = 0;
|
||||
protected:
|
||||
Window* mWindow;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,113 +0,0 @@
|
|||
#include "GuiComponent.h"
|
||||
#include "Renderer.h"
|
||||
#include <iostream>
|
||||
#include "Log.h"
|
||||
|
||||
std::vector<GuiComponent*> GuiComponent::sComponentVector;
|
||||
|
||||
GuiComponent::GuiComponent()
|
||||
{
|
||||
sComponentVector.push_back(this);
|
||||
|
||||
mOffsetX = 0;
|
||||
mOffsetY = 0;
|
||||
mOpacity = 255;
|
||||
}
|
||||
|
||||
GuiComponent::~GuiComponent()
|
||||
{
|
||||
for(unsigned int i = 0; i < sComponentVector.size(); i++)
|
||||
{
|
||||
if(sComponentVector.at(i) == this)
|
||||
{
|
||||
sComponentVector.erase(sComponentVector.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::addChild(GuiComponent* comp)
|
||||
{
|
||||
mChildren.push_back(comp);
|
||||
}
|
||||
|
||||
void GuiComponent::removeChild(GuiComponent* comp)
|
||||
{
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
if(mChildren.at(i) == comp)
|
||||
{
|
||||
mChildren.erase(mChildren.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(LogError) << "Error - tried to remove GuiComponent child, but couldn't find it!";
|
||||
}
|
||||
|
||||
void GuiComponent::clearChildren()
|
||||
{
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
void GuiComponent::processTicks(int deltaTime)
|
||||
{
|
||||
for(unsigned int i = 0; i < sComponentVector.size(); i++)
|
||||
{
|
||||
sComponentVector.at(i)->onTick(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::render()
|
||||
{
|
||||
onRender();
|
||||
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
mChildren.at(i)->render();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::pause()
|
||||
{
|
||||
onPause();
|
||||
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
mChildren.at(i)->pause();
|
||||
}
|
||||
|
||||
void GuiComponent::resume()
|
||||
{
|
||||
onResume();
|
||||
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
mChildren.at(i)->resume();
|
||||
}
|
||||
|
||||
void GuiComponent::init()
|
||||
{
|
||||
onInit();
|
||||
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
mChildren.at(i)->init();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::deinit()
|
||||
{
|
||||
onDeinit();
|
||||
|
||||
for(unsigned int i = 0; i < mChildren.size(); i++)
|
||||
{
|
||||
mChildren.at(i)->deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::setOffsetX(int val) { mOffsetX = val; }
|
||||
void GuiComponent::setOffsetY(int val) { mOffsetY = val; }
|
||||
void GuiComponent::setOffset(int x, int y) { mOffsetX = x; mOffsetY = y; }
|
||||
int GuiComponent::getOffsetX() { return mOffsetX; }
|
||||
int GuiComponent::getOffsetY() { return mOffsetY; }
|
||||
|
||||
void GuiComponent::setOpacity(unsigned char opacity) { mOpacity = opacity; }
|
||||
unsigned char GuiComponent::getOpacity() { return mOpacity; }
|
|
@ -1,68 +0,0 @@
|
|||
#ifndef _GUICOMPONENT_H_
|
||||
#define _GUICOMPONENT_H_
|
||||
|
||||
#include <vector>
|
||||
#include "Renderer.h"
|
||||
#include "InputManager.h"
|
||||
|
||||
/*
|
||||
The GuiComponent class is what everything that is rendered, updated by time (ticking), or takes input is subclassed from.
|
||||
GuiComponents have a list of child GuiComponents. Rendering, ticking, pausing/resuming, init/deinit, are all automatically sent to children.
|
||||
You can rely on the parent getting called first - this way, you can control what order components are rendered in.
|
||||
You can also manually call the render/pause/resume/init/deinit methods if you so desire (e.g. want a child to render *before* its parent).
|
||||
|
||||
To make a GuiComponent render/take input, you must register with the Renderer or InputManager respectively (Renderer::registerComponent(comp) or InputManager::registerComponent(comp)).
|
||||
All components are automatically ticked every frame, just add an onTick(int deltaTime) method.
|
||||
onInput calls arrive before onRender calls.
|
||||
*/
|
||||
|
||||
class GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiComponent();
|
||||
virtual ~GuiComponent();
|
||||
|
||||
void render();
|
||||
virtual void onRender() { };
|
||||
virtual void onTick(int deltaTime) { };
|
||||
|
||||
void pause();
|
||||
void resume();
|
||||
virtual void onPause() { };
|
||||
virtual void onResume() { };
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
virtual void onInit() { };
|
||||
virtual void onDeinit() { };
|
||||
|
||||
virtual void onInput(InputManager::InputButton button, bool keyDown) { };
|
||||
|
||||
void addChild(GuiComponent* comp);
|
||||
void removeChild(GuiComponent* comp);
|
||||
void clearChildren();
|
||||
unsigned int getChildCount() { return mChildren.size(); }
|
||||
GuiComponent* getChild(unsigned int i) { return mChildren.at(i); }
|
||||
|
||||
|
||||
int getOffsetX();
|
||||
int getOffsetY();
|
||||
void setOffsetX(int val);
|
||||
void setOffsetY(int val);
|
||||
void setOffset(int x, int y);
|
||||
|
||||
unsigned char getOpacity();
|
||||
void setOpacity(unsigned char opacity);
|
||||
|
||||
static void processTicks(int deltaTime);
|
||||
|
||||
private:
|
||||
int mOffsetX, mOffsetY;
|
||||
|
||||
unsigned char mOpacity;
|
||||
|
||||
static std::vector<GuiComponent*> sComponentVector;
|
||||
std::vector<GuiComponent*> mChildren;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,311 +1,151 @@
|
|||
#include "InputManager.h"
|
||||
#include "GuiComponent.h"
|
||||
#include "InputConfig.h"
|
||||
#include "Window.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "Log.h"
|
||||
|
||||
std::vector<GuiComponent*> InputManager::inputVector;
|
||||
SDL_Event* InputManager::lastEvent = NULL;
|
||||
|
||||
std::map<int, InputManager::InputButton> InputManager::joystickButtonMap, InputManager::joystickAxisPosMap, InputManager::joystickAxisNegMap;
|
||||
std::map<int, int> InputManager::axisState;
|
||||
InputManager::InputButton InputManager::hatState = InputManager::UNKNOWN;
|
||||
std::string InputManager::joystickName = "";
|
||||
|
||||
int InputManager::deadzone = 28000;
|
||||
|
||||
void InputManager::registerComponent(GuiComponent* comp)
|
||||
InputManager::InputManager(Window* window) : mWindow(window)
|
||||
{
|
||||
inputVector.push_back(comp);
|
||||
mJoysticks = NULL;
|
||||
mKeyboardInputConfig = NULL;
|
||||
mNumJoysticks = 0;
|
||||
mNumPlayers = 0;
|
||||
}
|
||||
|
||||
void InputManager::unregisterComponent(GuiComponent* comp)
|
||||
InputManager::~InputManager()
|
||||
{
|
||||
for(unsigned int i = 0; i < inputVector.size(); i++)
|
||||
{
|
||||
if(inputVector.at(i) == comp)
|
||||
{
|
||||
inputVector.erase(inputVector.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
deinit();
|
||||
}
|
||||
|
||||
InputManager::InputButton InputManager::processEvent(SDL_Event* event)
|
||||
void InputManager::init()
|
||||
{
|
||||
bool keyDown = false;
|
||||
InputButton button = UNKNOWN;
|
||||
if(mJoysticks != NULL)
|
||||
deinit();
|
||||
|
||||
lastEvent = event;
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
|
||||
//keyboard events
|
||||
if(event->type == SDL_KEYDOWN || event->type == SDL_KEYUP)
|
||||
mNumJoysticks = SDL_NumJoysticks();
|
||||
mJoysticks = new SDL_Joystick*[mNumJoysticks];
|
||||
mInputConfigs = new InputConfig*[mNumJoysticks];
|
||||
mPrevAxisValues = new std::map<int, int>[mNumJoysticks];
|
||||
|
||||
for(int i = 0; i < mNumJoysticks; i++)
|
||||
{
|
||||
if(event->key.state == SDL_PRESSED)
|
||||
keyDown = true;
|
||||
mJoysticks[i] = SDL_JoystickOpen(i);
|
||||
mInputConfigs[i] = new InputConfig(i);
|
||||
|
||||
//get InputButton from the event
|
||||
switch(event->key.keysym.sym)
|
||||
for(int k = 0; k < SDL_JoystickNumAxes(mJoysticks[i]); k++)
|
||||
{
|
||||
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_PAGEUP:
|
||||
button = PAGEUP;
|
||||
break;
|
||||
case SDLK_RIGHTBRACKET:
|
||||
button = PAGEUP;
|
||||
break;
|
||||
case SDLK_PAGEDOWN:
|
||||
button = PAGEDOWN;
|
||||
break;
|
||||
case SDLK_LEFTBRACKET:
|
||||
button = PAGEDOWN;
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
button = BUTTON1;
|
||||
break;
|
||||
case SDLK_ESCAPE:
|
||||
button = BUTTON2;
|
||||
break;
|
||||
case SDLK_F1:
|
||||
button = MENU;
|
||||
break;
|
||||
case SDLK_F2:
|
||||
button = SELECT;
|
||||
break;
|
||||
|
||||
default:
|
||||
button = UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
//catch emergency quit event
|
||||
if(event->key.keysym.sym == SDLK_F4 && keyDown)
|
||||
{
|
||||
//I have no idea if SDL will delete this event, but we're quitting, so I don't think it really matters
|
||||
SDL_Event* quit = new SDL_Event();
|
||||
quit->type = SDL_QUIT;
|
||||
SDL_PushEvent(quit);
|
||||
LOG(LogInfo) << "Pushing quit event.";
|
||||
}
|
||||
}else{
|
||||
if(event->type == SDL_JOYBUTTONDOWN || event->type == SDL_JOYBUTTONUP) //joystick button events
|
||||
{
|
||||
if(event->type == SDL_JOYBUTTONDOWN) //defaults to false, so no else
|
||||
keyDown = true;
|
||||
|
||||
button = joystickButtonMap[event->jbutton.button];
|
||||
}else{
|
||||
if(event->type == SDL_JOYHATMOTION)
|
||||
{
|
||||
int hat = event->jhat.value;
|
||||
|
||||
if(hat == 0) //centered
|
||||
{
|
||||
//we need to send a keyUp event for the last hat
|
||||
//keyDown is already false
|
||||
button = hatState;
|
||||
}else{
|
||||
keyDown = true;
|
||||
}
|
||||
|
||||
if(hat & SDL_HAT_LEFT)
|
||||
button = LEFT;
|
||||
if(hat & SDL_HAT_RIGHT)
|
||||
button = RIGHT;
|
||||
|
||||
if(hat & SDL_HAT_UP)
|
||||
button = UP;
|
||||
if(hat & SDL_HAT_DOWN)
|
||||
button = DOWN;
|
||||
|
||||
if(button == hatState && keyDown)
|
||||
{
|
||||
//ignore this hat event since the user most likely just made it a diagonal (but it still is using the old direction)
|
||||
button = UNKNOWN;
|
||||
}else{
|
||||
if(hatState != UNKNOWN && keyDown)
|
||||
{
|
||||
//this will occur if the user went down -> downLeft -> Left or similar
|
||||
button = hatState;
|
||||
keyDown = false;
|
||||
hatState = UNKNOWN;
|
||||
processEvent(event);
|
||||
}else{
|
||||
if(!keyDown)
|
||||
hatState = UNKNOWN;
|
||||
else
|
||||
hatState = button;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
if(event->type == SDL_JOYAXISMOTION)
|
||||
{
|
||||
int axis = event->jaxis.axis;
|
||||
int value = event->jaxis.value;
|
||||
|
||||
//if this axis was previously not centered, it can only keyUp
|
||||
if(axisState[axis] != 0)
|
||||
{
|
||||
if(abs(value) < deadzone) //if it has indeed centered
|
||||
{
|
||||
if(axisState[axis] > 0)
|
||||
button = joystickAxisPosMap[axis];
|
||||
else
|
||||
button = joystickAxisNegMap[axis];
|
||||
axisState[axis] = 0;
|
||||
}
|
||||
}else{
|
||||
if(value > deadzone)
|
||||
{
|
||||
//axisPos keyDown
|
||||
axisState[axis] = 1;
|
||||
keyDown = true;
|
||||
button = joystickAxisPosMap[axis];
|
||||
}else if(value < -deadzone)
|
||||
{
|
||||
axisState[axis] = -1;
|
||||
keyDown = true;
|
||||
button = joystickAxisNegMap[axis];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mPrevAxisValues[i][k] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < inputVector.size(); i++)
|
||||
{
|
||||
inputVector.at(i)->onInput(button, keyDown);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
void InputManager::loadConfig()
|
||||
{
|
||||
LOG(LogDebug) << "Loading input config...";
|
||||
|
||||
//clear any old config
|
||||
joystickButtonMap.clear();
|
||||
joystickAxisPosMap.clear();
|
||||
joystickAxisNegMap.clear();
|
||||
|
||||
std::string path = getConfigPath();
|
||||
|
||||
std::ifstream file(path.c_str());
|
||||
|
||||
joystickName = "";
|
||||
|
||||
while(file.good())
|
||||
{
|
||||
std::string line;
|
||||
std::getline(file, line);
|
||||
|
||||
//skip blank lines and comments
|
||||
if(line.empty() || line[0] == *"#")
|
||||
continue;
|
||||
|
||||
|
||||
//I know I could probably just read from the file stream directly, but I feel it would be harder to catch errors in a readable way
|
||||
std::istringstream stream(line);
|
||||
|
||||
std::string token[3];
|
||||
int tokNum = 0;
|
||||
|
||||
while(std::getline(stream, token[tokNum], ' '))
|
||||
{
|
||||
tokNum++;
|
||||
|
||||
//JOYNAME can have spaces
|
||||
if(tokNum == 1 && token[0] == "JOYNAME")
|
||||
{
|
||||
std::getline(stream, token[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if(tokNum >= 3)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(token[0] == "BUTTON")
|
||||
{
|
||||
joystickButtonMap[atoi(token[1].c_str())] = (InputButton)atoi(token[2].c_str());
|
||||
}else if(token[0] == "AXISPOS")
|
||||
{
|
||||
joystickAxisPosMap[atoi(token[1].c_str())] = (InputButton)atoi(token[2].c_str());
|
||||
}else if(token[0] == "AXISNEG")
|
||||
{
|
||||
joystickAxisNegMap[atoi(token[1].c_str())] = (InputButton)atoi(token[2].c_str());
|
||||
}else if(token[0] == "JOYNAME")
|
||||
{
|
||||
joystickName = token[1];
|
||||
}else{
|
||||
LOG(LogWarning) << "Invalid input type - " << token[0];
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LOG(LogDebug) << "Finished loading input config";
|
||||
|
||||
openJoystick();
|
||||
}
|
||||
|
||||
void InputManager::openJoystick()
|
||||
{
|
||||
//if any joystick is plugged in
|
||||
if(SDL_NumJoysticks() > 0)
|
||||
{
|
||||
if(!joystickName.empty())
|
||||
{
|
||||
LOG(LogDebug) << " attempting to open joystick of name \"" << joystickName << "\"";
|
||||
|
||||
bool found = false;
|
||||
for(int i = 0; i < SDL_NumJoysticks(); i++)
|
||||
{
|
||||
if(strcmp(SDL_JoystickName(i), joystickName.c_str()) == 0)
|
||||
{
|
||||
LOG(LogDebug) << " found, opening joystick " << joystickName << " at " << i;
|
||||
|
||||
SDL_JoystickOpen(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
LOG(LogWarning) << " could not find named joystick! You could try manually removing the joystick name entry in the input config file.";
|
||||
}
|
||||
}else{
|
||||
LOG(LogDebug) << " opening first joystick (no name saved)";
|
||||
|
||||
SDL_JoystickOpen(0); //if we don't have a specific joystick in mind, take the first
|
||||
}
|
||||
}else{
|
||||
LOG(LogDebug) << " no joysticks detected by SDL_NumJoysticks(), so no joystick opened";
|
||||
}
|
||||
mKeyboardInputConfig = new InputConfig(DEVICE_KEYBOARD);
|
||||
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
}
|
||||
|
||||
std::string InputManager::getConfigPath()
|
||||
void InputManager::deinit()
|
||||
{
|
||||
std::string home = getenv("HOME");
|
||||
home += "/.emulationstation/es_input.cfg";
|
||||
return home;
|
||||
SDL_JoystickEventState(SDL_DISABLE);
|
||||
|
||||
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
|
||||
return;
|
||||
|
||||
if(mJoysticks != NULL)
|
||||
{
|
||||
for(int i = 0; i < mNumJoysticks; i++)
|
||||
{
|
||||
SDL_JoystickClose(mJoysticks[i]);
|
||||
delete mInputConfigs[i];
|
||||
}
|
||||
|
||||
delete mKeyboardInputConfig;
|
||||
|
||||
delete[] mJoysticks;
|
||||
delete[] mInputConfigs;
|
||||
delete[] mPrevAxisValues;
|
||||
mJoysticks = NULL;
|
||||
mKeyboardInputConfig = NULL;
|
||||
mInputConfigs = NULL;
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
|
||||
int InputManager::getNumJoysticks() { return mNumJoysticks; }
|
||||
|
||||
int InputManager::getNumPlayers() { return mNumPlayers; }
|
||||
void InputManager::setNumPlayers(int num) { mNumPlayers = num; }
|
||||
|
||||
InputConfig* InputManager::getInputConfigByDevice(int device)
|
||||
{
|
||||
if(device == DEVICE_KEYBOARD)
|
||||
return mKeyboardInputConfig;
|
||||
else
|
||||
return mInputConfigs[device];
|
||||
}
|
||||
|
||||
InputConfig* InputManager::getInputConfigByPlayer(int player)
|
||||
{
|
||||
if(mKeyboardInputConfig->getPlayerNum() == player)
|
||||
return mKeyboardInputConfig;
|
||||
|
||||
for(int i = 0; i < mNumJoysticks; i++)
|
||||
{
|
||||
if(mInputConfigs[i]->getPlayerNum() == player)
|
||||
return mInputConfigs[i];
|
||||
}
|
||||
|
||||
std::cout << "Could not find input config for player number " << player << "!\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void InputManager::parseEvent(const SDL_Event& ev)
|
||||
{
|
||||
switch(ev.type)
|
||||
{
|
||||
case SDL_JOYAXISMOTION:
|
||||
//if it switched boundaries
|
||||
if((abs(ev.jaxis.value) > DEADZONE) != (abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > DEADZONE))
|
||||
{
|
||||
int normValue;
|
||||
if(abs(ev.jaxis.value) <= DEADZONE)
|
||||
normValue = 0;
|
||||
else
|
||||
if(ev.jaxis.value > 0)
|
||||
normValue = 1;
|
||||
else
|
||||
normValue = -1;
|
||||
|
||||
mWindow->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which, TYPE_AXIS, ev.jaxis.axis, normValue, false));
|
||||
}
|
||||
|
||||
mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = ev.jaxis.value;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
mWindow->input(getInputConfigByDevice(ev.jhat.which), Input(ev.jhat.which, TYPE_HAT, ev.jhat.hat, ev.jhat.value, false));
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
if(ev.key.keysym.sym == SDLK_F4)
|
||||
{
|
||||
SDL_Event* quit = new SDL_Event();
|
||||
quit->type = SDL_QUIT;
|
||||
SDL_PushEvent(quit);
|
||||
return;
|
||||
}
|
||||
|
||||
mWindow->input(getInputConfigByDevice(DEVICE_KEYBOARD), Input(DEVICE_KEYBOARD, TYPE_KEY, ev.key.keysym.sym, 1, false));
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
mWindow->input(getInputConfigByDevice(DEVICE_KEYBOARD), Input(DEVICE_KEYBOARD, TYPE_KEY, ev.key.keysym.sym, 0, false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,46 @@
|
|||
#ifndef _INPUTMANAGER_H_
|
||||
#define _INPUTMANAGER_H_
|
||||
|
||||
#include <SDL.h>
|
||||
#include <vector>
|
||||
#include <SDL/SDL.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class GuiComponent;
|
||||
class InputConfig;
|
||||
class Window;
|
||||
|
||||
//The InputManager takes native system input and abstracts it into InputButtons.
|
||||
//GuiComponents can be registered to receive onInput() events.
|
||||
namespace InputManager {
|
||||
void registerComponent(GuiComponent* comp);
|
||||
void unregisterComponent(GuiComponent* comp);
|
||||
//you should only ever instantiate one of these, by the way
|
||||
class InputManager
|
||||
{
|
||||
public:
|
||||
InputManager(Window* window);
|
||||
~InputManager();
|
||||
|
||||
void loadConfig();
|
||||
void openJoystick();
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
//enum for identifying input, regardless of configuration
|
||||
enum InputButton { UNKNOWN, UP, DOWN, LEFT, RIGHT, BUTTON1, BUTTON2, MENU, SELECT, PAGEUP, PAGEDOWN};
|
||||
void setNumPlayers(int num);
|
||||
int getNumPlayers();
|
||||
|
||||
InputButton processEvent(SDL_Event* event);
|
||||
int getNumJoysticks();
|
||||
|
||||
extern std::vector<GuiComponent*> inputVector;
|
||||
extern SDL_Event* lastEvent; //mostly for GuiInputConfig
|
||||
extern int deadzone;
|
||||
std::string getConfigPath();
|
||||
void parseEvent(const SDL_Event& ev);
|
||||
|
||||
extern std::map<int, InputButton> joystickButtonMap;
|
||||
extern std::map<int, InputButton> joystickAxisPosMap, joystickAxisNegMap;
|
||||
extern std::map<int, int> axisState;
|
||||
extern InputButton hatState;
|
||||
extern std::string joystickName;
|
||||
}
|
||||
InputConfig* getInputConfigByPlayer(int player);
|
||||
|
||||
private:
|
||||
static const int DEADZONE = 23000;
|
||||
|
||||
Window* mWindow;
|
||||
|
||||
//non-InputManager classes shouldn't use this, as you can easily miss the keyboard
|
||||
InputConfig* getInputConfigByDevice(int device);
|
||||
|
||||
int mNumJoysticks;
|
||||
int mNumPlayers;
|
||||
SDL_Joystick** mJoysticks;
|
||||
InputConfig** mInputConfigs;
|
||||
InputConfig* mKeyboardInputConfig;
|
||||
std::map<int, int>* mPrevAxisValues;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
#include "Renderer.h"
|
||||
#include "GuiComponent.h"
|
||||
|
||||
std::vector<GuiComponent*> renderVector;
|
||||
|
||||
void Renderer::registerComponent(GuiComponent* comp)
|
||||
{
|
||||
renderVector.push_back(comp);
|
||||
}
|
||||
|
||||
void Renderer::unregisterComponent(GuiComponent* comp)
|
||||
{
|
||||
for(unsigned int i = 0; i < renderVector.size(); i++)
|
||||
{
|
||||
if(renderVector.at(i) == comp)
|
||||
{
|
||||
renderVector.erase(renderVector.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::deleteAll()
|
||||
{
|
||||
for(unsigned int i = 0; i < renderVector.size(); i++)
|
||||
{
|
||||
delete renderVector.at(i);
|
||||
}
|
||||
renderVector.clear();
|
||||
}
|
||||
|
||||
void Renderer::render()
|
||||
{
|
||||
for(unsigned int i = 0; i < renderVector.size(); i++)
|
||||
{
|
||||
renderVector.at(i)->render();
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::onInit()
|
||||
{
|
||||
for(unsigned int i = 0; i < renderVector.size(); i++)
|
||||
{
|
||||
renderVector.at(i)->init();
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::onDeinit()
|
||||
{
|
||||
for(unsigned int i = 0; i < renderVector.size(); i++)
|
||||
{
|
||||
renderVector.at(i)->deinit();
|
||||
}
|
||||
}
|
70
src/Window.cpp
Normal file
70
src/Window.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "Window.h"
|
||||
#include <iostream>
|
||||
|
||||
Window::Window()
|
||||
{
|
||||
mInputManager = new InputManager(this);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
delete mInputManager;
|
||||
}
|
||||
|
||||
void Window::pushGui(Gui* gui)
|
||||
{
|
||||
mGuiStack.push_back(gui);
|
||||
}
|
||||
|
||||
void Window::removeGui(Gui* gui)
|
||||
{
|
||||
for(unsigned int i = 0; i < mGuiStack.size(); i++)
|
||||
{
|
||||
if(mGuiStack.at(i) == gui)
|
||||
{
|
||||
mGuiStack.erase(mGuiStack.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gui* Window::peekGui()
|
||||
{
|
||||
if(mGuiStack.size() == 0)
|
||||
return NULL;
|
||||
|
||||
return mGuiStack.at(mGuiStack.size() - 1);
|
||||
}
|
||||
|
||||
void Window::render()
|
||||
{
|
||||
if(mGuiStack.size() == 0)
|
||||
std::cout << "guistack empty\n";
|
||||
|
||||
for(unsigned int i = 0; i < mGuiStack.size(); i++)
|
||||
{
|
||||
mGuiStack.at(i)->render();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(peekGui())
|
||||
this->peekGui()->input(config, input);
|
||||
}
|
||||
|
||||
void Window::update(int deltaTime)
|
||||
{
|
||||
if(peekGui())
|
||||
peekGui()->update(deltaTime);
|
||||
}
|
||||
|
||||
InputManager* Window::getInputManager()
|
||||
{
|
||||
return mInputManager;
|
||||
}
|
||||
|
||||
asIScriptEngine* Window::getScriptEngine()
|
||||
{
|
||||
return mScriptEngine;
|
||||
}
|
29
src/Window.h
Normal file
29
src/Window.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef _WINDOW_H_
|
||||
#define _WINDOW_H_
|
||||
|
||||
#include "Gui.h"
|
||||
#include "InputManager.h"
|
||||
#include <vector>
|
||||
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
Window();
|
||||
~Window();
|
||||
|
||||
void pushGui(Gui* gui);
|
||||
void removeGui(Gui* gui);
|
||||
Gui* peekGui();
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
void update(int deltaTime);
|
||||
void render();
|
||||
|
||||
InputManager* getInputManager();
|
||||
|
||||
private:
|
||||
InputManager* mInputManager;
|
||||
std::vector<Gui*> mGuiStack;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue