joystick update, and improvement of keybinding handling

This commit is contained in:
Lendemor 2017-02-08 00:37:30 +01:00
parent bbf58d0104
commit afecb9596b
5 changed files with 220 additions and 144 deletions

@ -15,7 +15,7 @@ Input::Input(sf::Window *w) :
m_mouseGrabbed(false)
{
m_heldkeys = std::vector<sf::Keyboard::Key>();
m_actions = std::vector<int>();
m_actions = std::vector<Action>();
m_window->setKeyRepeatEnabled(false);
}
@ -43,93 +43,125 @@ void Input::updateEvents(){
kb = m_keybindings[m_current_context];
m_actions.clear();
int action;
Action action;
/*
sf::Joystick::X;
sf::Joystick::Y;
sf::Joystick::Z;
sf::Joystick::R;
sf::Joystick::U;
sf::Joystick::V;
sf::Joystick::PovX;
sf::Joystick::PovY;
*/
/* event-parsing loop */
/* event-parsing loop */
while(m_window->pollEvent(event))
{
// std::cout << event.type << std::endl;
switch(event.type){
case sf::Event::Closed:
m_closeRequested = true;
break;
case sf::Event::TextEntered:
c = (char) event.text.unicode;
sf::Utf32::encodeAnsi(event.text.unicode,std::back_inserter(m_buffer));
// std::cout << << std::endl;
// m_buffer.push_back('\u9190');
break;
case sf::Event::KeyPressed:
action = kb.getPressedAction(event.key.code);
if(action != -1)
m_actions.push_back(action);
m_heldkeys.push_back(event.key.code);
break;
case sf::Event::KeyReleased:
action = kb.getReleasedAction(event.key.code);
if(action != -1)
m_actions.push_back(action);
releaseHeldKeys(event.key.code);
break;
case sf::Event::MouseButtonPressed:
action = kb.getPressedAction(sf::Keyboard::KeyCount + event.mouseButton.button);
if(action != -1)
m_actions.push_back(action);
m_heldkeys.push_back((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button));
break;
case sf::Event::MouseButtonReleased:
action = kb.getReleasedAction(sf::Keyboard::KeyCount + event.mouseButton.button);
if(action != -1)
m_actions.push_back(action);
releaseHeldKeys((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button));
break;
case sf::Event::MouseWheelScrolled:
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
m_delta_vertical_scroll = event.mouseWheelScroll.delta;
break;
case sf::Event::MouseMoved:
m_mouse_position = sf::Mouse::getPosition(*m_window);
break;
case sf::Event::MouseEntered:
// action MouseEntered
break;
case sf::Event::MouseLeft:
//action MouseLeft
break;
case sf::Event::Resized:
m_hasBeenResized = true;
if(m_mouseGrabbed)
m_last_mouse_position = sf::Vector2i(m_window->getSize())/2;
break;
case sf::Event::Closed:
m_closeRequested = true;
break;
case sf::Event::Resized:
m_hasBeenResized = true;
if(m_mouseGrabbed)
m_last_mouse_position = sf::Vector2i(m_window->getSize())/2;
break;
case sf::Event::LostFocus:
case sf::Event::GainedFocus:
//Nothing to add here because the window already keep the state of the focus
break;
case sf::Event::TextEntered:
c = (char) event.text.unicode;
sf::Utf32::encodeAnsi(event.text.unicode,std::back_inserter(m_buffer));
break;
case sf::Event::KeyPressed:
action = kb.getPressedAction(input::KEYBOARD,event.key.code);
if(!action.isNull())
m_actions.push_back(action);
// m_heldkeys.push_back(event.key.code);
break;
case sf::Event::KeyReleased:
action = kb.getReleasedAction(input::KEYBOARD,event.key.code);
if(!action.isNull())
m_actions.push_back(action);
// releaseHeldKeys(event.key.code);
break;
case sf::Event::MouseWheelScrolled:
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
m_delta_vertical_scroll = event.mouseWheelScroll.delta;
break;
case sf::Event::MouseButtonPressed:
action = kb.getPressedAction(input::MOUSE,event.mouseButton.button);
if(!action.isNull())
m_actions.push_back(action);
// m_heldkeys.push_back((sf::Keyboard::Key) (event.mouseButton.button));
break;
case sf::Event::MouseButtonReleased:
action = kb.getReleasedAction(input::MOUSE,event.mouseButton.button);
if(!action.isNull())
m_actions.push_back(action);
// releaseHeldKeys((sf::Keyboard::Key) (event.mouseButton.button));
break;
case sf::Event::MouseMoved:
m_mouse_position = sf::Mouse::getPosition(*m_window);
break;
case sf::Event::MouseEntered:
// action MouseEntered
break;
case sf::Event::MouseLeft:
//action MouseLeft
break;
case sf::Event::JoystickButtonPressed:
action = kb.getPressedAction(input::CONTROLLER,event.joystickButton.button); // + idjoy * joystick::buttoncount
if(!action.isNull()){
action.controller_id = event.joystickButton.joystickId;
m_actions.push_back(action);
}
m_heldkeys.push_back((sf::Keyboard::Key) (event.joystickButton.button));
break;
case sf::Event::JoystickButtonReleased:
action = kb.getReleasedAction(input::CONTROLLER, event.joystickButton.button); // + idjoy * joystick::buttoncount
if(!action.isNull()){
action.controller_id = event.joystickButton.joystickId;
m_actions.push_back(action);
}
releaseHeldKeys((sf::Keyboard::Key) (event.joystickButton.button));
break;
case sf::Event::JoystickMoved:
// i'll handle that later
std::cout << "Joystick axis " << event.joystickMove.axis << " of controller " << event.joystickMove.joystickId << " moved at" << event.joystickMove.position << std::endl;
break;
case sf::Event::JoystickConnected:
{
sf::Joystick::Identification id = sf::Joystick::getIdentification(event.joystickConnect.joystickId);
std::cout << "Joystick "<< event.joystickConnect.joystickId << " connected :" << id.name.toAnsiString() << std::endl;
break;
}
case sf::Event::JoystickDisconnected:
{
sf::Joystick::Identification id = sf::Joystick::getIdentification(event.joystickConnect.joystickId);
std::cout << "Joystick "<< event.joystickConnect.joystickId << " disconnected :" << id.name.toAnsiString() << std::endl;
break;
}
}
}
if(m_mouseGrabbed)
sf::Mouse::setPosition(m_last_mouse_position, *m_window);
for (auto key: m_heldkeys)
{
m_actions.push_back(kb.getHoldAction(key));
// m_actions.push_back(kb.getHoldAction(key));
}
}
std::vector<int> Input::getActions()
std::vector<Action> Input::getActions()
{
return m_actions;
}
/* context-related functions */
//void Input::addContext(Context context)
//{
// m_contexts.push_back(context);
//}
//std::string Input::getCurrentContext()
//{
// return m_current_context;
//}
//void Input::setCurrentContext(std::string context_name){
// m_current_context = context_name;
//}
void Input::updateKeyBindings(){
m_keybindings.clear();
for (auto iter= m_contexts.begin(); iter != m_contexts.end(); ++iter)
@ -185,6 +217,11 @@ void Input::setMouseGrabbed(bool isGrabbed)
m_last_mouse_position = sf::Vector2i(m_window->getSize())/2;
}
float getAxisPosition(int device_id, int axis_id)
{
}
std::wstring Input::getText()
{
return m_buffer;
@ -194,12 +231,12 @@ std::wstring Input::getText()
void Input::test()
{
KeyBindings kb = m_keybindings[m_current_context];
/* KeyBindings kb = m_keybindings[m_current_context];
int action;
action = kb.getPressedAction(sf::Keyboard::I);
action = kb.getPressedAction(sf::Keyboard::I);
if (action != NO_ACTION)
std::cerr << action << std::endl;
action = kb.getPressedAction(sf::Keyboard::O);
if (action != NO_ACTION)
std::cerr << action << std::endl;
std::cerr << action << std::endl;*/
}

@ -20,7 +20,7 @@ private:
/* general action-mapping variables */
IKeysMap m_keysmap;
std::vector<int> m_actions;
std::vector<Action> m_actions;
int nb_actions;
/* context-related variables */
@ -47,10 +47,10 @@ public:
/* general action-mapping functions */
void setKeysMap(IKeysMap km); //set bindings
void updateEvents(); //handle the input and put the associated event in the file
std::vector<int> getActions(); //get the first action in the file of event
std::vector<Action> getActions(); //get the first action in the file of event
/* context-related functions */
void addContext(Context context){m_contexts.push_back(context);}
void addContext(Context context){m_contexts.push_back(context); updateKeyBindings();}
std::string getCurrentContext(){return m_current_context;}
void setCurrentContext(std::string context_name){m_current_context = context_name;}
void updateKeyBindings();

@ -15,13 +15,17 @@ IKeysMap::IKeysMap()
}
std::vector<Binding> IKeysMap::getBindings(int action) const {
std::vector<Binding> IKeysMap::getBindings(Action action) const {
std::vector<Binding> bindings;
for (auto binding : keys)
if (binding.action == action) bindings.push_back(binding);
if (binding.action.action == action.action) bindings.push_back(binding);
return bindings;
}
Action Action::getNull(){
return {NO_ACTION,input::NONE};
}
/* Implementation of KeyBindings class
* @author: Thomas Brandého
* @info: This class map a list of action with the associated keys, for a quick access in-game.
@ -34,7 +38,8 @@ KeyBindings::KeyBindings()
KeyBindings::KeyBindings(const Context &context, const IKeysMap &keysmap)
{
for (int action : context.getActions()){
init_map_bindings();
for (Action action : context.getActions()){
for (Binding binding : keysmap.getBindings(action)){
switch(binding.type){
case IKeysMap::PRESSED:
@ -55,75 +60,64 @@ KeyBindings::KeyBindings(const Context &context, const IKeysMap &keysmap)
}
int KeyBindings::getPressedAction(int key) const
Action KeyBindings::getPressedAction(input::Source src, int key) const
{
return bindings_pressed.count(key) == 1? bindings_pressed.at(key) : -1;
if (bindings_pressed.at(src).count(key))
return {bindings_pressed.at(src).at(key),src};
else
return Action::getNull();
}
int KeyBindings::getReleasedAction(int key) const
Action KeyBindings::getReleasedAction(input::Source src, int key) const
{
return bindings_released.count(key) == 1? bindings_released.at(key) : -1;
if(bindings_released.at(src).count(key))
return {bindings_released.at(src).at(key),src};
else
return Action::getNull();
}
int KeyBindings::getHoldAction(int key) const
Action KeyBindings::getHoldAction(input::Source src, int key) const
{
return bindings_hold.count(key) == 1? bindings_hold.at(key) : -1;
if(bindings_hold.at(src).count(key))
return {bindings_hold.at(src).at(key),src};
else
return Action::getNull();
}
void KeyBindings::setPressedAction(int key, int action)
void KeyBindings::setPressedAction(int key, Action action)
{
bindings_pressed[key]=action;
bindings_pressed[action.source][key]=action.action;
}
void KeyBindings::setReleasedAction(int key, int action)
void KeyBindings::setReleasedAction(int key, Action action)
{
bindings_released[key]=action;
bindings_released[action.source][key]=action.action;
}
void KeyBindings::setHoldAction(int key, int action)
void KeyBindings::setHoldAction(int key, Action action)
{
bindings_hold[key]=action;
bindings_hold[action.source][key]=action.action;
}
void KeyBindings::init_map_bindings(){
for(int i = 0; i < input::SOURCE_COUNT;i++){
bindings_pressed[i] = std::unordered_map<int,int>();
bindings_released[i] = std::unordered_map<int,int>();
bindings_hold[i] = std::unordered_map<int,int>();
}
}
/* Implementation of Context class
* @author: Thomas Brandého
* @info: This class contains a list of actions available in a given situation (context).
*/
Context::Context(std::string _name, std::vector<int> _actions): name(_name), actions(_actions)
Context::Context(std::string _name, std::vector<Action> _actions): name(_name), actions(_actions)
{
}
std::string Context::getName()
{
return name;
}
std::vector<int> Context::getActions() const
std::vector<Action> Context::getActions() const
{
return actions;
}

@ -12,47 +12,64 @@
#define NO_KEY -1
#define NO_ACTION -1
namespace input{
enum Source{NONE=-1,KEYBOARD,MOUSE,CONTROLLER,SOURCE_COUNT};
}
struct Action {
int action;
input::Source source;
int controller_id;
static Action getNull();
bool isNull(){
return (action == NO_ACTION) && (source == input::NONE);
}
friend bool operator ==(const Action& action1, const Action& action2){
return (action1.action == action2.action) && (action1.source == action2.source);
}
};
struct Binding{
int action;
Action action;
int key;
int type;
};
//write a function to add new Binding?
class IKeysMap{
public:
enum {PRESSED, RELEASED, HOLD};
IKeysMap();
std::vector<Binding> getBindings(int action) const;
std::vector<Binding> getBindings(Action action) const;
protected:
std::vector<Binding> keys;
};
class Context {
public:
Context(std::string name, std::vector<int> actions);
Context(std::string name, std::vector<Action> actions);
std::string getName();
std::vector<int> getActions() const;
std::vector<Action> getActions() const;
private:
std::string name;
std::vector<int> actions;
std::vector<Action> actions;
};
class KeyBindings {
public:
KeyBindings();
KeyBindings(const Context &context, const IKeysMap &keysmap);
int getPressedAction(int key) const;
int getReleasedAction(int key) const;
int getHoldAction(int key) const;
Action getPressedAction(input::Source src,int key) const;
Action getReleasedAction(input::Source src,int key) const;
Action getHoldAction(input::Source src,int key) const;
private:
std::unordered_map<int,int> bindings_pressed;
std::unordered_map<int,int> bindings_released;
std::unordered_map<int,int> bindings_hold;
void setPressedAction(int key, int action);
void setReleasedAction(int key, int action);
void setHoldAction(int key, int action);
std::unordered_map<int,std::unordered_map<int,int>> bindings_pressed;
std::unordered_map<int,std::unordered_map<int,int>> bindings_released;
std::unordered_map<int,std::unordered_map<int,int>> bindings_hold;
void setPressedAction(int key, Action action);
void setReleasedAction(int key, Action action);
void setHoldAction(int key, Action action);
void init_map_bindings();
};
#endif

@ -1,23 +1,51 @@
#include <iostream>
#include <SFML/Window.hpp>
#include "input.h"
//#include "keybindings.h"
using namespace std;
class TestKeysMap : public IKeysMap {
public:
enum{LEFT_CLICK,RIGHT_CLICK,MIDDLE_CLICK,ACTION};
TestKeysMap(){
keys.push_back ({{LEFT_CLICK,input::MOUSE},sf::Mouse::Left,PRESSED} );
keys.push_back ({{RIGHT_CLICK,input::MOUSE},sf::Mouse::Right,PRESSED} );
keys.push_back ({{ACTION,input::CONTROLLER},sf::Joystick::X,PRESSED} );
}
static std::vector<Action> getTestContext()
{
return
{
{LEFT_CLICK,input::MOUSE},
{RIGHT_CLICK,input::MOUSE},
{ACTION,input::CONTROLLER}
};
}
};
int main()
{
cerr << "Hello World!"<< endl;
sf::Window* window= new sf::Window(sf::VideoMode(400,200),"testSparrowInput");
Input myInput(window);
enum {ACTION_1,ACTION_2};
std::vector<int> myvector;
myvector.push_back(ACTION_1);
myvector.push_back(ACTION_2);
while(!myInput.isCloseRequested())
myInput.updateEvents();
// IKeysMap* keymap = new IKeysMap("test", 1);
Context context = Context("test",TestKeysMap::getTestContext());
myInput.setKeysMap(TestKeysMap());
myInput.addContext(context);
myInput.setCurrentContext("test");
while(!myInput.isCloseRequested())
{
myInput.updateEvents();
for (Action action : myInput.getActions())
{
if (action.action == TestKeysMap::ACTION)
std::cout << "Plop" << action.source << std::endl;
}
}
/* IKeysMap* keymap = new IKeysMap("test", 1);
// keymap->setKeyBinding(ACTION_2,0,sf::Keyboard::Z);
// keymap->setTypeAction(ACTION_2,KeysMap::RELEASED);
@ -51,7 +79,7 @@ int main()
// while (action = myInput.getAction() != NO_ACTION)
// cout << "test " << action << endl;
// window->display();
// }
// }*/
cerr << "Successfully ended" << endl;
return 0;
}