Compare commits

...

19 Commits

Author SHA1 Message Date
Jace 589ca45936 Removed debug output 2015-12-12 13:47:08 +01:00
Jace 0cff07101c Xbox Controller support 2015-12-12 13:42:46 +01:00
Jace 30474b70df MouseInputHandler 2015-12-12 13:42:46 +01:00
Jace 03e226ffea Refactored InputProxy to gracefully handle cases where multiple origins send the same command 2015-12-12 13:42:35 +01:00
Jace 2e7e8d3546 Clearing raw input events from event broker to encourage use of input commands instead 2015-12-12 13:42:35 +01:00
Jace 013f911ae2 Added MouseInputHandler and firstPersonInputController to aid in creation of first person movement. 2015-12-12 13:42:34 +01:00
Jace 35624008e7 InputProxy with a KeyboardInputHandler to translate keyboard keys to input commands. Input origins are bound to commands through the BindOrigin event, or through loading them from a config file. 2015-12-12 13:42:34 +01:00
Jace 5d46a10a4e Added GetAll function to config file that returns a list of all top level keys in a config file 2015-12-12 13:42:33 +01:00
Jace 784a04b8ad Fixed bug in config file overriding. Previously it was silently overwriting the whole default config and relied on hardcoded values for defaults. 2015-12-12 13:42:33 +01:00
Jace bffc97f310 Groundwork for input command proxy 2015-12-12 13:42:33 +01:00
Jace 7464facab9 Next generation raptor copter 2015-12-12 03:38:17 +01:00
Tobias Dahl f14c62f3d3 Merge pull request #12 from teamfisk/PlayerSystem
Player system
2015-12-11 17:15:00 +01:00
stiffly 3da69c8a1b Fixed indentation 2015-12-11 15:29:57 +01:00
stiffly 16d636a87c Removed Initialize function for systems. 2015-12-11 15:23:56 +01:00
stiffly 4da33ff4ec Fixed movement on a "player" cube. Very simple system atm 2015-12-11 15:00:57 +01:00
stiffly c2435fda2d Added Component to Components.xsd and Entity.xsd 2015-12-11 14:27:54 +01:00
stiffly 094c7fbb44 Added system to CMakeLists.txt. 2015-12-11 14:20:36 +01:00
stiffly 0b60979c7b Added a Initialize function for systems. 2015-12-11 14:03:00 +01:00
stiffly 80f028edf2 Added a very basic PlayerSystem, and a PlayerComponent. 2015-12-11 13:45:19 +01:00
43 changed files with 1323 additions and 673 deletions
+19 -1
View File
@@ -5,6 +5,7 @@
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/lexical_cast.hpp>
#include "../Common.h"
#include "ResourceManager.h"
@@ -19,12 +20,14 @@ private:
public:
template <typename T>
T Get(std::string key, T defaultValue);
template <typename T>
std::vector<std::pair<std::string, T>> GetAll(std::string key);
template <typename T>
void Set(std::string key, T value);
void SaveToDisk();
private:
private:
boost::filesystem::path m_Path;
boost::property_tree::ptree m_PTreeDefaults;
boost::property_tree::ptree m_PTreeOverrides;
@@ -37,6 +40,21 @@ T ConfigFile::Get(std::string key, T defaultValue)
return m_PTreeMerged.get<T>(key, defaultValue);
}
template <typename T>
std::vector<std::pair<std::string, T>> ConfigFile::GetAll(std::string key)
{
std::vector<std::pair<std::string, T>> out;
auto parent = m_PTreeMerged.find(key);
if (parent == m_PTreeMerged.not_found()) {
return out;
}
for (auto& child : parent->second) {
T value = boost::lexical_cast<T>(child.second.data());
out.push_back(std::make_pair(child.first, value));
}
return out;
}
template <typename T>
void ConfigFile::Set(std::string key, T value)
{
+67 -67
View File
@@ -17,119 +17,119 @@ class EventBroker;
class BaseEventRelay
{
friend class EventBroker;
friend class EventBroker;
protected:
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr)
{ }
~BaseEventRelay();
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr)
{ }
~BaseEventRelay();
public:
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
protected:
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
};
template <typename ContextType, typename EventType>
class EventRelay : public BaseEventRelay
{
public:
typedef std::function<bool(const EventType&)> CallbackType;
typedef std::function<bool(const EventType&)> CallbackType;
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ }
protected:
bool Receive(const std::shared_ptr<Event> event) override;
bool Receive(const std::shared_ptr<Event> event) override;
private:
CallbackType m_Callback;
CallbackType m_Callback;
};
template <typename ContextType, typename EventType>
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
{
if (m_Callback != nullptr) {
return m_Callback(*static_cast<const EventType*>(event.get()));
} else {
return false;
}
if (m_Callback != nullptr) {
return m_Callback(*static_cast<const EventType*>(event.get()));
} else {
return false;
}
}
class EventBroker
{
template <typename ContextType, typename EventType> friend class EventRelay;
template <typename ContextType, typename EventType> friend class EventRelay;
public:
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Swap();
void Clear();
void Unsubscribe(BaseEventRelay &relay);
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Swap();
void Clear();
void Unsubscribe(BaseEventRelay &relay);
private:
bool m_IsProcessing = false;
bool m_IsProcessing = false;
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
void subscribeImmediate(BaseEventRelay& relay);
void unsubscribeImmediate(BaseEventRelay& relay);
void subscribeImmediate(BaseEventRelay& relay);
void unsubscribeImmediate(BaseEventRelay& relay);
};
template <typename EventType>
void EventBroker::Publish(const EventType &event)
{
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
}
template <typename ContextType>
int EventBroker::Process()
{
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
}
#endif
+4 -7
View File
@@ -11,25 +11,22 @@ template <typename EventContext>
class InputController
{
public:
InputController(std::shared_ptr<dd::EventBroker> eventBroker)
: EventBroker(eventBroker)
InputController(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ Initialize(); }
virtual void Initialize()
{
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand);
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::OnMouseMove);
}
virtual bool OnCommand(const Events::InputCommand &event) { return false; }
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
virtual bool OnCommand(const Events::InputCommand& e) { return false; }
protected:
std::shared_ptr<dd::EventBroker> EventBroker;
EventBroker* m_EventBroker;
private:
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
};
#endif
+5 -7
View File
@@ -33,7 +33,6 @@ public:
void Initialize();
static const short MAX_GAMEPADS = 4;
void Update(double dt);
@@ -50,12 +49,6 @@ private:
std::array<int, GLFW_KEY_LAST+1> m_LastKeyState;
std::array<int, GLFW_MOUSE_BUTTON_LAST+1> m_CurrentMouseState;
std::array<int, GLFW_MOUSE_BUTTON_LAST+1> m_LastMouseState;
typedef std::array<float, static_cast<int>(Gamepad::Axis::LAST) + 1> GamepadAxisState;
std::array<GamepadAxisState, MAX_GAMEPADS> m_CurrentGamepadAxisState;
std::array<GamepadAxisState, MAX_GAMEPADS> m_LastGamepadAxisState;
typedef std::array<bool, static_cast<int>(Gamepad::Button::LAST) + 1> GamepadButtonState;
std::array<GamepadButtonState, MAX_GAMEPADS> m_CurrentGamepadButtonState;
std::array<GamepadButtonState, MAX_GAMEPADS> m_LastGamepadButtonState;
double m_CurrentMouseX, m_CurrentMouseY;
double m_LastMouseX, m_LastMouseY;
@@ -64,6 +57,11 @@ private:
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
static void GLFWMouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
LOG_DEBUG("Click! %i %i %i", button, action, mods);
}
};
#endif
+3 -3
View File
@@ -10,16 +10,16 @@ class System
friend class SystemPipeline;
public:
System(const EventBroker* eventBroker, std::string componentType)
System(EventBroker* eventBroker, std::string componentType)
: m_EventBroker(eventBroker)
, m_ComponentType(componentType)
{ }
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
private:
const EventBroker* m_EventBroker;
protected:
std::string m_ComponentType;
EventBroker* m_EventBroker;
};
#endif
+2 -2
View File
@@ -9,7 +9,7 @@
class SystemPipeline
{
public:
SystemPipeline(const EventBroker* eventBroker)
SystemPipeline(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~SystemPipeline()
@@ -51,7 +51,7 @@ public:
}
private:
const EventBroker* m_EventBroker;
EventBroker* m_EventBroker;
std::unordered_map<std::string, std::vector<System*>> m_Systems;
};
-24
View File
@@ -1,24 +0,0 @@
#ifndef Events_BindGamepadAxis_h__
#define Events_BindGamepadAxis_h__
#include "Core/EventBroker.h"
#include "Core/EGamepadAxis.h"
namespace Events
{
/** Called to bind a gamepad axis to an input command. */
struct BindGamepadAxis : Event
{
/** The axis to bind. */
Gamepad::Axis Axis;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the axis.
*/
float Value;
};
}
-26
View File
@@ -1,26 +0,0 @@
#ifndef Events_BindGamepadButton_h__
#define Events_BindGamepadButton_h__
#include "Core/EventBroker.h"
#include "Core/EGamepadButton.h"
namespace Events
{
/** Called to bind a gamepad button to an input command. */
struct BindGamepadButton : Event
{
/** The gamepad button to bind. */
Gamepad::Button Button;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the button.
*/
float Value;
};
}
#endif
-25
View File
@@ -1,25 +0,0 @@
#ifndef Events_BindKey_h__
#define Events_BindKey_h__
#include "Core/EventBroker.h"
namespace Events
{
/** Called to bind a keyboard key to an input command. */
struct BindKey : Event
{
/** The GLFW key code to bind. */
int KeyCode;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the key.
*/
float Value;
};
}
#endif
-25
View File
@@ -1,25 +0,0 @@
#ifndef Events_BindMouseButton_h__
#define Events_BindMouseButton_h__
#include "Core/EventBroker.h"
namespace Events
{
/** Called to bind a mouse button to an input command. */
struct BindMouseButton : Event
{
/** The GLFW mouse button code to bind. */
int Button;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation.
Multiplied by the 0-1 clamped value of the button.
*/
float Value;
};
}
#endif
+22
View File
@@ -0,0 +1,22 @@
#ifndef Events_BindOrigin_h__
#define Events_BindOrigin_h__
#include "Core/EventBroker.h"
namespace Events
{
/** Called to bind an input origin to an input command. */
struct BindOrigin : Event
{
/** The input origin to bind. */
std::string Origin;
/** The command to send. */
std::string Command;
/** The value to send for positive stimulation. */
float Value = 1.f;
};
}
#endif
+1 -1
View File
@@ -13,7 +13,7 @@ struct InputCommand : Event
/** The command that was sent. */
std::string Command;
/** The value of the command. */
float Value;
float Value = 0;
};
}
@@ -0,0 +1,70 @@
#ifndef FirstPersonInputController_h__
#define FirstPersonInputController_h__
#include "../GLM.h"
#include "../Core/InputController.h"
#include "../Core/ELockMouse.h"
template <typename EventContext>
class FirstPersonInputController : public InputController<EventContext>
{
public:
FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID)
: InputController(eventBroker)
, m_PlayerID(playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
}
const glm::quat Orientation() const { return m_Orientation; }
void LockMouse()
{
Events::LockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = true;
}
void UnlockMouse()
{
Events::UnlockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = false;
}
virtual bool OnCommand(const Events::InputCommand& e) override
{
if (m_PlayerID != e.PlayerID) {
return false;
}
if (m_MouseLocked) {
if (e.Command == "Pitch") {
float val = glm::radians(e.Value);
m_Orientation = m_Orientation * glm::angleAxis<float>(-val, glm::vec3(1, 0, 0));
return true;
}
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
m_Orientation = glm::angleAxis<float>(-val, glm::vec3(0, 1, 0)) * m_Orientation;
return true;
}
}
return false;
}
protected:
const unsigned int m_PlayerID;
glm::quat m_Orientation;
bool m_MouseLocked = false;
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
};
#endif
+25
View File
@@ -0,0 +1,25 @@
#ifndef InputHandler_h__
#define InputHandler_h__
#include "../Common.h"
#include "../Core/EventBroker.h"
#include "InputProxy.h"
class InputHandler
{
public:
InputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: m_EventBroker(eventBroker)
, m_InputProxy(inputProxy)
{ }
virtual bool BindOrigin(std::string origin, std::string command, float value) = 0;
virtual void Update(double dt) { }
virtual float GetCommandValue(std::string command) = 0;
protected:
EventBroker* m_EventBroker;
InputProxy* m_InputProxy;
};
#endif
+46
View File
@@ -0,0 +1,46 @@
#ifndef InputProxy_h__
#define InputProxy_h__
#include "../Common.h"
#include "../Core/ResourceManager.h"
#include "../Core/ConfigFile.h"
#include "EInputCommand.h"
#include "EBindOrigin.h"
class InputHandler;
class InputProxy
{
public:
InputProxy(EventBroker* eventBroker);
~InputProxy();
void LoadBindings(std::string file);
void Update(double dt);
void Process();
template <typename T>
void AddHandler();
void Publish(const Events::InputCommand& e);
protected:
EventBroker* m_EventBroker;
std::vector<InputHandler*> m_Handlers;
std::map<std::string, std::set<InputHandler*>> m_CommandHandlers;
// Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame
std::map<std::pair<unsigned int, std::string>, std::vector<float>> m_CommandQueue;
std::map<std::string, float> m_CurrentCommandValues;
std::map<std::string, float> m_LastCommandValues;
EventRelay<InputProxy, Events::BindOrigin> m_EBindOrigin;
bool OnBindOrigin(const Events::BindOrigin& e);
};
template <typename T>
void InputProxy::AddHandler()
{
m_Handlers.push_back(new T(m_EventBroker, this));
}
#endif
-78
View File
@@ -1,78 +0,0 @@
#ifndef InputSystem_h__
#define InputSystem_h__
#include <array>
#include <unordered_map>
#include "Core/System.h"
#include "Core/EKeyUp.h"
#include "Core/EKeyDown.h"
#include "Core/EMousePress.h"
#include "Core/EMouseRelease.h"
#include "Core/EGamepadAxis.h"
#include "Core/EGamepadButton.h"
#include "Core/Util/EnumClassHash.h"
#include "EBindKey.h"
#include "EBindMouseButton.h"
#include "EBindGamepadAxis.h"
#include "EBindGamepadButton.h"
#include "EInputCommand.h"
namespace Systems
{
class InputSystem : public System
{
public:
InputSystem(World* world, std::shared_ptr<dd::EventBroker> eventBroker)
: System(world, eventBroker)
{ }
void RegisterComponents(ComponentFactory* cf) override;
void Initialize() override;
void Update(double dt) override;
private:
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandKeyboardValues; // command string -> keyboard key value for command
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandMouseButtonValues; // command string -> mouse button value for command
std::unordered_map<std::string, std::unordered_map<Gamepad::Axis, float, EnumClassHash>> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command
std::unordered_map<std::string, std::unordered_map<Gamepad::Button, float, EnumClassHash>> m_CommandGamepadButtonValues; // command string -> gamepad button value for command
// Input binding tables
std::unordered_multimap<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
std::unordered_multimap<int, std::tuple<std::string, float>> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string
std::unordered_multimap<Gamepad::Axis, std::tuple<std::string, float>, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value
std::unordered_multimap<Gamepad::Button, std::tuple<std::string, float>, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string
// Input events
EventRelay<InputSystem, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown &event);
EventRelay<InputSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event);
EventRelay<InputSystem, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress &event);
EventRelay<InputSystem, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease &event);
EventRelay<InputSystem, Events::GamepadAxis> m_EGamepadAxis;
bool OnGamepadAxis(const Events::GamepadAxis &event);
EventRelay<InputSystem, Events::GamepadButtonDown> m_EGamepadButtonDown;
bool OnGamepadButtonDown(const Events::GamepadButtonDown &event);
EventRelay<InputSystem, Events::GamepadButtonUp> m_EGamepadButtonUp;
bool OnGamepadButtonUp(const Events::GamepadButtonUp &event);
// Input binding events
EventRelay<InputSystem, Events::BindKey> m_EBindKey;
bool OnBindKey(const Events::BindKey &event);
EventRelay<InputSystem, Events::BindMouseButton> m_EBindMouseButton;
bool OnBindMouseButton(const Events::BindMouseButton &event);
EventRelay<InputSystem, Events::BindGamepadAxis> m_EBindGamepadAxis;
bool OnBindGamepadAxis(const Events::BindGamepadAxis &event);
EventRelay<InputSystem, Events::BindGamepadButton> m_EBindGamepadButton;
bool OnBindGamepadButton(const Events::BindGamepadButton &event);
float GetCommandTotalValue(std::string command);
void PublishCommand(int playerID, std::string command, float value);
};
}
#endif
@@ -0,0 +1,28 @@
#ifndef KeyboardInputHandler_h__
#define KeyboardInputHandler_h__
#include <GLFW/glfw3.h>
#include "InputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EKeyUp.h"
class KeyboardInputHandler : public InputHandler
{
public:
KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
bool BindOrigin(std::string origin, std::string command, float value) override;
virtual float GetCommandValue(std::string command) override;
private:
std::unordered_map<std::string, int> m_OriginKeyCodes;
std::unordered_map<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
EventRelay<InputHandler, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown& e);
EventRelay<InputHandler, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp& e);
};
#endif
+38
View File
@@ -0,0 +1,38 @@
#ifndef MouseInputHandler_h__
#define MouseInputHandler_h__
#include <GLFW/glfw3.h>
#include "InputHandler.h"
#include "Core/EMousePress.h"
#include "Core/EMouseRelease.h"
#include "Core/EMouseMove.h"
class MouseInputHandler : public InputHandler
{
public:
MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
bool BindOrigin(std::string origin, std::string command, float value) override;
virtual float GetCommandValue(std::string command) override;
private:
std::unordered_map<std::string, int> m_OriginCodes;
std::unordered_map<std::string, char> m_OriginAxes;
std::unordered_map<int, std::tuple<std::string, float>> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value
std::unordered_map<char, std::tuple<std::string, float>> m_Axes; // Axis -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
std::unordered_map<std::string, float> m_ContinuousCommandValues;
EventRelay<InputHandler, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<InputHandler, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<InputHandler, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
bool hasOrigin(std::string origin);
};
#endif
@@ -0,0 +1,40 @@
#ifndef XboxControllerInputHandler_h__
#define XboxControllerInputHandler_h__
#include "InputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EKeyUp.h"
struct _XINPUT_STATE;
typedef _XINPUT_STATE XINPUT_STATE;
class XboxControllerInputHandler : public InputHandler
{
public:
XboxControllerInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
bool BindOrigin(std::string origin, std::string command, float value) override;
void Update(double dt) override;
virtual float GetCommandValue(std::string command) override;
private:
std::unordered_map<std::string, int> m_OriginButtons;
std::unordered_map<std::string, int> m_OriginAxes;
std::unordered_map<int, std::tuple<std::string, float>> m_ButtonBindings; // GLFW_KEY... -> command string & value
std::unordered_map<int, std::tuple<std::string, float>> m_AxisBindings; // GLFW_KEY... -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
static const short MAX_GAMEPADS = 4;
float getAxisValue(XINPUT_STATE& state, int axis);
//typedef std::array<float, static_cast<int>(Gamepad::Axis::LAST) + 1> GamepadAxisState;
//std::array<GamepadAxisState, MAX_GAMEPADS> m_CurrentGamepadAxisState;
//std::array<GamepadAxisState, MAX_GAMEPADS> m_LastGamepadAxisState;
//typedef std::array<bool, static_cast<int>(Gamepad::Button::LAST) + 1> GamepadButtonState;
//std::array<GamepadButtonState, MAX_GAMEPADS> m_CurrentGamepadButtonState;
//std::array<GamepadButtonState, MAX_GAMEPADS> m_LastGamepadButtonState;
};
#endif
@@ -0,0 +1,48 @@
#include "../Input/FirstPersonInputController.h"
template <typename EventContext>
class DebugCameraInputController : public FirstPersonInputController<EventContext>
{
public:
DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID)
: FirstPersonInputController(eventBroker, playerID)
{ }
const glm::vec3 Position() const { return m_Position; }
void SetBaseSpeed(float speed) { m_BaseSpeed = speed; }
virtual bool OnCommand(const Events::InputCommand& e) override
{
if (e.Command == "PrimaryFire") {
if (e.Value > 0) {
LockMouse();
} else {
UnlockMouse();
}
return false;
}
if (e.Command == "Right") {
float value = std::max(-1.f, std::min(e.Value, 1.f));
m_Velocity.x = value;
}
if (e.Command == "Forward") {
float value = std::max(-1.f, std::min(e.Value, 1.f));
m_Velocity.z = -value;
}
return FirstPersonInputController::OnCommand(e);
}
void Update(double dt)
{
if (glm::length2(m_Velocity) > 0) {
m_Position += (m_Orientation * (m_Velocity * m_BaseSpeed)) * (float)dt;
}
}
protected:
glm::vec3 m_Position = glm::vec3(0, 0, 0);
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
float m_BaseSpeed = 2.0f;
};
+10 -4
View File
@@ -9,10 +9,15 @@
#include "GUI/Frame.h"
#include "Core/World.h"
#include "Rendering/RenderQueueFactory.h"
#include "Input/InputProxy.h"
#include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h"
#include "Input/XboxControllerInputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EntityXMLFile.h"
#include "Core/SystemPipeline.h"
#include "RaptorCopterSystem.h"
#include "PlayerSystem.h"
class Game
{
@@ -29,16 +34,17 @@ private:
EventBroker* m_EventBroker;
IRenderer* m_Renderer;
InputManager* m_InputManager;
InputProxy* m_InputProxy;
GUI::Frame* m_FrameStack;
World* m_World;
SystemPipeline* m_SystemPipeline;
RenderQueueFactory* m_RenderQueueFactory;
EventRelay<Game, Events::KeyUp> m_EKeyUp;
bool testOnKeyUp(const Events::KeyUp& e);
EventRelay<Game, Events::InputCommand> m_EInputCommand;
bool debugOnInputCommand(const Events::InputCommand& e);
void testIntialize();
void testTick(double dt);
void debugInitialize();
void debugTick(double dt);
};
#endif
+44
View File
@@ -0,0 +1,44 @@
#ifndef PlayerSystem_h__
#define PlayerSystem_h__
#include <GLFW/glfw3.h>
#include <glm/common.hpp>
#include "Common.h"
#include "Core/System.h"
#include "Core/EventBroker.h"
#include "Core/EKeyDown.h"
#include "Core/EKeyUp.h"
struct KeyInput
{
bool Forward = false;
bool Left = false;
bool Back = false;
bool Right = false;
};
class PlayerSystem : public System
{
public:
PlayerSystem(EventBroker* eventBroker)
: System(eventBroker, "Player")
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp);
}
virtual void Update(World* world, ComponentWrapper& player, double dt) override;
private:
float m_Speed = 5;
glm::vec3 m_Direction;
KeyInput input;
EventRelay<PlayerSystem, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown &event);
EventRelay<PlayerSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event);
};
#endif
+3 -1
View File
@@ -4,10 +4,12 @@
class RaptorCopterSystem : public System
{
public:
RaptorCopterSystem(const EventBroker* eventBroker)
RaptorCopterSystem(EventBroker* eventBroker)
: System(eventBroker, "RaptorCopter")
{ }
virtual void Initialize() { }
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
{
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
+24
View File
@@ -0,0 +1,24 @@
[Mouse]
Sensitivity=0.5
InvertPitch=false
[Bindings]
MouseLeft=PrimaryFire
MouseX=Yaw
MouseY=Pitch
W=+Forward
S=-Forward
D=+Right
A=-Right
R=Reload
Space=Jump
LeftControl=Crouch
LeftShift=Sprint
GamepadRightTrigger=PrimaryFire
GamepadRightX=Yaw
GamepadRightY=-Pitch
GamepadA=TestGamepadA
GamepadX=TestGamepadX
GamepadLeftX=Right
GamepadLeftY=Forward
+1
View File
@@ -5,4 +5,5 @@
<xs:include schemaLocation="Components/Model.xsd"/>
<xs:include schemaLocation="Components/Test.xsd"/>
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
<xs:include schemaLocation="Components/Player.xsd"/>
</xs:schema>
+3
View File
@@ -0,0 +1,3 @@
<c:Player>
<Velocity X="0" Y="0" Z="0"/>
</c:Player>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Player">
<xs:complexType>
<xs:all>
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+18 -17
View File
@@ -31,6 +31,19 @@
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Player>
<Velocity X="0" Y="0" Z="0"/>
</c:Player>
<c:Transform>
<Position X="2.5"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
@@ -48,7 +61,7 @@
<Components>
<c:Transform>
<Position X="0" Y="0"/>
<Orientation X="0.0" Y="0" Z="0.0"/>
<Orientation X="0.0" Y="0" Z="1.0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource>
@@ -59,8 +72,8 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0"/>
<Orientation X="0" Y="0" Z="0"/>
<Position X="-0.01" Y="0.55"/>
<Orientation X="0" Y="0" Z="-1"/>
</c:Transform>
<c:RaptorCopter>
<Speed>20</Speed>
@@ -71,19 +84,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.4"/>
<Scale X="0.1" Y="0.4" Z="0.1"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCylinder.obj</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.6"/>
<Position X="0" Y="0"/>
<Scale X="1.7" Y="0.03" Z="0.1"/>
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
@@ -96,7 +97,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.6"/>
<Position X="0" Y="0"/>
<Scale X="1.7" Y="0.03" Z="0.1"/>
<Orientation X="0" Y="1.57" Z="0"/>
</c:Transform>
+1
View File
@@ -14,6 +14,7 @@
<xs:element ref="c:Model" minOccurs="0"/>
<xs:element ref="c:Test" minOccurs="0"/>
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+1 -1
View File
@@ -73,7 +73,7 @@ source_group(GUI FILES ${SOURCE_FILES_GUI})
set(SOURCE_FILES
${SOURCE_FILES_Core}
${SOURCE_FILES_Core_Util}
#${SOURCE_FILES_Input}
${SOURCE_FILES_Input}
${SOURCE_FILES_Network}
${SOURCE_FILES_GUI}
${SOURCE_FILES_Rendering}
+5 -2
View File
@@ -24,8 +24,11 @@ ConfigFile::ConfigFile(std::string path)
if (boost::filesystem::exists(m_Path)) {
try {
boost::property_tree::ini_parser::read_ini(m_Path.string(), m_PTreeOverrides);
for (auto& node : m_PTreeOverrides) {
m_PTreeMerged.put_child(node.first, node.second);
for (auto& topLevelNode : m_PTreeOverrides) {
auto& mergedTopLevelNode = m_PTreeMerged.find(topLevelNode.first);
for (auto& childOverrideNode : topLevelNode.second) {
mergedTopLevelNode->second.put_child(childOverrideNode.first, childOverrideNode.second);
}
}
} catch (boost::property_tree::ptree_error& e) {
LOG_ERROR("Failed to parse \"%s\":\n%s", m_Path.filename().string().c_str(), e.what());
+44 -90
View File
@@ -8,6 +8,8 @@ void InputManager::Initialize()
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &InputManager::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &InputManager::OnUnlockMouse);
//glfwSetMouseButtonCallback(m_GLFWWindow, &InputManager::GLFWMouseButtonCallback);
}
void InputManager::Update(double dt)
@@ -73,6 +75,21 @@ void InputManager::Update(double dt)
m_EventBroker->Publish(e);
}
// Joysticks
//for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) {
// if (glfwJoystickPresent(i) == GL_FALSE) {
// continue;
// }
// int count;
// const float* axes = glfwGetJoystickAxes(i, &count);
// LOG_DEBUG("Controller %i NumAxes: %i", i, count);
// m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftX)] = axes[0];
// m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftY)] = axes[1];
// m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightX)] = axes[2];
// m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightY)] = axes[3];
//}
// // Lock mouse while holding LMB
// if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT])
// {
@@ -91,109 +108,46 @@ void InputManager::Update(double dt)
// }
// TODO: Xbox360 controller
/*DWORD dwResult;
for (int i = 0; i < MAX_GAMEPADS; i++)
{
XINPUT_STATE state = { 0 };
// Simply get the state of the controller from XInput.
dwResult = XInputGetState(i, &state);
if (dwResult == 0)
{
if(std::abs(state.Gamepad.sThumbLX) <= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
state.Gamepad.sThumbLX = 0;
if(std::abs(state.Gamepad.sThumbLY) <= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
state.Gamepad.sThumbLY = 0;
if(std::abs(state.Gamepad.sThumbRX) <= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
state.Gamepad.sThumbRX = 0;
if(std::abs(state.Gamepad.sThumbRY) <= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
state.Gamepad.sThumbRY = 0;
if(std::abs(state.Gamepad.bLeftTrigger) <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
state.Gamepad.bLeftTrigger = 0;
if(std::abs(state.Gamepad.bRightTrigger) <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
state.Gamepad.bRightTrigger = 0;
m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftX)] = state.Gamepad.sThumbLX / 32767.f;
m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftY)] = state.Gamepad.sThumbLY / 32767.f;
m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightX)] = state.Gamepad.sThumbRX / 32767.f;
m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightY)] = state.Gamepad.sThumbRY / 32767.f;
m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftTrigger)] = state.Gamepad.bLeftTrigger / 255.f;
m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightTrigger)] = state.Gamepad.bRightTrigger / 255.f;
PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftX);
PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftY);
PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightX);
PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightY);
PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftTrigger);
PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightTrigger);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Up)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Down)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Left)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Right)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Start)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_START);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Back)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::LeftThumb)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::RightThumb)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::LeftShoulder)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::RightShoulder)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::A)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_A);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::B)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_B);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::X)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_X);
m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Y)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Up);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Down);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Left);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Right);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Start);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Back);
PublishGamepadButtonIfChanged(i, Gamepad::Button::LeftThumb);
PublishGamepadButtonIfChanged(i, Gamepad::Button::RightThumb);
PublishGamepadButtonIfChanged(i, Gamepad::Button::LeftShoulder);
PublishGamepadButtonIfChanged(i, Gamepad::Button::RightShoulder);
PublishGamepadButtonIfChanged(i, Gamepad::Button::A);
PublishGamepadButtonIfChanged(i, Gamepad::Button::B);
PublishGamepadButtonIfChanged(i, Gamepad::Button::X);
PublishGamepadButtonIfChanged(i, Gamepad::Button::Y);
}
}*/
/**/
m_LastKeyState = m_CurrentKeyState;
m_LastMouseState = m_CurrentMouseState;
m_LastMouseX = m_CurrentMouseX;
m_LastMouseY = m_CurrentMouseY;
m_LastGamepadAxisState = m_CurrentGamepadAxisState;
m_LastGamepadButtonState = m_CurrentGamepadButtonState;
//m_LastGamepadAxisState = m_CurrentGamepadAxisState;
//m_LastGamepadButtonState = m_CurrentGamepadButtonState;
}
void InputManager::PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis)
{
float currentValue = m_CurrentGamepadAxisState[gamepadID][static_cast<int>(axis)];
float lastValue = m_LastGamepadAxisState[gamepadID][static_cast<int>(axis)];
if (currentValue != lastValue) {
Events::GamepadAxis e;
e.GamepadID = gamepadID;
e.Axis = axis;
e.Value = currentValue;
m_EventBroker->Publish(e);
}
//float currentValue = m_CurrentGamepadAxisState[gamepadID][static_cast<int>(axis)];
//float lastValue = m_LastGamepadAxisState[gamepadID][static_cast<int>(axis)];
//if (currentValue != lastValue) {
// Events::GamepadAxis e;
// e.GamepadID = gamepadID;
// e.Axis = axis;
// e.Value = currentValue;
// m_EventBroker->Publish(e);
//}
}
void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button)
{
bool currentState = m_CurrentGamepadButtonState[gamepadID][static_cast<int>(button)];
float lastState = m_LastGamepadButtonState[gamepadID][static_cast<int>(button)];
if (currentState != lastState) {
if (currentState == true) {
Events::GamepadButtonDown e;
e.GamepadID = gamepadID;
e.Button = button;
m_EventBroker->Publish(e);
} else {
Events::GamepadButtonUp e;
e.GamepadID = gamepadID;
e.Button = button;
m_EventBroker->Publish(e);
}
}
//bool currentState = m_CurrentGamepadButtonState[gamepadID][static_cast<int>(button)];
//float lastState = m_LastGamepadButtonState[gamepadID][static_cast<int>(button)];
//if (currentState != lastState) {
// if (currentState == true) {
// Events::GamepadButtonDown e;
// e.GamepadID = gamepadID;
// e.Button = button;
// m_EventBroker->Publish(e);
// } else {
// Events::GamepadButtonUp e;
// e.GamepadID = gamepadID;
// e.Button = button;
// m_EventBroker->Publish(e);
// }
//}
}
bool InputManager::OnLockMouse(const Events::LockMouse &event)
+112
View File
@@ -0,0 +1,112 @@
#include "Input/InputProxy.h"
#include "Input/InputHandler.h"
InputProxy::InputProxy(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{
EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin);
}
InputProxy::~InputProxy()
{
for (auto& handler : m_Handlers) {
delete handler;
}
}
void InputProxy::LoadBindings(std::string file)
{
auto config = ResourceManager::Load<ConfigFile>(file);
for (auto& origin : config->GetAll<std::string>("Bindings")) {
Events::BindOrigin e;
e.Origin = origin.first;
e.Command = origin.second;
e.Value = 1.f;
if (!e.Command.empty()) {
char prefix = e.Command.at(0);
if (prefix == '+' || prefix == '-') {
e.Command = e.Command.substr(1);
if (prefix == '-') {
e.Value *= -1.f;
}
}
OnBindOrigin(e);
}
}
}
void InputProxy::Update(double dt)
{
m_EventBroker->Process<InputProxy>();
m_EventBroker->Process<InputHandler>();
for (auto& handler : m_Handlers) {
handler->Update(dt);
}
}
void InputProxy::Process()
{
for (auto& pair : m_CommandHandlers) {
const std::string& command = pair.first;
auto handlers = pair.second;
m_CurrentCommandValues[command] = 0.f;
for (auto& handler : handlers) {
m_CurrentCommandValues[command] += handler->GetCommandValue(command);
}
auto last = m_LastCommandValues.find(command);
float currentValue = m_CurrentCommandValues[command];
if (last == m_LastCommandValues.end() || last->second != currentValue) {
Events::InputCommand e;
e.PlayerID = -1;
e.Command = command;
e.Value = currentValue;
m_EventBroker->Publish(e);
LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
m_LastCommandValues[command] = currentValue;
}
}
// Accumulate the input values of all unique commands published by input handlers
for (auto& pair : m_CommandQueue) {
Events::InputCommand e;
e.PlayerID = pair.first.first;
e.Command = pair.first.second;
e.Value = 0;
for (auto& value : pair.second) {
e.Value += value;
}
//e.Value = std::max(-1.f, std::min(e.Value, 1.f));
m_EventBroker->Publish(e);
LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
}
m_CommandQueue.clear();
}
void InputProxy::Publish(const Events::InputCommand& e)
{
auto key = std::make_pair(e.PlayerID, e.Command);
m_CommandQueue[key].push_back(e.Value);
}
bool InputProxy::OnBindOrigin(const Events::BindOrigin& e)
{
bool originBound = false;
for (auto& handler : m_Handlers) {
bool result = handler->BindOrigin(e.Origin, e.Command, e.Value);
if (result) {
m_CommandHandlers[e.Command].insert(handler);
m_LastCommandValues[e.Command] = 0.f;
if (originBound) {
LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str());
}
originBound = true;
}
}
if (!originBound) {
LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str());
}
return originBound;
}
-221
View File
@@ -1,221 +0,0 @@
#include "PrecompiledHeader.h"
#include "Input/InputSystem.h"
#include "Core/World.h"
void Systems::InputSystem::RegisterComponents(ComponentFactory* cf)
{
}
void Systems::InputSystem::Initialize()
{
// Subscribe to events
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Systems::InputSystem::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::InputSystem::OnKeyUp);
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Systems::InputSystem::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Systems::InputSystem::OnMouseRelease);
EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &Systems::InputSystem::OnGamepadAxis);
EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &Systems::InputSystem::OnGamepadButtonDown);
EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &Systems::InputSystem::OnGamepadButtonUp);
EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &Systems::InputSystem::OnBindKey);
EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &Systems::InputSystem::OnBindMouseButton);
EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &Systems::InputSystem::OnBindGamepadAxis);
EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &Systems::InputSystem::OnBindGamepadButton);
}
void Systems::InputSystem::Update(double dt)
{
}
bool Systems::InputSystem::OnKeyDown(const Events::KeyDown &event)
{
auto range = m_KeyBindings.equal_range(event.KeyCode);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandKeyboardValues[command][event.KeyCode] = value;
PublishCommand(1, command, GetCommandTotalValue(command));
}
return true;
}
bool Systems::InputSystem::OnKeyUp(const Events::KeyUp &event)
{
auto range = m_KeyBindings.equal_range(event.KeyCode);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandKeyboardValues[command][event.KeyCode] = 0;
PublishCommand(1, command, GetCommandTotalValue(command));;
}
return true;
}
bool Systems::InputSystem::OnMousePress(const Events::MousePress &event)
{
auto range = m_MouseButtonBindings.equal_range(event.Button);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandMouseButtonValues[command][event.Button] = value;
PublishCommand(1, command, GetCommandTotalValue(command));
}
return true;
}
bool Systems::InputSystem::OnMouseRelease(const Events::MouseRelease &event)
{
auto range = m_MouseButtonBindings.equal_range(event.Button);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandMouseButtonValues[command][event.Button] = 0;
PublishCommand(1, command, GetCommandTotalValue(command));
}
return true;
}
bool Systems::InputSystem::OnGamepadAxis(const Events::GamepadAxis &event)
{
auto range = m_GamepadAxisBindings.equal_range(event.Axis);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandGamepadAxisValues[command][event.Axis] = event.Value * value;
PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command));
}
return true;
}
bool Systems::InputSystem::OnGamepadButtonDown(const Events::GamepadButtonDown &event)
{
auto range = m_GamepadButtonBindings.equal_range(event.Button);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandGamepadButtonValues[command][event.Button] = value;
PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command));
}
return true;
}
bool Systems::InputSystem::OnGamepadButtonUp(const Events::GamepadButtonUp &event)
{
auto range = m_GamepadButtonBindings.equal_range(event.Button);
for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
std::string command;
float value;
std::tie(command, value) = bindingIt->second;
m_CommandGamepadButtonValues[command][event.Button] = 0;
PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command));
}
return true;
}
bool Systems::InputSystem::OnBindKey(const Events::BindKey &event)
{
if (event.Command.empty()) {
return false;
}
m_KeyBindings.insert(std::make_pair(event.KeyCode, std::make_tuple(event.Command, event.Value)));
LOG_DEBUG("Input: Bound key %i to %s", event.KeyCode, event.Command.c_str());
return true;
}
bool Systems::InputSystem::OnBindMouseButton(const Events::BindMouseButton &event)
{
if (event.Command.empty()) {
return false;
}
m_MouseButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value)));
LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str());
return true;
}
bool Systems::InputSystem::OnBindGamepadAxis(const Events::BindGamepadAxis &event)
{
if (event.Command.empty()) {
return false;
}
m_GamepadAxisBindings.insert(std::make_pair(event.Axis, std::make_tuple(event.Command, event.Value)));
LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str());
return true;
}
bool Systems::InputSystem::OnBindGamepadButton(const Events::BindGamepadButton &event)
{
if (event.Command.empty()) {
return false;
}
m_GamepadButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value)));
LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str());
return true;
}
float Systems::InputSystem::GetCommandTotalValue(std::string command)
{
float value = 0.f;
auto keyboardIt = m_CommandKeyboardValues.find(command);
if (keyboardIt != m_CommandKeyboardValues.end()) {
for (auto &key : keyboardIt->second) {
value += key.second;
}
}
auto mouseButtonIt = m_CommandMouseButtonValues.find(command);
if (mouseButtonIt != m_CommandMouseButtonValues.end()) {
for (auto &button : mouseButtonIt->second) {
value += button.second;
}
}
auto gamepadAxisIt = m_CommandGamepadAxisValues.find(command);
if (gamepadAxisIt != m_CommandGamepadAxisValues.end()) {
for (auto &axis : gamepadAxisIt->second) {
value += axis.second;
}
}
auto gamepadButtonIt = m_CommandGamepadButtonValues.find(command);
if (gamepadButtonIt != m_CommandGamepadButtonValues.end()) {
for (auto &button : gamepadButtonIt->second) {
value += button.second;
}
}
return std::max(-1.f, std::min(value, 1.f));
}
void Systems::InputSystem::PublishCommand(int playerID, std::string command, float value)
{
Events::InputCommand e;
e.PlayerID = playerID;
e.Command = command;
e.Value = value;
EventBroker->Publish(e);
LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID);
}
+181
View File
@@ -0,0 +1,181 @@
#include "Input/KeyboardInputHandler.h"
KeyboardInputHandler::KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) : InputHandler(eventBroker, inputProxy)
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp);
m_OriginKeyCodes["Space"] = GLFW_KEY_SPACE;
m_OriginKeyCodes["Apostrophe"] = GLFW_KEY_APOSTROPHE;
m_OriginKeyCodes["Comma"] = GLFW_KEY_COMMA;
m_OriginKeyCodes["Minus"] = GLFW_KEY_MINUS;
m_OriginKeyCodes["Period"] = GLFW_KEY_PERIOD;
m_OriginKeyCodes["Slash"] = GLFW_KEY_SLASH;
m_OriginKeyCodes["0"] = GLFW_KEY_0;
m_OriginKeyCodes["1"] = GLFW_KEY_1;
m_OriginKeyCodes["2"] = GLFW_KEY_2;
m_OriginKeyCodes["3"] = GLFW_KEY_3;
m_OriginKeyCodes["4"] = GLFW_KEY_4;
m_OriginKeyCodes["5"] = GLFW_KEY_5;
m_OriginKeyCodes["6"] = GLFW_KEY_6;
m_OriginKeyCodes["7"] = GLFW_KEY_7;
m_OriginKeyCodes["8"] = GLFW_KEY_8;
m_OriginKeyCodes["9"] = GLFW_KEY_9;
m_OriginKeyCodes["Semicolon"] = GLFW_KEY_SEMICOLON;
m_OriginKeyCodes["Equal"] = GLFW_KEY_EQUAL;
m_OriginKeyCodes["A"] = GLFW_KEY_A;
m_OriginKeyCodes["B"] = GLFW_KEY_B;
m_OriginKeyCodes["C"] = GLFW_KEY_C;
m_OriginKeyCodes["D"] = GLFW_KEY_D;
m_OriginKeyCodes["E"] = GLFW_KEY_E;
m_OriginKeyCodes["F"] = GLFW_KEY_F;
m_OriginKeyCodes["G"] = GLFW_KEY_G;
m_OriginKeyCodes["H"] = GLFW_KEY_H;
m_OriginKeyCodes["I"] = GLFW_KEY_I;
m_OriginKeyCodes["J"] = GLFW_KEY_J;
m_OriginKeyCodes["K"] = GLFW_KEY_K;
m_OriginKeyCodes["L"] = GLFW_KEY_L;
m_OriginKeyCodes["M"] = GLFW_KEY_M;
m_OriginKeyCodes["N"] = GLFW_KEY_N;
m_OriginKeyCodes["O"] = GLFW_KEY_O;
m_OriginKeyCodes["P"] = GLFW_KEY_P;
m_OriginKeyCodes["Q"] = GLFW_KEY_Q;
m_OriginKeyCodes["R"] = GLFW_KEY_R;
m_OriginKeyCodes["S"] = GLFW_KEY_S;
m_OriginKeyCodes["T"] = GLFW_KEY_T;
m_OriginKeyCodes["U"] = GLFW_KEY_U;
m_OriginKeyCodes["V"] = GLFW_KEY_V;
m_OriginKeyCodes["W"] = GLFW_KEY_W;
m_OriginKeyCodes["X"] = GLFW_KEY_X;
m_OriginKeyCodes["Y"] = GLFW_KEY_Y;
m_OriginKeyCodes["Z"] = GLFW_KEY_Z;
m_OriginKeyCodes["LeftBracket"] = GLFW_KEY_LEFT_BRACKET;
m_OriginKeyCodes["Backslash"] = GLFW_KEY_BACKSLASH;
m_OriginKeyCodes["RightBracket"] = GLFW_KEY_RIGHT_BRACKET;
m_OriginKeyCodes["Accent"] = GLFW_KEY_GRAVE_ACCENT;
m_OriginKeyCodes["W1"] = GLFW_KEY_WORLD_1;
m_OriginKeyCodes["W2"] = GLFW_KEY_WORLD_2;
m_OriginKeyCodes["Escape"] = GLFW_KEY_ESCAPE;
m_OriginKeyCodes["Enter"] = GLFW_KEY_ENTER;
m_OriginKeyCodes["Tab"] = GLFW_KEY_TAB;
m_OriginKeyCodes["Backspace"] = GLFW_KEY_BACKSPACE;
m_OriginKeyCodes["Insert"] = GLFW_KEY_INSERT;
m_OriginKeyCodes["Delete"] = GLFW_KEY_DELETE;
m_OriginKeyCodes["Right"] = GLFW_KEY_RIGHT;
m_OriginKeyCodes["Left"] = GLFW_KEY_LEFT;
m_OriginKeyCodes["Down"] = GLFW_KEY_DOWN;
m_OriginKeyCodes["Up"] = GLFW_KEY_UP;
m_OriginKeyCodes["PgUp"] = GLFW_KEY_PAGE_UP;
m_OriginKeyCodes["PgDn"] = GLFW_KEY_PAGE_DOWN;
m_OriginKeyCodes["Home"] = GLFW_KEY_HOME;
m_OriginKeyCodes["End"] = GLFW_KEY_END;
m_OriginKeyCodes["CapsLock"] = GLFW_KEY_CAPS_LOCK;
m_OriginKeyCodes["ScrollLock"] = GLFW_KEY_SCROLL_LOCK;
m_OriginKeyCodes["NumLock"] = GLFW_KEY_NUM_LOCK;
m_OriginKeyCodes["PrintScreen"] = GLFW_KEY_PRINT_SCREEN;
m_OriginKeyCodes["Pause"] = GLFW_KEY_PAUSE;
m_OriginKeyCodes["F1"] = GLFW_KEY_F1;
m_OriginKeyCodes["F2"] = GLFW_KEY_F2;
m_OriginKeyCodes["F3"] = GLFW_KEY_F3;
m_OriginKeyCodes["F4"] = GLFW_KEY_F4;
m_OriginKeyCodes["F5"] = GLFW_KEY_F5;
m_OriginKeyCodes["F6"] = GLFW_KEY_F6;
m_OriginKeyCodes["F7"] = GLFW_KEY_F7;
m_OriginKeyCodes["F8"] = GLFW_KEY_F8;
m_OriginKeyCodes["F9"] = GLFW_KEY_F9;
m_OriginKeyCodes["F10"] = GLFW_KEY_F10;
m_OriginKeyCodes["F11"] = GLFW_KEY_F11;
m_OriginKeyCodes["F12"] = GLFW_KEY_F12;
m_OriginKeyCodes["F13"] = GLFW_KEY_F13;
m_OriginKeyCodes["F14"] = GLFW_KEY_F14;
m_OriginKeyCodes["F15"] = GLFW_KEY_F15;
m_OriginKeyCodes["F16"] = GLFW_KEY_F16;
m_OriginKeyCodes["F17"] = GLFW_KEY_F17;
m_OriginKeyCodes["F18"] = GLFW_KEY_F18;
m_OriginKeyCodes["F19"] = GLFW_KEY_F19;
m_OriginKeyCodes["F20"] = GLFW_KEY_F20;
m_OriginKeyCodes["F21"] = GLFW_KEY_F21;
m_OriginKeyCodes["F22"] = GLFW_KEY_F22;
m_OriginKeyCodes["F23"] = GLFW_KEY_F23;
m_OriginKeyCodes["F24"] = GLFW_KEY_F24;
m_OriginKeyCodes["F25"] = GLFW_KEY_F25;
m_OriginKeyCodes["KP0"] = GLFW_KEY_KP_0;
m_OriginKeyCodes["KP1"] = GLFW_KEY_KP_1;
m_OriginKeyCodes["KP2"] = GLFW_KEY_KP_2;
m_OriginKeyCodes["KP3"] = GLFW_KEY_KP_3;
m_OriginKeyCodes["KP4"] = GLFW_KEY_KP_4;
m_OriginKeyCodes["KP5"] = GLFW_KEY_KP_5;
m_OriginKeyCodes["KP6"] = GLFW_KEY_KP_6;
m_OriginKeyCodes["KP7"] = GLFW_KEY_KP_7;
m_OriginKeyCodes["KP8"] = GLFW_KEY_KP_8;
m_OriginKeyCodes["KP9"] = GLFW_KEY_KP_9;
m_OriginKeyCodes["KPDecimal"] = GLFW_KEY_KP_DECIMAL;
m_OriginKeyCodes["KPDivide"] = GLFW_KEY_KP_DIVIDE;
m_OriginKeyCodes["KPMultiply"] = GLFW_KEY_KP_MULTIPLY;
m_OriginKeyCodes["KPSubtract"] = GLFW_KEY_KP_SUBTRACT;
m_OriginKeyCodes["KPAdd"] = GLFW_KEY_KP_ADD;
m_OriginKeyCodes["KPEnter"] = GLFW_KEY_KP_ENTER;
m_OriginKeyCodes["KPEqual"] = GLFW_KEY_KP_EQUAL;
m_OriginKeyCodes["LeftShift"] = GLFW_KEY_LEFT_SHIFT;
m_OriginKeyCodes["LeftControl"] = GLFW_KEY_LEFT_CONTROL;
m_OriginKeyCodes["LeftAlt"] = GLFW_KEY_LEFT_ALT;
m_OriginKeyCodes["LeftSuper"] = GLFW_KEY_LEFT_SUPER;
m_OriginKeyCodes["RightShift"] = GLFW_KEY_RIGHT_SHIFT;
m_OriginKeyCodes["RightControl"] = GLFW_KEY_RIGHT_CONTROL;
m_OriginKeyCodes["RightAlt"] = GLFW_KEY_RIGHT_ALT;
m_OriginKeyCodes["RightSuper"] = GLFW_KEY_RIGHT_SUPER;
m_OriginKeyCodes["Menu"] = GLFW_KEY_MENU;
}
bool KeyboardInputHandler::BindOrigin(std::string origin, std::string command, float value)
{
auto originIt = m_OriginKeyCodes.find(origin);
if (originIt == m_OriginKeyCodes.end()) {
return false;
}
int keyCode = originIt->second;
m_KeyBindings[keyCode] = std::make_tuple(command, value);
return true;
}
bool KeyboardInputHandler::OnKeyDown(const Events::KeyDown& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
std::string command;
float value;
std::tie(command, value) = it->second;
m_CommandValues[command] += value;
return true;
}
bool KeyboardInputHandler::OnKeyUp(const Events::KeyUp& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
std::string command;
float value;
std::tie(command, value) = it->second;
m_CommandValues[command] -= value;
return true;
}
float KeyboardInputHandler::GetCommandValue(std::string command)
{
auto it = m_CommandValues.find(command);
if (it != m_CommandValues.end()) {
return m_CommandValues[command];
} else {
return 0.f;
}
}
+131
View File
@@ -0,0 +1,131 @@
#include "Input/MouseInputHandler.h"
MouseInputHandler::MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: InputHandler(eventBroker, inputProxy)
{
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &MouseInputHandler::OnMousePress);
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &MouseInputHandler::OnMouseRelease);
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &MouseInputHandler::OnMouseMove);
m_OriginCodes["Mouse1"] = GLFW_MOUSE_BUTTON_1;
m_OriginCodes["MouseLeft"] = GLFW_MOUSE_BUTTON_LEFT;
m_OriginCodes["Mouse2"] = GLFW_MOUSE_BUTTON_2;
m_OriginCodes["MouseRight"] = GLFW_MOUSE_BUTTON_RIGHT;
m_OriginCodes["Mouse3"] = GLFW_MOUSE_BUTTON_3;
m_OriginCodes["MouseMiddle"] = GLFW_MOUSE_BUTTON_MIDDLE;
m_OriginCodes["Mouse4"] = GLFW_MOUSE_BUTTON_4;
m_OriginCodes["Mouse5"] = GLFW_MOUSE_BUTTON_5;
m_OriginCodes["Mouse6"] = GLFW_MOUSE_BUTTON_6;
m_OriginCodes["Mouse7"] = GLFW_MOUSE_BUTTON_7;
m_OriginCodes["Mouse8"] = GLFW_MOUSE_BUTTON_8;
m_OriginAxes["MouseX"] = 'X';
m_OriginAxes["MouseY"] = 'Y';
}
bool MouseInputHandler::BindOrigin(std::string origin, std::string command, float value)
{
bool result = false;
auto originCode = m_OriginCodes.find(origin);
if (originCode != m_OriginCodes.end()) {
int code = originCode->second;
m_Bindings[code] = std::make_tuple(command, value);
result = true;
}
auto originAxis = m_OriginAxes.find(origin);
if (originAxis != m_OriginAxes.end()) {
char axis = originAxis->second;
float multiplier = 1.f;
// Sensitivity
multiplier *= ResourceManager::Load<ConfigFile>("Input.ini")->Get<float>("Mouse.Sensitivity", 1.f);
if (axis == 'Y') {
if (ResourceManager::Load<ConfigFile>("Input.ini")->Get<bool>("Mouse.InvertPitch", false)) {
multiplier *= -1.f;
}
}
m_Axes[axis] = std::make_tuple(command, value * multiplier);
result = true;
}
return result;
}
float MouseInputHandler::GetCommandValue(std::string command)
{
auto it = m_CommandValues.find(command);
if (it != m_CommandValues.end()) {
return m_CommandValues[command];
} else {
return 0.f;
}
}
bool MouseInputHandler::OnMousePress(const Events::MousePress& e)
{
auto it = m_Bindings.find(e.Button);
if (it == m_Bindings.end()) {
return false;
}
std::string command;
float value;
std::tie(command, value) = it->second;
m_CommandValues[command] += value;
return true;
}
bool MouseInputHandler::OnMouseRelease(const Events::MouseRelease& e)
{
auto it = m_Bindings.find(e.Button);
if (it == m_Bindings.end()) {
return false;
}
std::string command;
float value;
std::tie(command, value) = it->second;
m_CommandValues[command] -= value;
return true;
}
bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e)
{
if (std::abs(e.DeltaX) > 0) {
auto it = m_Axes.find('X');
if (it != m_Axes.end()) {
Events::InputCommand ic;
ic.PlayerID = -1;
std::tie(ic.Command, ic.Value) = it->second;
ic.Value *= e.DeltaX;
m_InputProxy->Publish(ic);
}
}
if (std::abs(e.DeltaY) > 0) {
auto it = m_Axes.find('Y');
if (it != m_Axes.end()) {
Events::InputCommand ic;
ic.PlayerID = -1;
std::tie(ic.Command, ic.Value) = it->second;
ic.Value *= e.DeltaY;
m_InputProxy->Publish(ic);
}
}
return true;
}
bool MouseInputHandler::hasOrigin(std::string origin)
{
if (m_OriginCodes.find(origin) == m_OriginCodes.end()) {
return false;
}
if (m_OriginAxes.find(origin) == m_OriginAxes.end()) {
return false;
}
return true;
}
@@ -0,0 +1,187 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Xinput.h>
#pragma comment(lib, "Xinput.lib")
#pragma comment(lib, "Xinput9_1_0.lib")
#include "Input/XboxControllerInputHandler.h"
XboxControllerInputHandler::XboxControllerInputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
: InputHandler(eventBroker, inputProxy)
{
m_OriginButtons["GamepadUp"] = XINPUT_GAMEPAD_DPAD_UP;
m_OriginButtons["GamepadDown"] = XINPUT_GAMEPAD_DPAD_DOWN;
m_OriginButtons["GamepadLeft"] = XINPUT_GAMEPAD_DPAD_LEFT;
m_OriginButtons["GamepadRight"] = XINPUT_GAMEPAD_DPAD_RIGHT;
m_OriginButtons["GamepadStart"] = XINPUT_GAMEPAD_START;
m_OriginButtons["GamepadBack"] = XINPUT_GAMEPAD_BACK;
m_OriginButtons["GamepadLeftStick"] = XINPUT_GAMEPAD_LEFT_THUMB;
m_OriginButtons["GamepadRightStick"] = XINPUT_GAMEPAD_RIGHT_THUMB;
m_OriginButtons["GamepadLeftBumper"] = XINPUT_GAMEPAD_LEFT_SHOULDER;
m_OriginButtons["GamepadRightBumper"] = XINPUT_GAMEPAD_RIGHT_SHOULDER;
m_OriginButtons["GamepadA"] = XINPUT_GAMEPAD_A;
m_OriginButtons["GamepadB"] = XINPUT_GAMEPAD_B;
m_OriginButtons["GamepadX"] = XINPUT_GAMEPAD_X;
m_OriginButtons["GamepadY"] = XINPUT_GAMEPAD_Y;
m_OriginAxes["GamepadLeftX"] = 0;
m_OriginAxes["GamepadLeftY"] = 1;
m_OriginAxes["GamepadRightX"] = 2;
m_OriginAxes["GamepadRightY"] = 3;
m_OriginAxes["GamepadLeftTrigger"] = 4;
m_OriginAxes["GamepadRightTrigger"] = 5;
}
bool XboxControllerInputHandler::BindOrigin(std::string origin, std::string command, float value)
{
bool result = false;
auto originIt = m_OriginButtons.find(origin);
if (originIt != m_OriginButtons.end()) {
int button = originIt->second;
m_ButtonBindings[button] = std::make_tuple(command, value);
result = true;
}
auto originAxis = m_OriginAxes.find(origin);
if (originAxis != m_OriginAxes.end()) {
char axis = originAxis->second;
float multiplier = 0.5f;
//// Sensitivity
//multiplier *= ResourceManager::Load<ConfigFile>("Input.ini")->Get<float>("Mouse.Sensitivity", 1.f);
//if (axis == 'Y') {
// if (ResourceManager::Load<ConfigFile>("Input.ini")->Get<bool>("Mouse.InvertPitch", false)) {
// multiplier *= -1.f;
// }
//}
m_AxisBindings[axis] = std::make_tuple(command, value * multiplier);
result = true;
}
return result;
}
void XboxControllerInputHandler::Update(double dt)
{
DWORD dwResult;
for (int i = 0; i < MAX_GAMEPADS; i++) {
XINPUT_STATE state = { 0 };
// Simply get the state of the controller from XInput.
dwResult = XInputGetState(i, &state);
if (dwResult == 0) {
if (std::abs(state.Gamepad.sThumbLX) <= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
state.Gamepad.sThumbLX = 0;
if (std::abs(state.Gamepad.sThumbLY) <= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
state.Gamepad.sThumbLY = 0;
if (std::abs(state.Gamepad.sThumbRX) <= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
state.Gamepad.sThumbRX = 0;
if (std::abs(state.Gamepad.sThumbRY) <= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
state.Gamepad.sThumbRY = 0;
if (std::abs(state.Gamepad.bLeftTrigger) <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
state.Gamepad.bLeftTrigger = 0;
if (std::abs(state.Gamepad.bRightTrigger) <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
state.Gamepad.bRightTrigger = 0;
//m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftX)] = state.Gamepad.sThumbLX / 32767.f;
//m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftY)] = state.Gamepad.sThumbLY / 32767.f;
//m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightX)] = state.Gamepad.sThumbRX / 32767.f;
//m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightY)] = state.Gamepad.sThumbRY / 32767.f;
//m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::LeftTrigger)] = state.Gamepad.bLeftTrigger / 255.f;
//m_CurrentGamepadAxisState[i][static_cast<int>(Gamepad::Axis::RightTrigger)] = state.Gamepad.bRightTrigger / 255.f;
//PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftX);
//PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftY);
//PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightX);
//PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightY);
//PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftTrigger);
//PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightTrigger);
for (auto& pair : m_OriginAxes) {
const std::string& origin = pair.first;
int axis = pair.second;
auto& binding = m_AxisBindings.find(axis);
if (binding == m_AxisBindings.end()) {
continue;
}
std::string command;
float value;
std::tie(command, value) = binding->second;
Events::InputCommand e;
e.PlayerID = -1;
e.Command = command;
e.Value = value * getAxisValue(state, axis);
m_InputProxy->Publish(e);
}
for (auto& pair : m_OriginButtons) {
auto& binding = m_ButtonBindings.find(pair.second);
if (binding == m_ButtonBindings.end()) {
continue;
}
std::string command;
float value;
std::tie(command, value) = binding->second;
bool pressed = static_cast<bool>(state.Gamepad.wButtons & binding->first);
m_CommandValues[command] = (pressed) ? value : 0.f;
}
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Up)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Down)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Left)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Right)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Start)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_START);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Back)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::LeftThumb)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::RightThumb)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::LeftShoulder)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::RightShoulder)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::A)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_A);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::B)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_B);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::X)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_X);
//m_CurrentGamepadButtonState[i][static_cast<int>(Gamepad::Button::Y)] = static_cast<bool>(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Up);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Down);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Left);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Right);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Start);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Back);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::LeftThumb);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::RightThumb);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::LeftShoulder);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::RightShoulder);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::A);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::B);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::X);
//PublishGamepadButtonIfChanged(i, Gamepad::Button::Y);
}
}
}
float XboxControllerInputHandler::GetCommandValue(std::string command)
{
auto it = m_CommandValues.find(command);
if (it != m_CommandValues.end()) {
return m_CommandValues[command];
} else {
return 0.f;
}
}
float XboxControllerInputHandler::getAxisValue(XINPUT_STATE& state, int axis)
{
switch (axis) {
case 0:
return state.Gamepad.sThumbLX / 32767.f;
case 1:
return state.Gamepad.sThumbLY / 32767.f;
case 2:
return state.Gamepad.sThumbRX / 32767.f;
case 3:
return state.Gamepad.sThumbRY / 32767.f;
case 4:
return state.Gamepad.bLeftTrigger / 255.f;
case 5:
return state.Gamepad.bRightTrigger / 255.f;
}
}
+1 -1
View File
@@ -30,7 +30,7 @@ glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
do {
ComponentWrapper transform = world->GetComponent(entity, "Transform");
position += AbsoluteOrientation(world, entity) * (glm::vec3)transform["Position"];
position += (glm::vec3)transform["Position"];
entity = world->GetParent(entity);
} while (entity != 0);
+6 -25
View File
@@ -1,4 +1,5 @@
#include "Rendering/Renderer.h"
#include "Rendering/DebugCameraInputController.h"
void Renderer::Initialize()
{
@@ -83,6 +84,8 @@ void Renderer::InitializeShaders()
void Renderer::InputUpdate(double dt)
{
static DebugCameraInputController<Renderer> firstPersonInputController(m_EventBroker, -1);
glm::vec3 m_Position = m_Camera->Position();
if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS)
{
@@ -112,37 +115,15 @@ void Renderer::InputUpdate(double dt)
m_CameraMoveSpeed = 0.5f;
}
static double mousePosX, mousePosY;
glfwGetCursorPos(m_Window, &mousePosX, &mousePosY);
if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) {
double deltaX, deltaY;
deltaX = mousePosX - (float)Resolution().Width / 2;
deltaY = mousePosY - (float)Resolution().Height / 2;
float rotationY = -deltaY / 300.f;
float rotationX = -deltaX / 300.f;
glm::quat orientation = m_Camera->Orientation();
orientation = orientation * glm::angleAxis<float>(rotationY, glm::vec3(1, 0, 0));
orientation = glm::angleAxis<float>(rotationX, glm::vec3(0, 1, 0)) * orientation;
m_Camera->SetOrientation(orientation);
glfwSetCursorPos(m_Window, Resolution().Width / 2, Resolution().Height / 2);
}
m_Camera->SetPosition(m_Position);
firstPersonInputController.Update(dt);
m_Camera->SetOrientation(firstPersonInputController.Orientation());
m_Camera->SetPosition(firstPersonInputController.Position());
}
void Renderer::Update(double dt)
{
m_EventBroker->Process<Renderer>();
InputUpdate(dt);
}
void Renderer::Draw(RenderQueueCollection& rq)
+1
View File
@@ -19,6 +19,7 @@ file(GLOB SOURCE_FILES
set(SOURCE_FILES
${SOURCE_FILES}
"Game.cpp"
"PlayerSystem.cpp"
)
set(LIBRARIES
+60 -45
View File
@@ -2,38 +2,43 @@
Game::Game(int argc, char* argv[])
{
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<Model>("Model");
ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<Model>("Model");
ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
// Create the core event broker
m_EventBroker = new EventBroker();
// Create the core event broker
m_EventBroker = new EventBroker();
m_RenderQueueFactory = new RenderQueueFactory();
// Create the renderer
m_Renderer = new Renderer(m_EventBroker);
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
m_Renderer->SetResolution(Rectangle(
0,
0,
m_Config->Get<int>("Video.Width", 1280),
m_Config->Get<int>("Video.Height", 720)
));
m_Renderer->Initialize();
// Create the renderer
m_Renderer = new Renderer(m_EventBroker);
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
m_Renderer->SetResolution(Rectangle(
0,
0,
m_Config->Get<int>("Video.Width", 1280),
m_Config->Get<int>("Video.Height", 720)
));
m_Renderer->Initialize();
// Create input manager
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
// Create input manager
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
m_InputProxy = new InputProxy(m_EventBroker);
m_InputProxy->AddHandler<KeyboardInputHandler>();
m_InputProxy->AddHandler<MouseInputHandler>();
m_InputProxy->AddHandler<XboxControllerInputHandler>();
m_InputProxy->LoadBindings("Input.ini");
// Create the root level GUI frame
m_FrameStack = new GUI::Frame(m_EventBroker);
m_FrameStack->Width = m_Renderer->Resolution().Width;
m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create the root level GUI frame
m_FrameStack = new GUI::Frame(m_EventBroker);
m_FrameStack->Width = m_Renderer->Resolution().Width;
m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create a world
m_World = new World();
@@ -41,50 +46,60 @@ Game::Game(int argc, char* argv[])
if (!mapToLoad.empty()) {
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
}
// Create system pipeline
m_SystemPipeline = new SystemPipeline(m_EventBroker);
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
m_SystemPipeline->AddSystem<PlayerSystem>();
m_LastTime = glfwGetTime();
testIntialize();
m_LastTime = glfwGetTime();
debugInitialize();
}
Game::~Game()
{
delete m_FrameStack;
delete m_EventBroker;
delete m_FrameStack;
delete m_EventBroker;
}
void Game::Tick()
{
double currentTime = glfwGetTime();
double dt = currentTime - m_LastTime;
m_LastTime = currentTime;
double currentTime = glfwGetTime();
double dt = currentTime - m_LastTime;
m_LastTime = currentTime;
m_EventBroker->Swap();
m_InputManager->Update(dt);
m_EventBroker->Swap();
// Handle input in a weird looking but responsive way
m_EventBroker->Process<InputManager>();
m_EventBroker->Swap();
m_InputManager->Update(dt);
m_EventBroker->Swap();
m_InputProxy->Update(dt);
m_EventBroker->Swap();
m_EventBroker->Clear();
m_InputProxy->Process();
m_EventBroker->Swap();
// Iterate through systems and update world!
m_SystemPipeline->Update(m_World, dt);
testTick(dt);
debugTick(dt);
m_Renderer->Update(dt);
m_RenderQueueFactory->Update(m_World);
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
m_EventBroker->Swap();
m_EventBroker->Clear();
m_EventBroker->Swap();
m_EventBroker->Clear();
glfwPollEvents();
glfwPollEvents();
}
bool Game::testOnKeyUp(const Events::KeyUp& e)
bool Game::debugOnInputCommand(const Events::InputCommand& e)
{
if (e.KeyCode == GLFW_KEY_R) {
if (e.Command == "DebugReload" && e.Value == 1) {
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) {
delete m_World;
@@ -97,12 +112,12 @@ bool Game::testOnKeyUp(const Events::KeyUp& e)
return false;
}
void Game::testIntialize()
void Game::debugInitialize()
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Game::testOnKeyUp);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand);
}
void Game::testTick(double dt)
void Game::debugTick(double dt)
{
m_EventBroker->Process<Game>();
}
+58
View File
@@ -0,0 +1,58 @@
#include "PlayerSystem.h"
void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt)
{
if (input.Forward) {
m_Direction.z = -1;
} else if (input.Back) {
m_Direction.z = 1;
} else {
m_Direction.z = 0;
}
if (input.Left) {
m_Direction.x = -1;
} else if (input.Right) {
m_Direction.x = 1;
} else {
m_Direction.x = 0;
}
m_EventBroker->Process<PlayerSystem>();
ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform");
(glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction;
(glm::vec3&)transform["Position"] += (glm::vec3)player["Velocity"];
}
bool PlayerSystem::OnKeyDown(const Events::KeyDown & event)
{
if (event.KeyCode == GLFW_KEY_W) {
input.Forward = true;
}
if (event.KeyCode == GLFW_KEY_A) {
input.Left = true;
}
if (event.KeyCode == GLFW_KEY_S) {
input.Back = true;
}
if (event.KeyCode == GLFW_KEY_D) {
input.Right = true;
}
return true;
}
bool PlayerSystem::OnKeyUp(const Events::KeyUp & event)
{
if (event.KeyCode == GLFW_KEY_W) {
input.Forward = false;
}
if (event.KeyCode == GLFW_KEY_A) {
input.Left = false;
}
if (event.KeyCode == GLFW_KEY_S) {
input.Back = false;
}
if (event.KeyCode == GLFW_KEY_D) {
input.Right = false;
}
return false;
}
+1
View File
@@ -21,6 +21,7 @@ RMDIR /S /Q "%DeployLocation%\Shaders"
MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J
:: Configuration files
MKLINK "%DeployLocation%\DefaultConfig.ini" "resources\DefaultConfig.ini" /H
MKLINK "%DeployLocation%\DefaultInput.ini" "resources\DefaultInput.ini" /H
:: Platform specific binaries
IF "%~1"=="" GOTO :EOF