diff --git a/CMakeLists.txt b/CMakeLists.txt index 86d745b..5305963 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ else(WIN32) set(SYSTEM_LIB_PATH "linux") endif(WIN32) -set(LIB_SRC_LIST input.cpp keybindings.cpp) +set(LIB_SRC_LIST input.cpp keybindings.cpp textbuffer.cpp) set(EXECUTABLE_NAME "test${PROJECT_NAME}") set(LIBRARY_NAME ${PROJECT_NAME}) diff --git a/input.cpp b/input.cpp index ed37585..b59d561 100644 --- a/input.cpp +++ b/input.cpp @@ -4,14 +4,22 @@ #include "input.h" +#include #include +#include Input::Input(sf::Window* w, std::string keysmappings, int nb_actions): window(w) { keysmap= KeysMap(keysmappings, nb_actions); -// action_file = std::queue(); -// keysmap = KeysMap(false); -// context_maps.push_back(new Context()); + heldkeys = std::vector(); + action_file = std::queue(); + window->setKeyRepeatEnabled(false); + /* test */ + std::vector mv; + mv.push_back(0); + current_context = "default"; + keybindings[current_context] = KeyBindings(mv,&keysmap); +// std::cerr << keybindings[current_context].getPressedAction(sf::Keyboard::I) << std::endl; } int Input::getKeyBinding(int action,int num){ @@ -22,35 +30,149 @@ void Input::setkeyBinding(int action, int num, sf::Keyboard::Key key){ keysmap.setKeyBinding(action,num-1,key); } +void Input::setTypeAction(int action, int type) +{ + keysmap.setTypeAction(action, type); +} + +void Input::createContext(std::string context_name, std::vector action_list) +{ + contexts[context_name]=action_list; +} + +void Input::setCurrentContext(std::string context_name){ + current_context = context_name; +} + + +void Input::reloadKeyBindings(){ + for (auto iter= keybindings.begin(); iter != keybindings.end(); ++iter){ + iter->second= KeyBindings(contexts[iter->first],&keysmap); + } +} -/* void Input::updateEvents(){ sf::Event event; - //WARNING : may cause lag if continuously fed with event? + KeyBindings kb; + + /* TEST ------------------------------------------------- */ + +// for(auto iter= kb.bindings_hold.begin(); iter != kb.bindings_hold.end(); ++iter){ +// std::cerr << iter->second << std::endl; +// } + + /* ------------------------------------------------------- */ + + /* reset variables */ + closeRequested = false; + + /* global affectation */ + kb = keybindings[current_context]; + + /* event-parsing loop */ while(window->pollEvent(event)){ - if (event.type == sf::Event::KeyPressed){ - switch(event.KeyPressed){ - // handle keypressed - default: + switch(event.type){ + case sf::Event::Closed: + closeRequested = true; break; - } - }else{ - //handle other kind of event + case sf::Event::TextEntered: + // add text entered to buffer + break; + case sf::Event::KeyPressed: + action_file.push(kb.getPressedAction(event.key.code)); + heldkeys.push_back(event.key.code); + break; + case sf::Event::KeyReleased: + action_file.push(kb.getReleasedAction(event.key.code)); + releaseHeldKeys(event.key.code); + break; + case sf::Event::MouseButtonPressed: + action_file.push(kb.getPressedAction(sf::Keyboard::KeyCount + event.mouseButton.button)); + heldkeys.push_back((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button)); + break; + case sf::Event::MouseButtonReleased: + action_file.push(kb.getReleasedAction(sf::Keyboard::KeyCount + event.mouseButton.button)); + releaseHeldKeys((sf::Keyboard::Key) (sf::Keyboard::KeyCount + event.mouseButton.button)); + break; + case sf::Event::MouseWheelScrolled: + if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) + delta_vertical_scroll = event.mouseWheelScroll.delta; + break; + case sf::Event::MouseEntered: + // action MouseEntered + break; + case sf::Event::MouseLeft: + //action MouseLeft + break; + + } + for (auto key: heldkeys){ + action_file.push(kb.getHoldAction(key)); } } } int Input::getAction(){ - //return action_file.first(); + if (action_file.empty()) + return -1; + int val = action_file.front(); + action_file.pop(); + return val; } -void Input::reloadKeyBindings(){ - for (int i = 0; i < NB_CONTEXT; i++){ - keybindings[i] = KeyBindings(contexts[i],&keysmap); - } + +/* window-related function */ + +bool Input::isCloseRequested() +{ + return closeRequested; } -void Input::setContext(Context context){ - current_context = context; + +/* keyboard-related function */ + +bool Input::isKeyPressed(int key) +{ + return sf::Keyboard::isKeyPressed((sf::Keyboard::Key) key); +} + +void Input::releaseHeldKeys(sf::Keyboard::Key keycode){ + auto iter = heldkeys.begin(); + while(*iter != keycode) ++iter; + heldkeys.erase(iter); +} + +/* mouse-related function */ + +sf::Vector2i Input::getPosition() +{ + mouse_position = sf::Mouse::getPosition(); + return mouse_position; +} + +sf::Vector2i Input::getDeltaPosition() +{ + sf::Vector2i last_position = mouse_position; + mouse_position = sf::Mouse::getPosition(); + return mouse_position - last_position; +} + +int Input::getDeltaVerticalScroll() +{ + return delta_vertical_scroll; +} + + +void Input::test() +{ + std::cerr << keysmap.getTypeAction(1) << std::endl; + std::cerr << keysmap.getKeyBinding(1,0) << std::endl; + KeyBindings kb = keybindings[current_context]; + int action; + 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; } -*/ diff --git a/input.h b/input.h index 15bbfc0..b151376 100644 --- a/input.h +++ b/input.h @@ -7,31 +7,62 @@ #include "keybindings.h" #include #include +#include class Input{ public: - //enum Context {MENU, EDITOR, GAME, DEBUG, NB_CONTEXT}; + /* Constructors */ Input(sf::Window* w, std::string keysmappings, int nb_actions); + +// enum SpecialAction {} + + /* general action-mapping functions */ + void updateEvents(); + int getAction(); int getKeyBinding(int action, int num); void setkeyBinding(int action, int num, sf::Keyboard::Key key); - bool createContext(std::string context_name, std::vector action_list); - void setCurrentContext(std::string context_name); + void setTypeAction(int action, int type); + + /* context-related functions */ + void createContext(std::string context_name, std::vector action_list); + void setCurrentContext(std::string context_name); + void reloadKeyBindings(); + + /* window-related function */ + bool isCloseRequested(); + + /* keyboard-related functions */ + bool isKeyPressed(int key); + + /* mouse-related function */ + sf::Vector2i getPosition(); + sf::Vector2i getDeltaPosition(); + int getDeltaVerticalScroll(); + + void test(); - // void updateEvents(); - // int getAction(); - // void reloadKeyBindings(); - /* -*/ private: + /* window-related variables */ sf::Window* window; + bool closeRequested; + + /* general action-mapping variables */ KeysMap keysmap; - /* - std::queue action_file; - Context current_context; - std::vector contexts[NB_CONTEXT]; - std::vector contexts; - KeyBindings keybindings[NB_CONTEXT]; -*/ + std::queue action_file; + int nb_actions; + + /* context-related variables */ + std::string current_context; + std::unordered_map> contexts; + std::unordered_map keybindings; + + /* keyboard-related variables */ + std::vector heldkeys; + void releaseHeldKeys(sf::Keyboard::Key keycode); + + /* mouse-related variables */ + sf::Vector2i mouse_position; + int delta_vertical_scroll; }; -#endif +#endif //INPUT_H diff --git a/keybindings.cpp b/keybindings.cpp index 7f170e2..fff050a 100644 --- a/keybindings.cpp +++ b/keybindings.cpp @@ -17,6 +17,11 @@ KeysMap::KeysMap() KeysMap::KeysMap(std::string keysmapping, int nb_actions):keysmapping_file(keysmapping), size_keys_map(nb_actions*2) { keys_map = (int*) malloc(size_keys_map*sizeof(int)); + for(int i = 0; i < size_keys_map; i++) + keys_map[i] = NO_KEY; + actiontype_map = (int*) malloc((size_keys_map/2)*sizeof(int)); + for (int i = 0; i < size_keys_map/2 ; i++) + actiontype_map[i] = PRESSED; loadKeysMap(); } @@ -30,6 +35,16 @@ void KeysMap::setKeyBinding(int action, int num, int key) keys_map[(action*NB_BINDINGS)+num] = key; } +int KeysMap::getTypeAction(int action) +{ + return actiontype_map[action]; +} + +void KeysMap::setTypeAction(int action, int type) +{ + actiontype_map[action]=type; +} + void KeysMap::saveKeysMap() { //TODO: Serialize map_keys @@ -42,6 +57,7 @@ void KeysMap::loadKeysMap() //use keysmapping_file } + /* 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. @@ -54,18 +70,63 @@ KeyBindings::KeyBindings() KeyBindings::KeyBindings(std::vector action_list, KeysMap* keysmap) { + int key; for (int action : action_list){ - for(int i=0; igetKeyBinding(action,i),action); + switch(keysmap->getTypeAction(action)){ + case KeysMap::PRESSED: + for(int i=0; igetKeyBinding(action,i); + if (key != NO_KEY) + setPressedAction(key,action); + } + break; + case KeysMap::RELEASED: + for(int i=0; igetKeyBinding(action,i); + if (key != NO_KEY) + setReleasedAction(key,action); + } + break; + case KeysMap::HOLD: + for(int i=0; igetKeyBinding(action,i); + if (key != NO_KEY) + setHoldAction(key,action); + } + break; + default: + //raiseError; + break; + } } } -int KeyBindings::getAction(int key) +int KeyBindings::getPressedAction(int key) { -// return bindings.; + return bindings_pressed.count(key) == 1? bindings_pressed[key] : -1; } -void KeyBindings::setKeyBinding(int key, int action) +int KeyBindings::getReleasedAction(int key) { -// bindings.set(key,action); + return bindings_released.count(key) == 1? bindings_released[key] : -1; +} + +int KeyBindings::getHoldAction(int key) +{ + return bindings_hold.count(key) == 1? bindings_hold[key] : -1; +} + +void KeyBindings::setPressedAction(int key, int action) +{ + bindings_pressed[key]=action; +} + +void KeyBindings::setReleasedAction(int key, int action) +{ + bindings_released[key]=action; +} + +void KeyBindings::setHoldAction(int key, int action) +{ + bindings_hold[key]=action; } diff --git a/keybindings.h b/keybindings.h index 2b555b5..fa0a390 100644 --- a/keybindings.h +++ b/keybindings.h @@ -9,32 +9,44 @@ #include +#define NO_KEY -1 +#define NO_ACTION -1 + class KeysMap { public: enum {PRIMARY,SECONDARY,NB_BINDINGS}; - + enum {PRESSED, RELEASED, HOLD}; KeysMap(); KeysMap(std::string keysmapping, int nb_actions); int getKeyBinding(int action,int num); void setKeyBinding(int action, int num, int key); - + int getTypeAction(int action); + void setTypeAction(int action, int type); void saveKeysMap(); void loadKeysMap(); private: std::string keysmapping_file; int size_keys_map = 0; int* keys_map; + int* actiontype_map; }; class KeyBindings { public: KeyBindings(); KeyBindings(const std::vector action_list, KeysMap* keysmap); - int getAction(int key); + int getPressedAction(int key); + int getReleasedAction(int key); + int getHoldAction(int key); + std::unordered_map bindings_hold; + private: - std::unordered_map bindings; - void setKeyBinding(int key, int action); + std::unordered_map bindings_pressed; + std::unordered_map bindings_released; + void setPressedAction(int key, int action); + void setReleasedAction(int key, int action); + void setHoldAction(int key, int action); }; #endif diff --git a/main.cpp b/main.cpp index a88cf43..e0b789d 100644 --- a/main.cpp +++ b/main.cpp @@ -6,15 +6,49 @@ using namespace std; int main() { - cout << "Hello World!" << endl; + cerr << "Hello World!"<< endl; sf::Window* window= new sf::Window(sf::VideoMode(400,200),"testSparrowInput"); - Input myInput(window, "test.esk",5); + Input myInput(window, "test.esk",2); + enum {ACTION_1,ACTION_2}; + std::vector myvector; + myvector.push_back(ACTION_2); + +/* KeysMap* keymap = new KeysMap("test", 2); + + keymap->setKeyBinding(ACTION_1,0,sf::Keyboard::A); + keymap->setKeyBinding(ACTION_1,1,sf::Keyboard::Z); + keymap->setTypeAction(ACTION_1,KeysMap::HOLD); +// cerr << keymap->getKeyBinding(ACTION_1,0) << endl; + cerr << keymap->getTypeAction(ACTION_1) << endl; +*/ + //KeyBindings keybind(myvector,keymap); + //cerr << " Action : " << keybind.getPressedAction(sf::Keyboard::A) << endl; + + myInput.setkeyBinding(ACTION_1,1,sf::Keyboard::A); + myInput.setkeyBinding(ACTION_1,2,sf::Keyboard::Z); + myInput.setkeyBinding(ACTION_2,1,sf::Keyboard::I); + myInput.setkeyBinding(ACTION_2,2,sf::Keyboard::O); + + myInput.setTypeAction(ACTION_1, KeysMap::RELEASED); + + myInput.test(); + + myInput.createContext("test", myvector); + myInput.setCurrentContext("test"); +// myInput.reloadKeyBindings(); bool run = true; while(run){ //myInput.updateEvents(); + if (myInput.isCloseRequested()){ + window->close(); + run = false; + } + while (myInput.getAction() != NO_ACTION) + cout << "test " << myInput.getAction() << endl; +/* if (myInput.getAction() == ACTION_2) + cout << "hello" << endl;*/ + window->display(); } - vector actions; - actions.size(); return 0; } diff --git a/textbuffer.cpp b/textbuffer.cpp new file mode 100644 index 0000000..3212f83 --- /dev/null +++ b/textbuffer.cpp @@ -0,0 +1,7 @@ +#include "textbuffer.h" + +TextBuffer::TextBuffer() +{ + +} + diff --git a/textbuffer.h b/textbuffer.h new file mode 100644 index 0000000..e584a56 --- /dev/null +++ b/textbuffer.h @@ -0,0 +1,15 @@ +#ifndef TEXTBUFFER_H +#define TEXTBUFFER_H +#include + +class TextBuffer +{ +public: + TextBuffer(); + +private: + std::string buffer; + +}; + +#endif // TEXTBUFFER_H