diff --git a/Windows/Gopher/ConfigFile.h b/Windows/Gopher/ConfigFile.h index 391fa30..da03513 100644 --- a/Windows/Gopher/ConfigFile.h +++ b/Windows/Gopher/ConfigFile.h @@ -1,11 +1,14 @@ #pragma once +#include #include #include #include #include #include #include "Convert.h" +#include + class ConfigFile { @@ -41,5 +44,22 @@ class ConfigFile return Convert::string_to_T(contents.find(key)->second); }; + + std::vector getValueOfKeys(const std::string& key) const + { + if (!keyExists(key)) + return std::vector{}; + + std::vector keyValues; + std::stringstream ss(contents.find(key)->second); + while (ss.good()) + { + std::string substr; + getline(ss, substr, ','); + keyValues.push_back(strtol(substr.c_str(), 0, 0)); + } + return keyValues; + }; + void exitWithError(const std::string &error); }; \ No newline at end of file diff --git a/Windows/Gopher/Gopher.cpp b/Windows/Gopher/Gopher.cpp index 32b47f0..7bc991f 100644 --- a/Windows/Gopher/Gopher.cpp +++ b/Windows/Gopher/Gopher.cpp @@ -1,5 +1,6 @@ #include "Gopher.h" #include "ConfigFile.h" +#include // Description: // Send a keyboard input to the system based on the key value @@ -8,16 +9,18 @@ // Params: // cmd The value of the key to send(see http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx) // flag The KEYEVENT for the key -void inputKeyboard(WORD cmd, DWORD flag) +void inputKeyboard(std::vector cmd, DWORD flag) { - INPUT input; - input.type = INPUT_KEYBOARD; - input.ki.wScan = 0; - input.ki.time = 0; - input.ki.dwExtraInfo = 0; - input.ki.wVk = cmd; - input.ki.dwFlags = flag; - SendInput(1, &input, sizeof(INPUT)); + for (auto const& i : cmd) { + INPUT input; + input.type = INPUT_KEYBOARD; + input.ki.wScan = 0; + input.ki.time = 0; + input.ki.dwExtraInfo = 0; + input.ki.wVk = i; + input.ki.dwFlags = flag; + SendInput(1, &input, sizeof(INPUT)); + } } // Description: @@ -25,7 +28,7 @@ void inputKeyboard(WORD cmd, DWORD flag) // // Params: // cmd The value of the key to send -void inputKeyboardDown(WORD cmd) +void inputKeyboardDown(std::vector cmd) { inputKeyboard(cmd, 0); } @@ -35,9 +38,9 @@ void inputKeyboardDown(WORD cmd) // // Params: // cmd The value of the key to send -void inputKeyboardUp(WORD cmd) +void inputKeyboardUp(std::vector cmd) { - inputKeyboard(cmd, KEYEVENTF_KEYUP); + inputKeyboard(cmd, KEYEVENTF_KEYUP); } // Description: @@ -97,22 +100,26 @@ void Gopher::loadConfigFile() //-------------------------------- // Controller bindings //-------------------------------- - GAMEPAD_DPAD_UP = strtol(cfg.getValueOfKey("GAMEPAD_DPAD_UP").c_str(), 0, 0); - GAMEPAD_DPAD_DOWN = strtol(cfg.getValueOfKey("GAMEPAD_DPAD_DOWN").c_str(), 0, 0); - GAMEPAD_DPAD_LEFT = strtol(cfg.getValueOfKey("GAMEPAD_DPAD_LEFT").c_str(), 0, 0); - GAMEPAD_DPAD_RIGHT = strtol(cfg.getValueOfKey("GAMEPAD_DPAD_RIGHT").c_str(), 0, 0); - GAMEPAD_START = strtol(cfg.getValueOfKey("GAMEPAD_START").c_str(), 0, 0); - GAMEPAD_BACK = strtol(cfg.getValueOfKey("GAMEPAD_BACK").c_str(), 0, 0); - GAMEPAD_LEFT_THUMB = strtol(cfg.getValueOfKey("GAMEPAD_LEFT_THUMB").c_str(), 0, 0); - GAMEPAD_RIGHT_THUMB = strtol(cfg.getValueOfKey("GAMEPAD_RIGHT_THUMB").c_str(), 0, 0); - GAMEPAD_LEFT_SHOULDER = strtol(cfg.getValueOfKey("GAMEPAD_LEFT_SHOULDER").c_str(), 0, 0); - GAMEPAD_RIGHT_SHOULDER = strtol(cfg.getValueOfKey("GAMEPAD_RIGHT_SHOULDER").c_str(), 0, 0); - GAMEPAD_A = strtol(cfg.getValueOfKey("GAMEPAD_A").c_str(), 0, 0); - GAMEPAD_B = strtol(cfg.getValueOfKey("GAMEPAD_B").c_str(), 0, 0); - GAMEPAD_X = strtol(cfg.getValueOfKey("GAMEPAD_X").c_str(), 0, 0); - GAMEPAD_Y = strtol(cfg.getValueOfKey("GAMEPAD_Y").c_str(), 0, 0); - GAMEPAD_TRIGGER_LEFT = strtol(cfg.getValueOfKey("GAMEPAD_TRIGGER_LEFT").c_str(), 0, 0); - GAMEPAD_TRIGGER_RIGHT = strtol(cfg.getValueOfKey("GAMEPAD_TRIGGER_RIGHT").c_str(), 0, 0); + GAMEPAD_DPAD_UP = cfg.getValueOfKeys("GAMEPAD_DPAD_UP"); + GAMEPAD_DPAD_DOWN = cfg.getValueOfKeys("GAMEPAD_DPAD_DOWN"); + GAMEPAD_DPAD_LEFT = cfg.getValueOfKeys("GAMEPAD_DPAD_LEFT"); + GAMEPAD_DPAD_RIGHT = cfg.getValueOfKeys("GAMEPAD_DPAD_RIGHT"); + GAMEPAD_START = cfg.getValueOfKeys("GAMEPAD_START"); + GAMEPAD_BACK = cfg.getValueOfKeys("GAMEPAD_BACK"); + GAMEPAD_LEFT_THUMB = cfg.getValueOfKeys("GAMEPAD_LEFT_THUMB"); + GAMEPAD_RIGHT_THUMB = cfg.getValueOfKeys("GAMEPAD_RIGHT_THUMB"); + GAMEPAD_LEFT_SHOULDER = cfg.getValueOfKeys("GAMEPAD_LEFT_SHOULDER"); + GAMEPAD_RIGHT_SHOULDER = cfg.getValueOfKeys("GAMEPAD_RIGHT_SHOULDER"); + GAMEPAD_A = cfg.getValueOfKeys("GAMEPAD_A"); + GAMEPAD_B = cfg.getValueOfKeys("GAMEPAD_B"); + GAMEPAD_X = cfg.getValueOfKeys("GAMEPAD_X"); + GAMEPAD_Y = cfg.getValueOfKeys("GAMEPAD_Y"); + GAMEPAD_TRIGGER_LEFT = cfg.getValueOfKeys("GAMEPAD_TRIGGER_LEFT"); + GAMEPAD_TRIGGER_RIGHT = cfg.getValueOfKeys("GAMEPAD_TRIGGER_RIGHT"); + + + + //-------------------------------- // Advanced settings @@ -279,60 +286,61 @@ void Gopher::loop() } // Update all controller keys. + //WARNING handleTriggers(GAMEPAD_TRIGGER_LEFT, GAMEPAD_TRIGGER_RIGHT); - if (GAMEPAD_DPAD_UP) + if (!GAMEPAD_DPAD_UP.empty()) { mapKeyboard(XINPUT_GAMEPAD_DPAD_UP, GAMEPAD_DPAD_UP); } - if (GAMEPAD_DPAD_DOWN) + if (!GAMEPAD_DPAD_DOWN.empty()) { mapKeyboard(XINPUT_GAMEPAD_DPAD_DOWN, GAMEPAD_DPAD_DOWN); } - if (GAMEPAD_DPAD_LEFT) + if (!GAMEPAD_DPAD_LEFT.empty()) { mapKeyboard(XINPUT_GAMEPAD_DPAD_LEFT, GAMEPAD_DPAD_LEFT); } - if (GAMEPAD_DPAD_RIGHT) + if (!GAMEPAD_DPAD_RIGHT.empty()) { mapKeyboard(XINPUT_GAMEPAD_DPAD_RIGHT, GAMEPAD_DPAD_RIGHT); } - if (GAMEPAD_START) + if (!GAMEPAD_START.empty()) { mapKeyboard(XINPUT_GAMEPAD_START, GAMEPAD_START); } - if (GAMEPAD_BACK) + if (!GAMEPAD_BACK.empty()) { mapKeyboard(XINPUT_GAMEPAD_BACK, GAMEPAD_BACK); } - if (GAMEPAD_LEFT_THUMB) + if (!GAMEPAD_LEFT_THUMB.empty()) { mapKeyboard(XINPUT_GAMEPAD_LEFT_THUMB, GAMEPAD_LEFT_THUMB); } - if (GAMEPAD_RIGHT_THUMB) + if (!GAMEPAD_RIGHT_THUMB.empty()) { mapKeyboard(XINPUT_GAMEPAD_RIGHT_THUMB, GAMEPAD_RIGHT_THUMB); } - if (GAMEPAD_LEFT_SHOULDER) + if (!GAMEPAD_LEFT_SHOULDER.empty()) { mapKeyboard(XINPUT_GAMEPAD_LEFT_SHOULDER, GAMEPAD_LEFT_SHOULDER); } - if (GAMEPAD_RIGHT_SHOULDER) + if (!GAMEPAD_RIGHT_SHOULDER.empty()) { mapKeyboard(XINPUT_GAMEPAD_RIGHT_SHOULDER, GAMEPAD_RIGHT_SHOULDER); } - if (GAMEPAD_A) + if (!GAMEPAD_A.empty()) { mapKeyboard(XINPUT_GAMEPAD_A, GAMEPAD_A); } - if (GAMEPAD_B) + if (!GAMEPAD_B.empty()) { mapKeyboard(XINPUT_GAMEPAD_B, GAMEPAD_B); } - if (GAMEPAD_X) + if (!GAMEPAD_X.empty()) { mapKeyboard(XINPUT_GAMEPAD_X, GAMEPAD_X); } - if (GAMEPAD_Y) + if (!GAMEPAD_Y.empty()) { mapKeyboard(XINPUT_GAMEPAD_Y, GAMEPAD_Y); } @@ -395,7 +403,7 @@ void Gopher::handleDisableButton() // Handle keys (TODO: support mouse X1 and X2 buttons) else { - inputKeyboardUp(*it); + inputKeyboardUp(std::vector{ *it }); } _pressedKeys.erase(it); @@ -538,6 +546,7 @@ void Gopher::handleMouseMovement() _yRest = y - (float)((int)y); SetCursorPos((int)x, (int)y); //after all click input processing + } // Description: @@ -577,7 +586,7 @@ void Gopher::handleScrolling() // Params: // lKey The mapped key for the left trigger // rKey The mapped key for the right trigger -void Gopher::handleTriggers(WORD lKey, WORD rKey) +void Gopher::handleTriggers(std::vector lKeys, std::vector rKeys) { bool lTriggerIsDown = _currentState.Gamepad.bLeftTrigger > TRIGGER_DEAD_ZONE; bool rTriggerIsDown = _currentState.Gamepad.bRightTrigger > TRIGGER_DEAD_ZONE; @@ -585,14 +594,17 @@ void Gopher::handleTriggers(WORD lKey, WORD rKey) // Handle left trigger if (lTriggerIsDown != _lTriggerPrevious) { - _lTriggerPrevious = lTriggerIsDown; + _lTriggerPrevious = lTriggerIsDown; + + std::vector lKEyArr = mapDwordArrayToWrodArray(lKeys); + if (lTriggerIsDown) { - inputKeyboardDown(lKey); + inputKeyboardDown(lKEyArr); } else { - inputKeyboardUp(lKey); + inputKeyboardUp(lKEyArr); } } @@ -600,13 +612,14 @@ void Gopher::handleTriggers(WORD lKey, WORD rKey) if (rTriggerIsDown != _rTriggerPrevious) { _rTriggerPrevious = rTriggerIsDown; + std::vector rKEyArr = mapDwordArrayToWrodArray(rKeys);; if (rTriggerIsDown) { - inputKeyboardDown(rKey); + inputKeyboardDown(rKEyArr); } else { - inputKeyboardUp(rKey); + inputKeyboardUp(rKEyArr); } } } @@ -685,26 +698,40 @@ bool Gopher::xboxClickStateExists(DWORD STATE) // Params: // STATE The Gopher state, or command, to trigger a key event // key The key value to input to the system -void Gopher::mapKeyboard(DWORD STATE, WORD key) +void Gopher::mapKeyboard(DWORD STATE, std::vector keys) { + setXboxClickState(STATE); if (_xboxClickIsDown[STATE]) { - inputKeyboardDown(key); + std::vector wordKeys = mapDwordArrayToWrodArray(keys); + inputKeyboardDown(wordKeys); // Add key to the list of pressed keys. - _pressedKeys.push_back(key); + for (auto const& i : keys) { + _pressedKeys.push_back(i); + } } if (_xboxClickIsUp[STATE]) { - inputKeyboardUp(key); + std::vector wordKeys = mapDwordArrayToWrodArray(keys); + inputKeyboardUp(wordKeys); // Remove key from the list of pressed keys. - erasePressedKey(key); + erasePressedKeys(wordKeys); } } +std::vector Gopher::mapDwordArrayToWrodArray(std::vector dwordArray) +{ + std::vector wordArray; + for (auto const& i : dwordArray) { + wordArray.push_back(i); + } + return wordArray; +} + // Description: // Presses or releases a mouse button based on a mapped Gopher state // @@ -818,3 +845,29 @@ bool Gopher::erasePressedKey(WORD key) return false; } + +// Description: +// Removes an enteries for a pressed keys from the list. +// +// Params: +// keys The key values to remove from the pressed key list. +// +// Returns: +// True if the given keys were found and removed from the list. +bool Gopher::erasePressedKeys(std::vector keys) +{ + for (auto const& i : keys) { + for (std::list::iterator it = _pressedKeys.begin(); + it != _pressedKeys.end(); + ++it) + { + if (*it == i) + { + _pressedKeys.erase(it); + return true; + } + } + } + + return false; +} diff --git a/Windows/Gopher/Gopher.h b/Windows/Gopher/Gopher.h index bf4aebe..57f6d85 100644 --- a/Windows/Gopher/Gopher.h +++ b/Windows/Gopher/Gopher.h @@ -62,22 +62,22 @@ class Gopher DWORD CONFIG_OSK = NULL; // Gamepad bindings - DWORD GAMEPAD_DPAD_UP = NULL; - DWORD GAMEPAD_DPAD_DOWN = NULL; - DWORD GAMEPAD_DPAD_LEFT = NULL; - DWORD GAMEPAD_DPAD_RIGHT = NULL; - DWORD GAMEPAD_START = NULL; - DWORD GAMEPAD_BACK = NULL; - DWORD GAMEPAD_LEFT_THUMB = NULL; - DWORD GAMEPAD_RIGHT_THUMB = NULL; - DWORD GAMEPAD_LEFT_SHOULDER = NULL; - DWORD GAMEPAD_RIGHT_SHOULDER = NULL; - DWORD GAMEPAD_A = NULL; - DWORD GAMEPAD_B = NULL; - DWORD GAMEPAD_X = NULL; - DWORD GAMEPAD_Y = NULL; - DWORD GAMEPAD_TRIGGER_LEFT = NULL; - DWORD GAMEPAD_TRIGGER_RIGHT = NULL; + std::vector GAMEPAD_DPAD_UP = {}; + std::vector GAMEPAD_DPAD_DOWN = {}; + std::vector GAMEPAD_DPAD_LEFT = {}; + std::vector GAMEPAD_DPAD_RIGHT = {}; + std::vector GAMEPAD_START = {}; + std::vector GAMEPAD_BACK = {}; + std::vector GAMEPAD_LEFT_THUMB = {}; + std::vector GAMEPAD_RIGHT_THUMB = {}; + std::vector GAMEPAD_LEFT_SHOULDER = {}; + std::vector GAMEPAD_RIGHT_SHOULDER = {}; + std::vector GAMEPAD_A = {}; + std::vector GAMEPAD_B = {}; + std::vector GAMEPAD_X = {}; + std::vector GAMEPAD_Y = {}; + std::vector GAMEPAD_TRIGGER_LEFT = {}; + std::vector GAMEPAD_TRIGGER_RIGHT = {}; // Button press state logic variables std::map _xboxClickStateLastIteration; @@ -116,11 +116,11 @@ class Gopher void handleScrolling(); - void handleTriggers(WORD lKey, WORD rKey); + void handleTriggers(std::vector lKeys, std::vector rKeys); bool xboxClickStateExists(DWORD xinput); - void mapKeyboard(DWORD STATE, WORD key); + void mapKeyboard(DWORD STATE, std::vector key); void mapMouseClick(DWORD STATE, DWORD keyDown, DWORD keyUp); @@ -128,7 +128,10 @@ class Gopher HWND getOskWindow(); + std::vector mapDwordArrayToWrodArray(std::vector dwordArray); + private: bool erasePressedKey(WORD key); + bool erasePressedKeys(std::vector keys); };