diff --git a/src/input/input.cpp b/src/input/input.cpp index 9ec25a70..d12366db 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -1,23 +1,23 @@ /* -** input.cpp -** -** This file is part of mkxp. -** -** Copyright (C) 2013 Jonas Kulla -** -** mkxp is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 2 of the License, or -** (at your option) any later version. -** -** mkxp is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with mkxp. If not, see . -*/ + ** input.cpp + ** + ** This file is part of mkxp. + ** + ** Copyright (C) 2013 Jonas Kulla + ** + ** mkxp is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 2 of the License, or + ** (at your option) any later version. + ** + ** mkxp is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with mkxp. If not, see . + */ #include "input.h" #include "config.h" @@ -425,190 +425,190 @@ std::unordered_map strToScancode{ struct ButtonState { - bool pressed; - bool triggered; - bool repeated; + bool pressed; + bool triggered; + bool repeated; bool released; - - ButtonState() - : pressed(false), - triggered(false), - repeated(false), - released(false) - {} + + ButtonState() + : pressed(false), + triggered(false), + repeated(false), + released(false) + {} }; struct KbBindingData { - SDL_Scancode source; - Input::ButtonCode target; + SDL_Scancode source; + Input::ButtonCode target; }; struct Binding { - Binding(Input::ButtonCode target = Input::None) - : target(target) - {} - - virtual bool sourceActive() const = 0; - virtual bool sourceRepeatable() const = 0; - - Input::ButtonCode target; + Binding(Input::ButtonCode target = Input::None) + : target(target) + {} + + virtual bool sourceActive() const = 0; + virtual bool sourceRepeatable() const = 0; + + Input::ButtonCode target; }; /* Keyboard binding */ struct KbBinding : public Binding { - KbBinding() {} - - KbBinding(const KbBindingData &data) - : Binding(data.target), - source(data.source) - {} - - bool sourceActive() const - { - /* Special case aliases */ - if (source == SDL_SCANCODE_LSHIFT) - return EventThread::keyStates[source] - || EventThread::keyStates[SDL_SCANCODE_RSHIFT]; - - if (source == SDL_SCANCODE_RETURN) - return EventThread::keyStates[source] - || EventThread::keyStates[SDL_SCANCODE_KP_ENTER]; - - return EventThread::keyStates[source]; - } - - bool sourceRepeatable() const - { + KbBinding() {} + + KbBinding(const KbBindingData &data) + : Binding(data.target), + source(data.source) + {} + + bool sourceActive() const + { + /* Special case aliases */ + if (source == SDL_SCANCODE_LSHIFT) + return EventThread::keyStates[source] + || EventThread::keyStates[SDL_SCANCODE_RSHIFT]; + + if (source == SDL_SCANCODE_RETURN) + return EventThread::keyStates[source] + || EventThread::keyStates[SDL_SCANCODE_KP_ENTER]; + + return EventThread::keyStates[source]; + } + + bool sourceRepeatable() const + { return true; /* - return (source >= SDL_SCANCODE_A && source <= SDL_SCANCODE_0) || - (source >= SDL_SCANCODE_RIGHT && source <= SDL_SCANCODE_UP) || - (source >= SDL_SCANCODE_F1 && source <= SDL_SCANCODE_F12); + return (source >= SDL_SCANCODE_A && source <= SDL_SCANCODE_0) || + (source >= SDL_SCANCODE_RIGHT && source <= SDL_SCANCODE_UP) || + (source >= SDL_SCANCODE_F1 && source <= SDL_SCANCODE_F12); */ - } - - SDL_Scancode source; + } + + SDL_Scancode source; }; /* Joystick button binding */ struct JsButtonBinding : public Binding { - JsButtonBinding() {} - - bool sourceActive() const - { - return EventThread::joyState.buttons[source]; - } - - bool sourceRepeatable() const - { - return true; - } - - uint8_t source; + JsButtonBinding() {} + + bool sourceActive() const + { + return EventThread::joyState.buttons[source]; + } + + bool sourceRepeatable() const + { + return true; + } + + uint8_t source; }; /* Joystick axis binding */ struct JsAxisBinding : public Binding { - JsAxisBinding() {} - - JsAxisBinding(uint8_t source, - AxisDir dir, - Input::ButtonCode target) - : Binding(target), - source(source), - dir(dir) - {} - - bool sourceActive() const - { - int val = EventThread::joyState.axes[source]; - - if (dir == Negative) - return val < -JAXIS_THRESHOLD; - else /* dir == Positive */ - return val > JAXIS_THRESHOLD; - } - - bool sourceRepeatable() const - { - return true; - } - - uint8_t source; - AxisDir dir; + JsAxisBinding() {} + + JsAxisBinding(uint8_t source, + AxisDir dir, + Input::ButtonCode target) + : Binding(target), + source(source), + dir(dir) + {} + + bool sourceActive() const + { + int val = EventThread::joyState.axes[source]; + + if (dir == Negative) + return val < -JAXIS_THRESHOLD; + else /* dir == Positive */ + return val > JAXIS_THRESHOLD; + } + + bool sourceRepeatable() const + { + return true; + } + + uint8_t source; + AxisDir dir; }; /* Joystick hat binding */ struct JsHatBinding : public Binding { - JsHatBinding() {} - - JsHatBinding(uint8_t source, - uint8_t pos, - Input::ButtonCode target) - : Binding(target), - source(source), - pos(pos) - {} - - bool sourceActive() const - { - /* For a diagonal input accept it as an input for both the axes */ - return (pos & EventThread::joyState.hats[source]) != 0; - } - - bool sourceRepeatable() const - { - return true; - } - - uint8_t source; - uint8_t pos; + JsHatBinding() {} + + JsHatBinding(uint8_t source, + uint8_t pos, + Input::ButtonCode target) + : Binding(target), + source(source), + pos(pos) + {} + + bool sourceActive() const + { + /* For a diagonal input accept it as an input for both the axes */ + return (pos & EventThread::joyState.hats[source]) != 0; + } + + bool sourceRepeatable() const + { + return true; + } + + uint8_t source; + uint8_t pos; }; /* Mouse button binding */ struct MsBinding : public Binding { - MsBinding() {} - - MsBinding(int buttonIndex, - Input::ButtonCode target) - : Binding(target), - index(buttonIndex) - {} - - bool sourceActive() const - { - return EventThread::mouseState.buttons[index]; - } - - bool sourceRepeatable() const - { - return true; - } - - int index; + MsBinding() {} + + MsBinding(int buttonIndex, + Input::ButtonCode target) + : Binding(target), + index(buttonIndex) + {} + + bool sourceActive() const + { + return EventThread::mouseState.buttons[index]; + } + + bool sourceRepeatable() const + { + return true; + } + + int index; }; /* Not rebindable */ static const KbBindingData staticKbBindings[] = { - { SDL_SCANCODE_LSHIFT, Input::Shift }, - { SDL_SCANCODE_RSHIFT, Input::Shift }, - { SDL_SCANCODE_LCTRL, Input::Ctrl }, - { SDL_SCANCODE_RCTRL, Input::Ctrl }, - { SDL_SCANCODE_LALT, Input::Alt }, - { SDL_SCANCODE_RALT, Input::Alt }, - { SDL_SCANCODE_F5, Input::F5 }, - { SDL_SCANCODE_F6, Input::F6 }, - { SDL_SCANCODE_F7, Input::F7 }, - { SDL_SCANCODE_F8, Input::F8 }, - { SDL_SCANCODE_F9, Input::F9 } + { SDL_SCANCODE_LSHIFT, Input::Shift }, + { SDL_SCANCODE_RSHIFT, Input::Shift }, + { SDL_SCANCODE_LCTRL, Input::Ctrl }, + { SDL_SCANCODE_RCTRL, Input::Ctrl }, + { SDL_SCANCODE_LALT, Input::Alt }, + { SDL_SCANCODE_RALT, Input::Alt }, + { SDL_SCANCODE_F5, Input::F5 }, + { SDL_SCANCODE_F6, Input::F6 }, + { SDL_SCANCODE_F7, Input::F7 }, + { SDL_SCANCODE_F8, Input::F8 }, + { SDL_SCANCODE_F9, Input::F9 } }; static elementsN(staticKbBindings); @@ -617,16 +617,16 @@ static elementsN(staticKbBindings); * in the button state array */ static const int mapToIndex[] = { - 0, 0, - 1, 0, 2, 0, 3, 0, 4, 0, - 0, - 5, 6, 7, 8, 9, 10, 11, 12, - 0, 0, - 13, 14, 15, - 0, - 16, 17, 18, 19, 20, - 0, 0, 0, 0, 0, 0, 0, 0, - 21, 22, 23 + 0, 0, + 1, 0, 2, 0, 3, 0, 4, 0, + 0, + 5, 6, 7, 8, 9, 10, 11, 12, + 0, 0, + 13, 14, 15, + 0, + 16, 17, 18, 19, 20, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 22, 23 }; static elementsN(mapToIndex); @@ -636,53 +636,53 @@ static const Input::ButtonCode dirs[] = static const int dirFlags[] = { - 1 << Input::Down, - 1 << Input::Left, - 1 << Input::Right, - 1 << Input::Up + 1 << Input::Down, + 1 << Input::Left, + 1 << Input::Right, + 1 << Input::Up }; /* Dir4 is always zero on these combinations */ static const int deadDirFlags[] = { - dirFlags[0] | dirFlags[3], - dirFlags[1] | dirFlags[2] + dirFlags[0] | dirFlags[3], + dirFlags[1] | dirFlags[2] }; static const Input::ButtonCode otherDirs[4][3] = { - { Input::Left, Input::Right, Input::Up }, /* Down */ - { Input::Down, Input::Up, Input::Right }, /* Left */ - { Input::Down, Input::Up, Input::Left }, /* Right */ - { Input::Left, Input::Right, Input::Up } /* Up */ + { Input::Left, Input::Right, Input::Up }, /* Down */ + { Input::Down, Input::Up, Input::Right }, /* Left */ + { Input::Down, Input::Up, Input::Left }, /* Right */ + { Input::Left, Input::Right, Input::Up } /* Up */ }; struct InputPrivate { - std::vector kbStatBindings; - std::vector kbBindings; - std::vector jsABindings; - std::vector jsHBindings; - std::vector jsBBindings; - std::vector msBindings; - - /* Collective binding array */ - std::vector bindings; - - ButtonState stateArray[BUTTON_CODE_COUNT*2]; - - ButtonState *states; - ButtonState *statesOld; + std::vector kbStatBindings; + std::vector kbBindings; + std::vector jsABindings; + std::vector jsHBindings; + std::vector jsBBindings; + std::vector msBindings; + + /* Collective binding array */ + std::vector bindings; + + ButtonState stateArray[BUTTON_CODE_COUNT*2]; + + ButtonState *states; + ButtonState *statesOld; // Raw keystates uint8_t rawStateArray[SDL_NUM_SCANCODES*2]; uint8_t *rawStates; uint8_t *rawStatesOld; - - Input::ButtonCode repeating; + + Input::ButtonCode repeating; int rawRepeating; - unsigned int repeatCount; + unsigned int repeatCount; unsigned int rawRepeatCount; unsigned long long repeatTime; unsigned long long rawRepeatTime; @@ -691,84 +691,84 @@ struct InputPrivate unsigned int repeatDelay; unsigned long long last_update; - - struct - { - int active; - Input::ButtonCode previous; - } dir4Data; - - struct - { - int active; - } dir8Data; - + + struct + { + int active; + Input::ButtonCode previous; + } dir4Data; + + struct + { + int active; + } dir8Data; + void recalcRepeatTime(unsigned int fps) { double framems = 1.f / fps; // Approximate time in milliseconds double start = (rgssVer >= 2) ? 0.375 : 0.400; double delay = 0.100; - + repeatStart = ceil(start / framems); repeatDelay = ceil(delay / framems); } - - InputPrivate(const RGSSThreadData &rtData) - { + + InputPrivate(const RGSSThreadData &rtData) + { last_update = 0; - initStaticKbBindings(); - initMsBindings(); - - /* Main thread should have these posted by now */ - checkBindingChange(rtData); + initStaticKbBindings(); + initMsBindings(); + + /* Main thread should have these posted by now */ + checkBindingChange(rtData); int fps = rtData.config.fixedFramerate; if (!fps) fps = (rgssVer >= 2) ? 60 : 40; recalcRepeatTime(fps); - - states = stateArray; - statesOld = stateArray + BUTTON_CODE_COUNT; + + states = stateArray; + statesOld = stateArray + BUTTON_CODE_COUNT; rawStates = rawStateArray; rawStatesOld = rawStateArray + SDL_NUM_SCANCODES; - - /* Clear buffers */ - clearBuffer(); - swapBuffers(); - clearBuffer(); - - repeating = Input::None; - repeatCount = 0; - dir4Data.active = 0; - dir4Data.previous = Input::None; - - dir8Data.active = 0; - } - - inline ButtonState &getStateCheck(int code) - { - int index; - - if (code < 0 || (size_t) code > mapToIndexN-1) - index = 0; - else - index = mapToIndex[code]; - - return states[index]; - } - - inline ButtonState &getState(Input::ButtonCode code) - { - return states[mapToIndex[code]]; - } - - inline ButtonState &getOldState(Input::ButtonCode code) - { - return statesOld[mapToIndex[code]]; - } + /* Clear buffers */ + clearBuffer(); + swapBuffers(); + clearBuffer(); + + repeating = Input::None; + repeatCount = 0; + + dir4Data.active = 0; + dir4Data.previous = Input::None; + + dir8Data.active = 0; + } + + inline ButtonState &getStateCheck(int code) + { + int index; + + if (code < 0 || (size_t) code > mapToIndexN-1) + index = 0; + else + index = mapToIndex[code]; + + return states[index]; + } + + inline ButtonState &getState(Input::ButtonCode code) + { + return states[mapToIndex[code]]; + } + + inline ButtonState &getOldState(Input::ButtonCode code) + { + return statesOld[mapToIndex[code]]; + } inline ButtonState getStateRaw(int code, bool useVKey) { @@ -778,36 +778,36 @@ struct InputPrivate { switch (code) { - case 0x10: + case 0x10: return getState(Input::Shift); break; - case 0x11: + case 0x11: return getState(Input::Ctrl); break; - case 0x12: + case 0x12: return getState(Input::Alt); break; - case 0x1: + case 0x1: return getState(Input::MouseLeft); break; - case 0x2: + case 0x2: return getState(Input::MouseRight); break; - case 0x4: + case 0x4: return getState(Input::MouseMiddle); break; - default: + default: ButtonState b; try - { - scancode = vKeyToScancode[code]; - } + { + scancode = vKeyToScancode[code]; + } catch (...) {} if (scancode == -1) return b; break; @@ -822,183 +822,186 @@ struct InputPrivate return b; } - - void swapBuffers() - { - ButtonState *tmp = states; - states = statesOld; - statesOld = tmp; + + void swapBuffers() + { + ButtonState *tmp = states; + states = statesOld; + statesOld = tmp; uint8_t *tmpr = rawStates; rawStates = rawStatesOld; rawStatesOld = tmpr; - } - - void clearBuffer() - { - const size_t size = sizeof(ButtonState) * BUTTON_CODE_COUNT; - memset(states, 0, size); + } + + void clearBuffer() + { + const size_t size = sizeof(ButtonState) * BUTTON_CODE_COUNT; + memset(states, 0, size); memset(rawStates, 0, SDL_NUM_SCANCODES); - } - - void checkBindingChange(const RGSSThreadData &rtData) - { - BDescVec d; - - if (!rtData.bindingUpdateMsg.poll(d)) - return; - - applyBindingDesc(d); - } - - template - void appendBindings(std::vector &bind) - { - for (size_t i = 0; i < bind.size(); ++i) - bindings.push_back(&bind[i]); - } - - void applyBindingDesc(const BDescVec &d) - { - kbBindings.clear(); - jsABindings.clear(); - jsHBindings.clear(); - jsBBindings.clear(); - - for (size_t i = 0; i < d.size(); ++i) - { - const BindingDesc &desc = d[i]; - const SourceDesc &src = desc.src; - - if (desc.target == Input::None) - continue; - - switch (desc.src.type) - { - case Invalid : - break; - case Key : - { - KbBinding bind; - bind.source = src.d.scan; - bind.target = desc.target; - kbBindings.push_back(bind); - - break; - } - case JAxis : - { - JsAxisBinding bind; - bind.source = src.d.ja.axis; - bind.dir = src.d.ja.dir; - bind.target = desc.target; - jsABindings.push_back(bind); - - break; - } - case JHat : - { - JsHatBinding bind; - bind.source = src.d.jh.hat; - bind.pos = src.d.jh.pos; - bind.target = desc.target; - jsHBindings.push_back(bind); - - break; - } - case JButton : - { - JsButtonBinding bind; - bind.source = src.d.jb; - bind.target = desc.target; - jsBBindings.push_back(bind); - - break; - } - default : - assert(!"unreachable"); - } - } - - bindings.clear(); - - appendBindings(kbStatBindings); - appendBindings(msBindings); - - appendBindings(kbBindings); - appendBindings(jsABindings); - appendBindings(jsHBindings); - appendBindings(jsBBindings); - } - - void initStaticKbBindings() - { - kbStatBindings.clear(); - - for (size_t i = 0; i < staticKbBindingsN; ++i) - kbStatBindings.push_back(KbBinding(staticKbBindings[i])); - } - - void initMsBindings() - { - msBindings.resize(3); - - size_t i = 0; - msBindings[i++] = MsBinding(SDL_BUTTON_LEFT, Input::MouseLeft); - msBindings[i++] = MsBinding(SDL_BUTTON_MIDDLE, Input::MouseMiddle); - msBindings[i++] = MsBinding(SDL_BUTTON_RIGHT, Input::MouseRight); - } - - void pollBindings(Input::ButtonCode &repeatCand) - { + } + + void checkBindingChange(const RGSSThreadData &rtData) + { + BDescVec d; + + if (!rtData.bindingUpdateMsg.poll(d)) + return; + + applyBindingDesc(d); + } + + template + void appendBindings(std::vector &bind) + { + for (size_t i = 0; i < bind.size(); ++i) + bindings.push_back(&bind[i]); + } + + void applyBindingDesc(const BDescVec &d) + { + kbBindings.clear(); + jsABindings.clear(); + jsHBindings.clear(); + jsBBindings.clear(); + + for (size_t i = 0; i < d.size(); ++i) + { + const BindingDesc &desc = d[i]; + const SourceDesc &src = desc.src; + + if (desc.target == Input::None) + continue; + + switch (desc.src.type) + { + case Invalid : + break; + case Key : + { + KbBinding bind; + bind.source = src.d.scan; + bind.target = desc.target; + kbBindings.push_back(bind); + + break; + } + case JAxis : + { + JsAxisBinding bind; + bind.source = src.d.ja.axis; + bind.dir = src.d.ja.dir; + bind.target = desc.target; + jsABindings.push_back(bind); + + break; + } + case JHat : + { + JsHatBinding bind; + bind.source = src.d.jh.hat; + bind.pos = src.d.jh.pos; + bind.target = desc.target; + jsHBindings.push_back(bind); + + break; + } + case JButton : + { + JsButtonBinding bind; + bind.source = src.d.jb; + bind.target = desc.target; + jsBBindings.push_back(bind); + + break; + } + default : + assert(!"unreachable"); + } + } + + bindings.clear(); + + appendBindings(kbStatBindings); + appendBindings(msBindings); + + appendBindings(kbBindings); + appendBindings(jsABindings); + appendBindings(jsHBindings); + appendBindings(jsBBindings); + } + + void initStaticKbBindings() + { + kbStatBindings.clear(); + + for (size_t i = 0; i < staticKbBindingsN; ++i) + kbStatBindings.push_back(KbBinding(staticKbBindings[i])); + } + + void initMsBindings() + { + msBindings.resize(3); + + size_t i = 0; + msBindings[i++] = MsBinding(SDL_BUTTON_LEFT, Input::MouseLeft); + msBindings[i++] = MsBinding(SDL_BUTTON_MIDDLE, Input::MouseMiddle); + msBindings[i++] = MsBinding(SDL_BUTTON_RIGHT, Input::MouseRight); + } + + void pollBindings(Input::ButtonCode &repeatCand) + { for (Binding *bind : bindings) { // Get all binding states pollBindingPriv(*bind, repeatCand); - - // Check for released buttons + } + + for (Binding *bind : bindings) { + // Check for released buttons, now that all the bindings + // have been checked ButtonState &state = getState(bind->target); ButtonState &oldState = getOldState(bind->target); if (!state.pressed && oldState.pressed) state.released = true; } - - updateDir4(); - updateDir8(); - } - - void pollBindingPriv(const Binding &b, - Input::ButtonCode &repeatCand) - { - if (!b.sourceActive()) - return; - - if (b.target == Input::None) - return; - - ButtonState &state = getState(b.target); - ButtonState &oldState = getOldState(b.target); - - state.pressed = true; - - /* Must have been released before to trigger */ - if (!oldState.pressed) - state.triggered = true; - - /* Unbound keys don't create/break repeat */ - if (repeatCand != Input::None) - return; - - if (repeating != b.target && - !oldState.pressed) - { - if (b.sourceRepeatable()) - repeatCand = b.target; - else - /* Unrepeatable keys still break current repeat */ - repeating = Input::None; - } - } + + updateDir4(); + updateDir8(); + } + + void pollBindingPriv(const Binding &b, + Input::ButtonCode &repeatCand) + { + if (!b.sourceActive()) + return; + + if (b.target == Input::None) + return; + + ButtonState &state = getState(b.target); + ButtonState &oldState = getOldState(b.target); + + state.pressed = true; + + /* Must have been released before to trigger */ + if (!oldState.pressed) + state.triggered = true; + + /* Unbound keys don't create/break repeat */ + if (repeatCand != Input::None) + return; + + if (repeating != b.target && + !oldState.pressed) + { + if (b.sourceRepeatable()) + repeatCand = b.target; + else + /* Unrepeatable keys still break current repeat */ + repeating = Input::None; + } + } void updateRaw() { @@ -1025,93 +1028,93 @@ struct InputPrivate rawRepeating = -1; } - - void updateDir4() - { - int dirFlag = 0; - - for (size_t i = 0; i < 4; ++i) - dirFlag |= (getState(dirs[i]).pressed ? dirFlags[i] : 0); - - if (dirFlag == deadDirFlags[0] || dirFlag == deadDirFlags[1]) - { - dir4Data.active = Input::None; - return; - } - - if (dir4Data.previous != Input::None) - { - /* Check if prev still pressed */ - if (getState(dir4Data.previous).pressed) - { - for (size_t i = 0; i < 3; ++i) - { - Input::ButtonCode other = - otherDirs[(dir4Data.previous/2)-1][i]; - - if (!getState(other).pressed) - continue; - - dir4Data.active = other; - return; - } - } - } - - for (size_t i = 0; i < 4; ++i) - { - if (!getState(dirs[i]).pressed) - continue; - - dir4Data.active = dirs[i]; - dir4Data.previous = dirs[i]; - return; - } - - dir4Data.active = Input::None; - dir4Data.previous = Input::None; - } - - void updateDir8() - { - static const int combos[4][4] = - { - { 2, 1, 3, 0 }, - { 1, 4, 0, 7 }, - { 3, 0, 6, 9 }, - { 0, 7, 9, 8 } - }; - - dir8Data.active = 0; - - for (size_t i = 0; i < 4; ++i) - { - Input::ButtonCode one = dirs[i]; - - if (!getState(one).pressed) - continue; - - for (int j = 0; j < 3; ++j) - { - Input::ButtonCode other = otherDirs[i][j]; - - if (!getState(other).pressed) - continue; - - dir8Data.active = combos[(one/2)-1][(other/2)-1]; - return; - } - - dir8Data.active = one; - return; - } - } + + void updateDir4() + { + int dirFlag = 0; + + for (size_t i = 0; i < 4; ++i) + dirFlag |= (getState(dirs[i]).pressed ? dirFlags[i] : 0); + + if (dirFlag == deadDirFlags[0] || dirFlag == deadDirFlags[1]) + { + dir4Data.active = Input::None; + return; + } + + if (dir4Data.previous != Input::None) + { + /* Check if prev still pressed */ + if (getState(dir4Data.previous).pressed) + { + for (size_t i = 0; i < 3; ++i) + { + Input::ButtonCode other = + otherDirs[(dir4Data.previous/2)-1][i]; + + if (!getState(other).pressed) + continue; + + dir4Data.active = other; + return; + } + } + } + + for (size_t i = 0; i < 4; ++i) + { + if (!getState(dirs[i]).pressed) + continue; + + dir4Data.active = dirs[i]; + dir4Data.previous = dirs[i]; + return; + } + + dir4Data.active = Input::None; + dir4Data.previous = Input::None; + } + + void updateDir8() + { + static const int combos[4][4] = + { + { 2, 1, 3, 0 }, + { 1, 4, 0, 7 }, + { 3, 0, 6, 9 }, + { 0, 7, 9, 8 } + }; + + dir8Data.active = 0; + + for (size_t i = 0; i < 4; ++i) + { + Input::ButtonCode one = dirs[i]; + + if (!getState(one).pressed) + continue; + + for (int j = 0; j < 3; ++j) + { + Input::ButtonCode other = otherDirs[i][j]; + + if (!getState(other).pressed) + continue; + + dir8Data.active = combos[(one/2)-1][(other/2)-1]; + return; + } + + dir8Data.active = one; + return; + } + } }; Input::Input(const RGSSThreadData &rtData) { - p = new InputPrivate(rtData); + p = new InputPrivate(rtData); } unsigned long long Input::getDelta() { @@ -1124,52 +1127,52 @@ void Input::recalcRepeat(unsigned int fps) { void Input::update() { - shState->checkShutdown(); - p->checkBindingChange(shState->rtData()); - - p->swapBuffers(); - p->clearBuffer(); - - ButtonCode repeatCand = None; - - /* Poll all bindings */ - p->pollBindings(repeatCand); + shState->checkShutdown(); + p->checkBindingChange(shState->rtData()); + + p->swapBuffers(); + p->clearBuffer(); + + ButtonCode repeatCand = None; + + /* Poll all bindings */ + p->pollBindings(repeatCand); // Get raw keystates p->updateRaw(); - - /* Check for new repeating key */ - if (repeatCand != None && repeatCand != p->repeating) - { - p->repeating = repeatCand; - p->repeatCount = 0; + + /* Check for new repeating key */ + if (repeatCand != None && repeatCand != p->repeating) + { + p->repeating = repeatCand; + p->repeatCount = 0; p->repeatTime = shState->runTime(); - p->getState(repeatCand).repeated = true; - + p->getState(repeatCand).repeated = true; + p->last_update = p->repeatTime; - return; - } - - /* Check if repeating key is still pressed */ - if (p->getState(p->repeating).pressed) - { - p->repeatCount++; - + return; + } + + /* Check if repeating key is still pressed */ + if (p->getState(p->repeating).pressed) + { + p->repeatCount++; + /* - bool repeated; - if (rgssVer >= 2) - repeated = p->repeatCount >= 23 && ((p->repeatCount+1) % 6) == 0; - else - repeated = p->repeatCount >= 15 && ((p->repeatCount+1) % 4) == 0; + bool repeated; + if (rgssVer >= 2) + repeated = p->repeatCount >= 23 && ((p->repeatCount+1) % 6) == 0; + else + repeated = p->repeatCount >= 15 && ((p->repeatCount+1) % 4) == 0; */ bool repeated = p->repeatCount >= p->repeatStart && ((p->repeatCount+1) % p->repeatDelay) == 0; - p->getState(p->repeating).repeated |= repeated; - + p->getState(p->repeating).repeated |= repeated; + p->last_update = shState->runTime(); - return; - } + return; + } - p->repeating = None; + p->repeating = None; p->last_update = shState->runTime(); } @@ -1200,17 +1203,17 @@ std::vector Input::getBindings(ButtonCode code) { bool Input::isPressed(int button) { - return p->getStateCheck(button).pressed; + return p->getStateCheck(button).pressed; } bool Input::isTriggered(int button) { - return p->getStateCheck(button).triggered; + return p->getStateCheck(button).triggered; } bool Input::isRepeated(int button) { - return p->getStateCheck(button).repeated; + return p->getStateCheck(button).repeated; } bool Input::isReleased(int button) { @@ -1282,26 +1285,26 @@ unsigned long long Input::repeatTimeEx(int code, bool isVKey) { int Input::dir4Value() { - return p->dir4Data.active; + return p->dir4Data.active; } int Input::dir8Value() { - return p->dir8Data.active; + return p->dir8Data.active; } int Input::mouseX() { - RGSSThreadData &rtData = shState->rtData(); - - return (EventThread::mouseState.x - rtData.screenOffset.x) * rtData.sizeResoRatio.x; + RGSSThreadData &rtData = shState->rtData(); + + return (EventThread::mouseState.x - rtData.screenOffset.x) * rtData.sizeResoRatio.x; } int Input::mouseY() { - RGSSThreadData &rtData = shState->rtData(); - - return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y; + RGSSThreadData &rtData = shState->rtData(); + + return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y; } bool Input::getJoystickConnected() @@ -1359,5 +1362,5 @@ void Input::setClipboardText(char *text) Input::~Input() { - delete p; + delete p; }