diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 5f8af58..8e8aebd 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -291,10 +291,10 @@ void AnimationEditor::applyState() - addAction(ACTION_SWIMLEFT, KEY_J, -1); - addAction(ACTION_SWIMRIGHT, KEY_K, -1); - addAction(ACTION_SWIMUP, KEY_UP, -1); - addAction(ACTION_SWIMDOWN, KEY_DOWN, -1); + addAction(ACTION_SWIMLEFT, KEY_J); + addAction(ACTION_SWIMRIGHT, KEY_K); + addAction(ACTION_SWIMUP, KEY_UP); + addAction(ACTION_SWIMDOWN, KEY_DOWN); @@ -537,7 +537,7 @@ void AnimationEditor::redo() } } -void AnimationEditor::action(int id, int state, int source, InputDevice device) +void AnimationEditor::action(int id, int state, int source, InputDeviceType device) { if (editingBone && state) { @@ -726,14 +726,14 @@ void AnimationEditor::update(float dt) if (editingStrip) { - if (isActing(ACTION_SWIMLEFT, -1)) + if (isActing(ACTION_SWIMLEFT)) moveBoneStripPoint(Vector(-dt, 0)); - if (isActing(ACTION_SWIMRIGHT, -1)) + if (isActing(ACTION_SWIMRIGHT)) moveBoneStripPoint(Vector(dt, 0)); - if (isActing(ACTION_SWIMUP, -1)) + if (isActing(ACTION_SWIMUP)) moveBoneStripPoint(Vector(0, -dt)); - if (isActing(ACTION_SWIMDOWN, -1)) + if (isActing(ACTION_SWIMDOWN)) moveBoneStripPoint(Vector(0, dt)); } int spd = 1; diff --git a/Aquaria/AnimationEditor.h b/Aquaria/AnimationEditor.h index 3fa64f5..343e1a2 100644 --- a/Aquaria/AnimationEditor.h +++ b/Aquaria/AnimationEditor.h @@ -113,7 +113,7 @@ public: std::vector keyframeWidgets; - void action(int id, int state, int source, InputDevice device); + void action(int id, int state, int source, InputDeviceType device); void rebuildKeyframeWidgets(); diff --git a/Aquaria/AquariaMenuItem.cpp b/Aquaria/AquariaMenuItem.cpp index f80619c..191d305 100644 --- a/Aquaria/AquariaMenuItem.cpp +++ b/Aquaria/AquariaMenuItem.cpp @@ -89,7 +89,7 @@ void AquariaGuiElement::setFocus(bool v) if (v) { currentFocus = this; - if (dsq->getInputMode() == INPUT_JOYSTICK || dsq->getInputMode() == INPUT_KEYBOARD) + if (dsq->getInputMode() == INP_DEV_JOYSTICK || dsq->getInputMode() == INP_DEV_KEYBOARD) core->setMousePosition(getGuiPosition()); AquariaGuiElement *gui=0, *guiThis = (AquariaGuiElement*)this; @@ -162,49 +162,13 @@ void AquariaGuiElement::UpdateGlobalFocus(float dt) Direction AquariaGuiElement::GetDirection() { Direction dir = DIR_NONE; - - // This joystick code is already supposed to send ACTION_MENU*. - // Actually some places depend on the actions to be sent, - // So checking this here might work for a few cases, - // but others will break. - // I'll leave this in here for now -- fg - /*Vector p; - for(size_t i = 0; i < core->getNumJoysticks(); ++i) - if(Joystick *j = core->getJoystick(i)) - if(j->isEnabled()) - { - p = core->getJoystick(i)->position; - if(!p.isLength2DIn(0.4f)) - break; - } - - if (!p.isLength2DIn(0.4f)) + StateObject *obj = dsq->getTopStateObject(); // usually Game... + if (obj) { - if (fabsf(p.x) > fabsf(p.y)) - { - if (p.x > 0) - dir = DIR_RIGHT; - else - dir = DIR_LEFT; - } - else - { - if (p.y > 0) - dir = DIR_DOWN; - else - dir = DIR_UP; - } - } - else*/ - { - StateObject *obj = dsq->getTopStateObject(); // usually Game... - if (obj) - { - if (obj->isActing(ACTION_MENULEFT, -1)) dir = DIR_LEFT; - else if (obj->isActing(ACTION_MENURIGHT, -1)) dir = DIR_RIGHT; - else if (obj->isActing(ACTION_MENUUP, -1)) dir = DIR_UP; - else if (obj->isActing(ACTION_MENUDOWN, -1)) dir = DIR_DOWN; - } + if (obj->isActing(ACTION_MENULEFT)) dir = DIR_LEFT; + else if (obj->isActing(ACTION_MENURIGHT)) dir = DIR_RIGHT; + else if (obj->isActing(ACTION_MENUUP)) dir = DIR_UP; + else if (obj->isActing(ACTION_MENUDOWN)) dir = DIR_DOWN; } return dir; } @@ -343,9 +307,6 @@ void AquariaGuiQuad::onUpdate(float dt) Quad::onUpdate(dt); } -// Joystick input threshold at which we start sliding (0.0-1.0); must be -// less than updateMovement() threshold. -const float SLIDER_JOY_THRESHOLD = 0.39f; // Initial delay before repeating for slider input (seconds). const float SLIDER_REPEAT_DELAY = 0.4f; // Scale factor for delay as repeats continue. @@ -382,26 +343,10 @@ bool AquariaSlider::doSliderInput(float dt) float inputAmount; // How much to adjust by? - // disabled the jaxis threshold check; - // ACTION_MENU* should be sent automatically when above the threshold -- fg - /*Vector jpos; - for(size_t i = 0; i < core->getNumJoysticks(); ++i) - if(Joystick *j = core->getJoystick(i)) - if(j->isEnabled()) - { - jpos = core->getJoystick(i)->position; - if(fabsf(jpos.x) > SLIDER_JOY_THRESHOLD) - break; - }*/ - StateObject *obj = dsq->getTopStateObject(); - /*if (jpos.x <= -SLIDER_JOY_THRESHOLD) + if (obj && obj->isActing(ACTION_MENULEFT)) inputAmount = -0.1f; - else if (jpos.x >= SLIDER_JOY_THRESHOLD) - inputAmount = +0.1f; - else*/ if (obj && obj->isActing(ACTION_MENULEFT, -1)) - inputAmount = -0.1f; - else if (obj && obj->isActing(ACTION_MENURIGHT, -1)) + else if (obj && obj->isActing(ACTION_MENURIGHT)) inputAmount = +0.1f; else inputAmount = 0; @@ -484,27 +429,81 @@ bool AquariaCheckBox::isGuiVisible() AquariaKeyConfig *AquariaKeyConfig::waitingForInput = 0; +enum KeyMapResult +{ + KMR_NONE, + KMR_ASSIGNED, + KMR_CLEARED, + KMR_CANCELLED +}; -AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputSetType inputSetType, int inputIdx) +// created on the stack while waiting for keys to be pressed +class InputSniffer : public IInputMapper +{ +public: + InputSniffer(InputDeviceType dev) : _dev(dev), _res(KMR_NONE) {} + + virtual void input(const RawInput *inp) + { + if(_res != KMR_NONE) + return; + + if(inp->src.deviceType == INP_DEV_KEYBOARD && inp->src.ctrlType == INP_CTRL_BUTTON && inp->u.pressed) + { + switch(inp->src.ctrlID) + { + case KEY_ESCAPE: _res = KMR_CANCELLED; return; + case KEY_BACKSPACE: + case KEY_DELETE: _res = KMR_CLEARED; return; + } + } + // TODO controllerfixup: check if input is "interesting" enough + if(inp->src.deviceType == _dev) + { + _res = KMR_ASSIGNED; + stored = *inp; + } + } + + KeyMapResult get(RawInput *inp) const + { + if(_res == KMR_ASSIGNED) + *inp = stored; + return _res; + } + + RawInput stored; + InputDeviceType _dev; + KeyMapResult _res; +}; + +static KeyMapResult waitForInput(RawInput *raw, InputDeviceType dev) +{ + InputSniffer sniff(dev); + KeyMapResult km; + for(;;) + { + km = sniff.get(raw); + if(km != KMR_NONE) + break; + dsq->run(0.1f, true); + } + return km; +} + +AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputDeviceType dev, unsigned slot) : AquariaGuiElement(), RenderObject() , actionInputName(actionInputName) -, inputSetType(inputSetType) -, inputIdx(inputIdx) +, inputDevType(dev) +, inputSlot(slot) +, inputField(ActionInput::GetField(dev, slot)) , actionSetIndex(0) , rejectJoyAxis(false) { bg = new Quad(); bg2 = new Quad(); - if (inputSetType == INPUTSET_OTHER) - { - bg->setWidthHeight(40, 20); - bg2->setWidthHeight(40, 20); - } - else - { - bg->setWidthHeight(90, 20); - bg2->setWidthHeight(90, 20); - } + bg->setWidthHeight(90, 20); + bg2->setWidthHeight(90, 20); bg->color = Vector(0.5f, 0.5f, 0.5f); bg->alphaMod = 0; @@ -516,7 +515,6 @@ AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputSetT addChild(bg2, PM_POINTER); - keyConfigFont = new TTFText(&dsq->fontArialSmallest); keyConfigFont->setAlign(ALIGN_CENTER); @@ -589,342 +587,29 @@ void AquariaKeyConfig::onUpdate(float dt) inLoop = true; - unsigned int *k = 0; + ActionInput &ai = as.ensureActionInput(actionInputName); - ActionInput *ai = 0; - - bool used = false; - - if (inputSetType != INPUTSET_OTHER) - { - ai = as.getActionInputByName(actionInputName); - - if (!ai) - { - exit_error("Could not find actionInput: " + actionInputName); - } - switch(inputSetType) - { - case INPUTSET_KEY: - k = &ai->data.single.key[inputIdx]; - break; - case INPUTSET_MOUSE: - k = &ai->data.single.mse[inputIdx]; - break; - case INPUTSET_JOY: - k = &ai->data.single.joy[inputIdx]; - break; - case INPUTSET_NONE: - case INPUTSET_OTHER: - k = 0; - break; - } - used = k && *k; - } - - - if (inputSetType == INPUTSET_OTHER) - { - if (actionInputName == "s1ax") - k = &as.joycfg.s1ax; - else if (actionInputName == "s1ay") - k = &as.joycfg.s1ay; - else if (actionInputName == "s2ax") - k = &as.joycfg.s2ax; - else if (actionInputName == "s2ay") - k = &as.joycfg.s2ay; - used = k && int(*k) >= 0; - } + bool used = ai.hasEntry(inputSlot); if(used) bg2->alphaMod = 0.3f; else bg2->alphaMod = 0; - if (waitingForInput == this) + if (waitingForInput != this) + keyConfigFont->setText(ai.prettyPrintField(inputField, as.joystickID)); + else { std::string s; s.reserve(6); s = "_"; - for (int i = 0; i < int(dsq->game->getTimer(5)); i++) + const int tm = int(dsq->game->getTimer(5)); + for (int i = 0; i < tm; i++) { s += "_"; } keyConfigFont->setText(s); } - else - { - if (inputSetType != INPUTSET_OTHER) - { - keyConfigFont->setText(getInputCodeToUserString(*k, as.joystickID)); - } - else - { - if(*k >= 0) - { - std::ostringstream os; - os << (*k); - keyConfigFont->setText(os.str()); - } - else - { - keyConfigFont->setText(getInputCodeToUserString(0, as.joystickID)); - } - } - } - - if (waitingForInput == this) - { - switch(inputSetType) - { - case INPUTSET_OTHER: - { - if (k) - { - int ac = -1; - bool clear = false; - bool abort = false; - for (int i = 0; i < KEY_MAXARRAY; i++) - { - if (core->getKeyState(i)) - { - if(i == KEY_BACKSPACE || i == KEY_DELETE) - clear = true; - else if (i == KEY_ESCAPE) - abort = true; - else - { - switch(i) - { - #define K(k) case k: ac = i-k; break - K(KEY_0); - K(KEY_1); - K(KEY_2); - K(KEY_3); - K(KEY_4); - K(KEY_5); - K(KEY_6); - K(KEY_7); - K(KEY_8); - K(KEY_9); - #undef K - } - } - - while (dsq->game->getKeyState(i)) - { - dsq->run(0.1f, true); - } - } - } - - if(ac < 0) - { - Joystick *j = core->getJoystick(as.joystickID); - if(j) - for(int i = 0; i < MAX_JOYSTICK_AXIS; ++i) - { - float ax = j->getAxisUncalibrated(i); - if(fabsf(ax) > JOY_AXIS_THRESHOLD) - { - ac = i; - while (fabsf(j->getAxisUncalibrated(i)) > JOY_AXIS_THRESHOLD) - dsq->run(0.1f, true); - break; - } - } - } - - if(ac >= 0 || abort || clear) - { - toggleEnterKey(0); - waitingForInput = 0; - AquariaGuiElement::canDirMoveGlobal = true; - if(!abort) - { - if(clear || ac == *k) - *k = -1; - else - *k = ac; - } - } - } - } - break; - case INPUTSET_KEY: - { - for (int i = 0; i < KEY_MAXARRAY; i++) - { - if (core->getKeyState(i)) - { - if(*k == i) // clear key if pressed again - *k = 0; - else if(i != KEY_ESCAPE) - { - if (i == KEY_DELETE || i == KEY_BACKSPACE) - *k = 0; - else - *k = i; - } - - while (dsq->game->getKeyState(i)) - { - dsq->run(0.1f, true); - } - - toggleEnterKey(0); - waitingForInput = 0; - AquariaGuiElement::canDirMoveGlobal = true; - break; - } - } - } - break; - case INPUTSET_MOUSE: - { - bool clear = false; - bool abort = false; - unsigned int ac = 0; - if (core->getKeyState(KEY_DELETE) || core->getKeyState(KEY_BACKSPACE)) - { - while(core->getKeyState(KEY_DELETE) || core->getKeyState(KEY_BACKSPACE)) - dsq->run(0.1f, true); - clear = true; - } - else if(core->getKeyState(KEY_ESCAPE)) - { - while(core->getKeyState(KEY_ESCAPE)) - dsq->run(0.1f, true); - abort = true; - } - else if(dsq->mouse.rawButtonMask) - { - MouseButtons btns = dsq->mouse.buttons; - - while(dsq->mouse.rawButtonMask) - dsq->run(0.1f, true); - - if(btns.left) - ac = MOUSE_BUTTON_LEFT; - else if(btns.right) - ac = MOUSE_BUTTON_RIGHT; - else if(btns.middle) - ac = MOUSE_BUTTON_MIDDLE; - else - { - for(unsigned i = 0; i < mouseExtraButtons; ++i) - if(btns.extra[i]) - { - ac = MOUSE_BUTTON_EXTRA_START+i; - break; - } - } - } - - if(ac || clear || abort) - { - toggleEnterKey(0); - waitingForInput = 0; - AquariaGuiElement::canDirMoveGlobal = true; - - if(!abort) - { - if(clear || *k == ac) // clear key if pressed again - *k = 0; - else - *k = ac; - } - } - } - break; - case INPUTSET_JOY: - { - size_t ac = 0; - bool clear = false; - bool abort = false; - if (core->getKeyState(KEY_DELETE) || core->getKeyState(KEY_BACKSPACE)) - { - clear = true; - } - else if(core->getKeyState(KEY_ESCAPE)) - { - abort = true; - while(core->getKeyState(KEY_ESCAPE)) - dsq->run(0.1f, true); - } - else - { - Joystick *j = core->getJoystick(as.joystickID); - if(j) - { - for (size_t i = 0; i < MAX_JOYSTICK_BTN; i++) - if (j->getButton(i)) - { - ac = JOY_BUTTON_0 + i; - while (j->getButton(i)) - dsq->run(0.1f, true); // skip recursion check; we're already in the menu so this would always warn - break; - } - - if(!ac) - for(size_t i = 0; i < MAX_JOYSTICK_AXIS; ++i) - { - float ax = j->getAxisUncalibrated(i); - if(fabsf(ax) > JOY_AXIS_THRESHOLD) - { - ac = (ax < 0.0f ? JOY_AXIS_0_NEG : JOY_AXIS_0_POS) + i; - while (fabsf(j->getAxisUncalibrated(i)) > JOY_AXIS_THRESHOLD) - dsq->run(0.1f, true); - break; - } - } - - if(!ac) - for(size_t i = 0; i < MAX_JOYSTICK_HATS; ++i) - { - JoyHatDirection hd = j->getHat(i); - if(hd != JOY_HAT_DIR_CENTERED) - { - ac = joyHatToActionButton(i, hd); - while (j->getHat(i) != JOY_HAT_DIR_CENTERED) - dsq->run(0.1f, true); - break; - } - } - } - else - clear = true; - } - - if(abort || ac || clear) - { - toggleEnterKey(0); - waitingForInput = 0; - AquariaGuiElement::canDirMoveGlobal = true; - - if(rejectJoyAxis && ( - (ac >= JOY_AXIS_0_POS && ac < JOY_AXIS_END_POS) - || (ac >= JOY_AXIS_0_NEG && ac < JOY_AXIS_END_NEG) - )) - { - dsq->sound->playSfx("denied"); - abort = true; - } - - if(!abort) - { - if(clear || *k == ac) // clear key if pressed again - *k = 0; - else - *k = ac; - } - } - } - break; - case INPUTSET_NONE: - break; - } - } Vector p = bg->getWorldPosition(); @@ -938,7 +623,7 @@ void AquariaKeyConfig::onUpdate(float dt) toggleEnterKey(-1); } - + // FIXME controllerfixup: don't rely on mouse emulation here? if (!keyDown && (core->mouse.buttons.left || core->mouse.buttons.right)) { keyDown = true; @@ -958,6 +643,19 @@ void AquariaKeyConfig::onUpdate(float dt) waitingForInput = this; toggleEnterKey(1); AquariaGuiElement::canDirMoveGlobal = false; + + RawInput raw; + switch(waitForInput(&raw, inputDevType)) + { + case KMR_ASSIGNED: + ai.ImportField(raw, inputField); + break; + case KMR_CLEARED: + ai.clearEntry(inputField); + break; + case KMR_CANCELLED: + break; + } } } } @@ -1218,7 +916,7 @@ void AquariaButton::goDown() buttonlabel->position = Vector(0, 7); } -void AquariaButton::action(int actionID, int state, int source, InputDevice device) +void AquariaButton::action(int actionID, int state, int source, InputDeviceType device) { if(actionID == ACTION_PRIMARY) { diff --git a/Aquaria/AquariaMenuItem.h b/Aquaria/AquariaMenuItem.h index db5483b..fbafae0 100644 --- a/Aquaria/AquariaMenuItem.h +++ b/Aquaria/AquariaMenuItem.h @@ -87,7 +87,7 @@ public: bool useQuad(const std::string &tex); void useGlow(const std::string &tex, int w, int h); void useSound(const std::string &tex); - virtual void action(int actionID, int state, int source, InputDevice device) {} + virtual void action(int actionID, int state, int source, InputDeviceType device) {} virtual bool isCursorInMenuItem(); Vector getGuiPosition(); @@ -166,7 +166,8 @@ protected: class AquariaKeyConfig : public AquariaGuiElement, public RenderObject { public: - AquariaKeyConfig(const std::string &actionInputName, InputSetType type, int idx); + // field goes from 0 to INP_NUMFIELDS-1 + AquariaKeyConfig(const std::string &actionInputName, InputDeviceType type, unsigned field); void destroy(); Vector getGuiPosition(); @@ -186,8 +187,8 @@ protected: std::string actionInputName; - InputSetType inputSetType; - int inputIdx; + const InputDeviceType inputDevType; + const unsigned inputSlot, inputField; TTFText *keyConfigFont; Quad *bg, *bg2; size_t actionSetIndex; @@ -267,7 +268,7 @@ public: protected: - virtual void action(int actionID, int state, int source, InputDevice device); + virtual void action(int actionID, int state, int source, InputDeviceType device); virtual void onUpdate(float dt); virtual void onToggleHighlight(bool on); diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 8391c76..522c1c4 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -128,34 +128,32 @@ void Avatar::bindInput() ActionMapper::clearActions(); ActionMapper::clearCreatedEvents(); - for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + const NamedAction actions[] = { - const ActionSet& as = dsq->user.control.actionSets[i]; - int sourceID = (int)i; + { "PrimaryAction", ACTION_PRIMARY}, + { "SecondaryAction", ACTION_SECONDARY}, - as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID); - as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID); + { "SwimUp", ACTION_SWIMUP}, + { "SwimDown", ACTION_SWIMDOWN}, + { "SwimLeft", ACTION_SWIMLEFT}, + { "SwimRight", ACTION_SWIMRIGHT}, - as.importAction(this, "SwimUp", ACTION_SWIMUP, sourceID); - as.importAction(this, "SwimDown", ACTION_SWIMDOWN, sourceID); - as.importAction(this, "SwimLeft", ACTION_SWIMLEFT, sourceID); - as.importAction(this, "SwimRight", ACTION_SWIMRIGHT, sourceID); + { "SongSlot1", ACTION_SONGSLOT1}, + { "SongSlot2", ACTION_SONGSLOT2}, + { "SongSlot3", ACTION_SONGSLOT3}, + { "SongSlot4", ACTION_SONGSLOT4}, + { "SongSlot5", ACTION_SONGSLOT5}, + { "SongSlot6", ACTION_SONGSLOT6}, + { "SongSlot7", ACTION_SONGSLOT7}, + { "SongSlot8", ACTION_SONGSLOT8}, + { "SongSlot9", ACTION_SONGSLOT9}, + { "SongSlot10", ACTION_SONGSLOT10}, - as.importAction(this, "SongSlot1", ACTION_SONGSLOT1, sourceID); - as.importAction(this, "SongSlot2", ACTION_SONGSLOT2, sourceID); - as.importAction(this, "SongSlot3", ACTION_SONGSLOT3, sourceID); - as.importAction(this, "SongSlot4", ACTION_SONGSLOT4, sourceID); - as.importAction(this, "SongSlot5", ACTION_SONGSLOT5, sourceID); - as.importAction(this, "SongSlot6", ACTION_SONGSLOT6, sourceID); - as.importAction(this, "SongSlot7", ACTION_SONGSLOT7, sourceID); - as.importAction(this, "SongSlot8", ACTION_SONGSLOT8, sourceID); - as.importAction(this, "SongSlot9", ACTION_SONGSLOT9, sourceID); - as.importAction(this, "SongSlot10", ACTION_SONGSLOT10, sourceID); - - as.importAction(this, "Revert", ACTION_REVERT, sourceID); - as.importAction(this, "Look", ACTION_LOOK, sourceID); - as.importAction(this, "Roll", ACTION_ROLL, sourceID); - } + { "Revert", ACTION_REVERT}, + { "Look", ACTION_LOOK}, + { "Roll", ACTION_ROLL} + }; + ImportInput(actions); } // note: z is set to 1.0 when we want the aim to be used as the shot direction @@ -163,31 +161,22 @@ void Avatar::bindInput() Vector Avatar::getAim() { Vector d; - if (dsq->getInputMode() == INPUT_JOYSTICK) + float z = 1; + if (dsq->getInputMode() == INP_DEV_JOYSTICK) { - for(size_t i = 0; i < core->getNumJoysticks(); ++i) - if(Joystick *j = core->getJoystick(i)) - if(j->isEnabled() && !j->rightStick.isZero()) - { - d = j->rightStick * 300; - d.z = 1; - break; - } + d = dsq->playerInput.getStick2(); if(d.isZero()) - for(size_t i = 0; i < core->getNumJoysticks(); ++i) - if(Joystick *j = core->getJoystick(i)) - if(j->isEnabled() && !j->position.isZero()) - { - d = j->position * 300; - break; - } + { + d = dsq->playerInput.getStick1(); + z = 0; + } + d *= 300; + d.z = z; } else - { d = dsq->getGameCursorPosition() - position; - d.z = 1; - } + d.z = z; if (d.isZero()) d = getForwardAim(); @@ -209,7 +198,7 @@ void Avatar::onAnimationKeyPassed(int key) Entity::onAnimationKeyPassed(key); } -Vector randCirclePos(Vector position, int radius) +static Vector randCirclePos(Vector position, int radius) { float a = ((rand()%360)*(2*PI))/360.0f; return position + Vector(sinf(a), cosf(a))*radius; @@ -1100,7 +1089,7 @@ void Avatar::onDamage(DamageData &d) if (healthWillBe<=0) t = 2; - dsq->rumble(d.damage, d.damage, 0.4f, _lastActionSourceID, _lastActionInputDevice); + dsq->rumble(d.damage, d.damage, 0.4f); if (d.damage > 0) { //dsq->shakeCamera(5, t); @@ -1312,12 +1301,12 @@ void Avatar::clearTargets() } } -void Avatar::openSingingInterface(InputDevice device) +void Avatar::openSingingInterface(InputDeviceType device) { if (!singing && health > 0 && !isEntityDead() && !blockSinging) { //core->mouse.position = Vector(400,300); - if (device != INPUT_MOUSE) + if (device != INP_DEV_MOUSE) { core->centerMouse(); //core->setMousePosition(Vector(400,300)); @@ -1340,7 +1329,7 @@ void Avatar::openSingingInterface(InputDevice device) dsq->game->songLineRender->clear(); - if (device == INPUT_JOYSTICK) + if (device == INP_DEV_JOYSTICK) { core->setMousePosition(core->center); } @@ -1730,7 +1719,7 @@ void Avatar::updateSingingInterface(float dt) { if (songIcons.size()>0 && songIcons[0]->alpha.x > 0) { - if (dsq->getInputMode() != INPUT_JOYSTICK && !core->mouse.change.isZero()) + if (dsq->getInputMode() != INP_DEV_JOYSTICK && !core->mouse.change.isZero()) { if (dsq->game->songLineRender && songIcons[0]->alpha.x == 1) { @@ -1756,9 +1745,10 @@ void Avatar::updateSingingInterface(float dt) } else { - if (dsq->getInputMode() == INPUT_JOYSTICK) + if (dsq->getInputMode() == INP_DEV_JOYSTICK) { Vector d; + /* // FIXME controllerfixup for(size_t i = 0; i < core->getNumJoysticks(); ++i) if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) @@ -1767,6 +1757,7 @@ void Avatar::updateSingingInterface(float dt) if(!d.isZero()) break; } + */ if (d.isLength2DIn(JOYSTICK_NOTE_THRESHOLD)) { @@ -1948,7 +1939,7 @@ void Avatar::updateTargets(float dt, bool override) break; } } - if ((dsq->getInputMode() == INPUT_MOUSE || dsq->getInputMode() == INPUT_KEYBOARD) && !(wasDown && core->mouse.buttons.right)) + if ((dsq->getInputMode() == INP_DEV_MOUSE || dsq->getInputMode() == INP_DEV_KEYBOARD) && !(wasDown && core->mouse.buttons.right)) { wasDown = false; float mod = 1; @@ -2108,11 +2099,11 @@ void Avatar::updateTargetQuads(float dt) targetQuads[i]->position = cursorpos; if (dsq->continuity.form == FORM_ENERGY && isInputEnabled()) { - if (dsq->getInputMode() == INPUT_JOYSTICK && targetQuads[i]->isRunning()) + if (dsq->getInputMode() == INP_DEV_JOYSTICK && targetQuads[i]->isRunning()) { targetQuads[i]->stop(); } - else if (dsq->getInputMode() != INPUT_JOYSTICK && !targetQuads[i]->isRunning()) + else if (dsq->getInputMode() != INP_DEV_JOYSTICK && !targetQuads[i]->isRunning()) { targetQuads[i]->start(); } @@ -2147,7 +2138,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot) p = boneLeftArm->getWorldPosition(); //&& !dsq->game->isObstructed(TileVector(position)) /* - if (dsq->inputMode == INPUT_MOUSE && state.lockedToWall ) + if (dsq->inputMode == INP_DEV_MOUSE && state.lockedToWall ) dir = dsq->getGameCursorPosition() - p; else */ @@ -2168,7 +2159,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot) /* if (target) { - if (dsq->inputMode != INPUT_JOYSTICK && vel.isLength2DIn(50)) + if (dsq->inputMode != INP_DEV_JOYSTICK && vel.isLength2DIn(50)) { } else @@ -2189,7 +2180,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot) bool clearTargets = false; // allow autoAim if desired - if ((dsq->getInputMode() == INPUT_JOYSTICK && !aimAt) || dsq->user.control.autoAim) + if ((dsq->getInputMode() == INP_DEV_JOYSTICK && !aimAt) || dsq->user.control.autoAim) { if (targets.empty()) { @@ -2252,7 +2243,7 @@ bool Avatar::fireAtNearestValidEntity(const std::string &shot) } else { - //if (!dir.isLength2DIn(2) || dsq->inputMode == INPUT_JOYSTICK) + //if (!dir.isLength2DIn(2) || dsq->inputMode == INP_DEV_JOYSTICK) if (true) { s = dsq->game->fireShot(shot, this); @@ -2998,12 +2989,12 @@ bool Avatar::isMouseInputEnabled() return true; } -void Avatar::rmbd(int source, InputDevice device) +void Avatar::rmbd(int source, InputDeviceType device) { if (!isMouseInputEnabled() || isEntityDead()) return; if (dsq->continuity.form == FORM_NORMAL ) { - if (device == INPUT_MOUSE) + if (device == INP_DEV_MOUSE) { Vector diff = getVectorToCursorFromScreenCentre(); if (diff.getSquaredLength2D() < sqr(openSingingInterfaceRadius)) @@ -3020,7 +3011,7 @@ void Avatar::rmbd(int source, InputDevice device) } } -void Avatar::rmbu(int source, InputDevice device) +void Avatar::rmbu(int source, InputDeviceType device) { if (!isMouseInputEnabled() || isEntityDead()) return; @@ -3168,7 +3159,7 @@ void Avatar::onUpdateBoneLock() rotateToVec(wallNormal, 0.01f); } -void Avatar::lmbd(int source, InputDevice device) +void Avatar::lmbd(int source, InputDeviceType device) { if (!isMouseInputEnabled()) return; @@ -3210,7 +3201,7 @@ void Avatar::fallOffWall() } } -void Avatar::lmbu(int source, InputDevice device) +void Avatar::lmbu(int source, InputDeviceType device) { if (!isMouseInputEnabled()) return; @@ -3886,8 +3877,6 @@ Avatar::Avatar() : Entity(), ActionMapper() blockBackFlip = false; elementEffectMult = 1; - _lastActionSourceID = 9999; - _lastActionInputDevice = INPUT_NODEVICE; } void Avatar::revert() @@ -4056,11 +4045,11 @@ void Avatar::startBurst() { if (!riding && canBurst() && (joystickMove || getVectorToCursor().getSquaredLength2D() > sqr(BURST_DISTANCE)) && getState() != STATE_PUSH && (!skeletalSprite.getCurrentAnimation() || (skeletalSprite.getCurrentAnimation()->name != "spin")) - && _isUnderWater && !isActing(ACTION_ROLL, -1)) + && _isUnderWater && !isActing(ACTION_ROLL)) { if (!bursting && burst == 1) { - dsq->rumble(0.2f, 0.2f, 0.2f, _lastActionSourceID, _lastActionInputDevice); + dsq->rumble(0.2f, 0.2f, 0.2f); if (dsq->continuity.form != FORM_BEAST) wakeEmitter.start(); dsq->game->playBurstSound(pushingOffWallEffect>0); @@ -4133,7 +4122,7 @@ void Avatar::startWallBurst(bool useCursor) { lastBurstType = BURST_WALL; - dsq->rumble(0.22f, 0.22f, 0.2f, _lastActionSourceID, _lastActionInputDevice); + dsq->rumble(0.22f, 0.22f, 0.2f); bittenEntities.clear(); if (useCursor) { @@ -4171,10 +4160,10 @@ void Avatar::startWallBurst(bool useCursor) bool Avatar::isActionAndGetDir(Vector& dir) { - bool dL = isActing(ACTION_SWIMLEFT, -1); - bool dR = isActing(ACTION_SWIMRIGHT, -1); - bool dU = isActing(ACTION_SWIMUP, -1); - bool dD = isActing(ACTION_SWIMDOWN, -1); + bool dL = isActing(ACTION_SWIMLEFT); + bool dR = isActing(ACTION_SWIMRIGHT); + bool dU = isActing(ACTION_SWIMUP); + bool dD = isActing(ACTION_SWIMDOWN); Vector a; if (dL) a += Vector(-1,0); @@ -4198,7 +4187,8 @@ Vector Avatar::getFakeCursorPosition() if(isActionAndGetDir(dir)) return dir * 350; - for(size_t i = 0; i < core->getNumJoysticks(); ++i) + // FIXME controllerfixup + /*for(size_t i = 0; i < core->getNumJoysticks(); ++i) if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) { @@ -4209,7 +4199,7 @@ Vector Avatar::getFakeCursorPosition() const float distance = minMouse + ((axisInput - JOYSTICK_LOW_THRESHOLD) * axisMult); return (j->position * (distance / axisInput)); } - } + }*/ return dir; } @@ -4220,7 +4210,7 @@ Vector Avatar::getVectorToCursorFromScreenCentre() return getVectorToCursor(); else { - if (dsq->getInputMode() != INPUT_MOUSE) + if (dsq->getInputMode() != INP_DEV_MOUSE) return getFakeCursorPosition(); return (core->mouse.position+offset) - Vector(400,300); } @@ -4232,21 +4222,18 @@ Vector Avatar::getVectorToCursor(bool trueMouse) Vector pos = dsq->getGameCursorPosition(); - if (!trueMouse && dsq->getInputMode() != INPUT_MOUSE) + if (!trueMouse && dsq->getInputMode() != INP_DEV_MOUSE) return getFakeCursorPosition(); return pos - (position+offset); //return core->mouse.position - Vector(400,300); } -void Avatar::action(int id, int state, int source, InputDevice device) +void Avatar::action(int id, int state, int source, InputDeviceType device) { if(dsq->game->isIgnoreAction((AquariaActions)id)) return; - _lastActionSourceID = source; - _lastActionInputDevice = device; - if (id == ACTION_PRIMARY) { if (state) lmbd(source, device); else lmbu(source, device); } if (id == ACTION_SECONDARY) { if (state) rmbd(source, device); else rmbu(source, device); } @@ -4313,7 +4300,7 @@ void Avatar::action(int id, int state, int source, InputDevice device) // done for wall bursts, but the movement there is fast // enough that people probably won't notice, so I skipped // that. Sorry about the ugliness. --achurch - if (device != INPUT_MOUSE) + if (device != INP_DEV_MOUSE) skeletalSprite.transitionAnimate("swim", ANIM_TRANSITION, -1); } } @@ -4515,7 +4502,7 @@ void Avatar::splash(bool down) //dsq->postProcessingFx.disable(FXT_RADIALBLUR); if (_isUnderWater && core->afterEffectManager) core->afterEffectManager->addEffect(new ShockEffect(Vector(core->width/2, core->height/2),core->screenCenter,0.08f,0.05f,22,0.2f, 1.2f)); - dsq->rumble(0.7f, 0.7f, 0.2f, _lastActionSourceID, _lastActionInputDevice); + dsq->rumble(0.7f, 0.7f, 0.2f); plungeEmitter.start(); core->sound->playSfx("GoUnder"); @@ -4992,13 +4979,13 @@ void Avatar::updateRoll(float dt) stopRoll(); } } - const bool rollact = isActing(ACTION_ROLL, -1); + const bool rollact = isActing(ACTION_ROLL); if (!_isUnderWater && rollact) { stopRoll(); } - if (!core->mouse.buttons.left && dsq->getInputMode() == INPUT_MOUSE && !rollact) + if (!core->mouse.buttons.left && dsq->getInputMode() == INP_DEV_MOUSE && !rollact) { if (rolling) stopRoll(); @@ -5390,7 +5377,7 @@ void Avatar::onUpdate(float dt) } } - if (!dsq->game->isPaused() && isActing(ACTION_LOOK, -1) && !dsq->game->avatar->isSinging() && dsq->game->avatar->isInputEnabled() && !dsq->game->isInGameMenu()) + if (!dsq->game->isPaused() && isActing(ACTION_LOOK) && !dsq->game->avatar->isSinging() && dsq->game->avatar->isInputEnabled() && !dsq->game->isInGameMenu()) { looking = 1; } @@ -5790,7 +5777,7 @@ void Avatar::onUpdate(float dt) // revert stuff float revertGrace = 0.4f; static bool revertButtonsAreDown = false; - if (inputEnabled && (dsq->getInputMode() == INPUT_KEYBOARD || dsq->getInputMode() == INPUT_MOUSE) && (!pathToActivate && !entityToActivate)) + if (inputEnabled && (dsq->getInputMode() == INP_DEV_KEYBOARD || dsq->getInputMode() == INP_DEV_MOUSE) && (!pathToActivate && !entityToActivate)) { if (dsq->continuity.form != FORM_NORMAL && (core->mouse.pure_buttons.left && core->mouse.pure_buttons.right) && getVectorToCursor(true).isLength2DIn(minMouse)) { @@ -6133,11 +6120,11 @@ void Avatar::onUpdate(float dt) float len = 0; - if (dsq->isMiniMapCursorOkay() && !isActing(ACTION_ROLL, -1) && + if (dsq->isMiniMapCursorOkay() && !isActing(ACTION_ROLL) && _isUnderWater && !riding && !boneLock.on && - (movingOn || ((dsq->getInputMode() == INPUT_JOYSTICK || dsq->getInputMode()== INPUT_KEYBOARD) || (core->mouse.buttons.left || bursting)))) + (movingOn || ((dsq->getInputMode() == INP_DEV_JOYSTICK || dsq->getInputMode()== INP_DEV_KEYBOARD) || (/*core->mouse.buttons.left ||*/ bursting)))) { - const bool isMouse = dsq->getInputMode() == INPUT_MOUSE; + const bool isMouse = dsq->getInputMode() == INP_DEV_MOUSE; if (isMouse || !this->singing) { addVec = getVectorToCursorFromScreenCentre();//getVectorToCursor(); @@ -6145,7 +6132,7 @@ void Avatar::onUpdate(float dt) if (isMouse) { static Vector lastAddVec; - if (!isActing(ACTION_PRIMARY, -1) && bursting) + if (!isActing(ACTION_PRIMARY) && bursting) { addVec = lastAddVec; } @@ -6158,7 +6145,7 @@ void Avatar::onUpdate(float dt) if (addVec.isLength2DIn(minMouse)) { - if (dsq->getInputMode() == INPUT_JOYSTICK) + if (dsq->getInputMode() == INP_DEV_JOYSTICK) addVec = Vector(0,0,0); } @@ -6187,7 +6174,7 @@ void Avatar::onUpdate(float dt) // For joystick/keyboard control, don't stop unless // the Swim (primary action) button is pressed with // no movement input. --achurch - if ((isMouse || isActing(ACTION_PRIMARY, -1)) + if ((isMouse || isActing(ACTION_PRIMARY)) && addVec.isLength2DIn(STOP_DISTANCE)) { vel *= 0.9f; @@ -6275,14 +6262,14 @@ void Avatar::onUpdate(float dt) // here for roll key? // seems like this isn't reached //if (isActing("roll")) - if (isActing(ACTION_ROLL, -1)) + if (isActing(ACTION_ROLL)) { //debugLog("here"); } else { float t = 0; - if (dsq->getInputMode() == INPUT_KEYBOARD) + if (dsq->getInputMode() == INP_DEV_KEYBOARD) t = 0.1f; rotateToVec(addVec, t); } diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index 1321bc8..9821524 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -138,7 +138,7 @@ public: Avatar(); virtual ~Avatar(); void destroy(); - void action(int actionID, int state, int source, InputDevice device); + void action(int actionID, int state, int source, InputDeviceType device); AvatarState state; float burst, burstTimer; float burstDelay; @@ -179,7 +179,7 @@ public: void startBurstCommon(); - void openSingingInterface(InputDevice device); + void openSingingInterface(InputDeviceType device); void closeSingingInterface(); void updateSingingInterface(float dt); @@ -331,9 +331,6 @@ public: bool blockBackFlip; - int getLastActionSourceID() const { return _lastActionSourceID; } - InputDevice getLastActionInputDevice() const { return _lastActionInputDevice; } - protected: void setSongIconPositions(); @@ -440,11 +437,11 @@ protected: Quad *glow; bool swimming; - void lmbd(int source, InputDevice device); - void lmbu(int source, InputDevice device); + void lmbd(int source, InputDeviceType device); + void lmbu(int source, InputDeviceType device); - void rmbd(int source, InputDevice device); - void rmbu(int source, InputDevice device); + void rmbd(int source, InputDeviceType device); + void rmbu(int source, InputDeviceType device); bool charging; @@ -467,10 +464,6 @@ protected: int _collisionAvoidRange; float _collisionAvoidMod; - - int _lastActionSourceID; - InputDevice _lastActionInputDevice; - }; #endif diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index ace7e23..0447c80 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -193,7 +193,7 @@ DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir) subbox = 0; modSelectorScr = 0; blackout = 0; - lastInputMode = INPUT_MOUSE; + lastInputMode = INP_DEV_MOUSE; overlay = 0; recentSaveSlot = -1; arialFontData = 0; @@ -249,24 +249,26 @@ void DSQ::onWindowResize(int w, int h) screenTransition->reloadDevice(); } -void DSQ::rumble(float leftMotor, float rightMotor, float time, int source, InputDevice device) +void DSQ::rumble(float leftMotor, float rightMotor, float time, int playerID /* = -1 */) { - if (device == INPUT_JOYSTICK) - { - if(source < 0) - for(size_t i = 0; i < user.control.actionSets.size(); ++i) - { - const ActionSet& as = user.control.actionSets[i]; - if(Joystick *j = core->getJoystick(as.joystickID)) - j->rumble(leftMotor, rightMotor, time); - } - else if(source < (int)user.control.actionSets.size()) + if(lastInputMode != INP_DEV_JOYSTICK) + return; + + /* // FIXME controllerfixup + if(source < 0) + for(size_t i = 0; i < user.control.actionSets.size(); ++i) { - const ActionSet& as = user.control.actionSets[source]; + const ActionSet& as = user.control.actionSets[i]; if(Joystick *j = core->getJoystick(as.joystickID)) j->rumble(leftMotor, rightMotor, time); } + else if(source < (int)user.control.actionSets.size()) + { + const ActionSet& as = user.control.actionSets[source]; + if(Joystick *j = core->getJoystick(as.joystickID)) + j->rumble(leftMotor, rightMotor, time); } + */ } void DSQ::newGame() @@ -502,7 +504,6 @@ void DSQ::debugMenu() if (core->getShiftState()) { - core->frameOutputMode = false; dsq->game->togglePause(true); std::string s = dsq->getUserInputString(stringbank.get(2012), ""); stringToUpper(s); @@ -630,32 +631,6 @@ void DSQ::debugMenu() is >> read >> nm; dsq->continuity.setCostume(nm); } - else if (c == 'R') - { - dsq->demo.toggleRecord(true); - } - else if (c == 'P') - { - dsq->demo.togglePlayback(true); - } - else if (c == 'T') - { - if (dsq->demo.frames.size()> 0) - { - dsq->game->avatar->position = dsq->demo.frames[0].avatarPos; - dsq->game->avatar->rotation.z = dsq->demo.frames[0].rot; - } - } - else if (c == 'U') - { - dsq->demo.renderFramesToDisk(); - - - } - else if (c == 'K') - { - dsq->demo.clearRecordedFrames(); - } else if (c == 'H') { std::ostringstream os; @@ -1684,21 +1659,21 @@ void DSQ::toggleVersionLabel(bool on) versionLabel->alpha.interpolateTo(a, 1); } -void DSQ::setInputMode(InputDevice mode) +void DSQ::setInputMode(InputDeviceType mode) { lastInputMode = mode; switch(mode) { - case INPUT_JOYSTICK: + case INP_DEV_JOYSTICK: core->joystickAsMouse = true; break; - case INPUT_MOUSE: + case INP_DEV_MOUSE: setMousePosition(core->mouse.position); core->joystickAsMouse = false; break; - case INPUT_KEYBOARD: + case INP_DEV_KEYBOARD: break; - case INPUT_NODEVICE: + case INP_DEV_NODEVICE: break; } } @@ -3665,7 +3640,7 @@ void DSQ::watch(float t, int canQuit) } } -void DSQ::action(int id, int state, int source, InputDevice device) +void DSQ::action(int id, int state, int source, InputDeviceType device) { Core::action(id, state, source, device); @@ -3693,10 +3668,8 @@ void DSQ::action(int id, int state, int source, InputDevice device) void DSQ::bindInput() { clearActions(); - almb.clear(); - armb.clear(); - addAction(ACTION_ESC, KEY_ESCAPE, -1); + addAction(ACTION_ESC, KEY_ESCAPE); addAction(MakeFunctionEvent(DSQ, onSwitchScreenMode), KEY_RETURN, 1); if (isDeveloperKeys()) @@ -3708,20 +3681,16 @@ void DSQ::bindInput() } addAction(MakeFunctionEvent(DSQ, debugMenu), KEY_BACKSPACE, 0); //addAction(MakeFunctionEvent(DSQ, takeScreenshotKey ), KEY_P, 0); - - for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) - { - ActionSet& as = dsq->user.control.actionSets[i]; - int sourceID = (int)i; - as.importAction(this, "Escape", ACTION_ESC, sourceID); - as.importAction(this, "Screenshot", ACTION_SCREENSHOT, sourceID); - - if(ActionInput *a = as.getActionInputByName("PrimaryAction")) - almb.push_back(a); - if(ActionInput *a = as.getActionInputByName("SecondaryAction")) - armb.push_back(a); - } + const NamedAction actions[] = + { + { "Escape", ACTION_ESC }, + { "Screenshot", ACTION_SCREENSHOT } + }; + ImportInput(actions); + + if(game) + game->bindInput(); } void DSQ::jiggleCursor() @@ -3731,13 +3700,15 @@ void DSQ::jiggleCursor() SDL_ShowCursor(SDL_DISABLE); } +#if 0 // FIXME controllerfixup void DSQ::updateActionButtons() { // HACK: not optimal +#if 0 // This must be done *before* Core::updateActionButtons() // for LMB/RMB emulation to work properly -- fg - if (/*inputMode != INPUT_KEYBOARD &&*/ game->isActive()) + if (/*inputMode != INP_DEV_KEYBOARD &&*/ game->isActive()) { for(size_t i = 0; i < almb.size(); ++i) if (ActionMapper::getKeyState(almb[i]->data.single.key[0]) || ActionMapper::getKeyState(almb[i]->data.single.key[1])) @@ -3768,9 +3739,11 @@ void DSQ::updateActionButtons() break; } } +#endif Core::updateActionButtons(); } +#endif static float skipSfxVol = 1.0; void DSQ::onUpdate(float dt) @@ -3828,7 +3801,7 @@ void DSQ::onUpdate(float dt) if (dsq->game && watchForQuit && isNested()) { - if (dsq->game->isActing(ACTION_ESC, -1)) + if (dsq->game->isActing(ACTION_ESC)) { watchQuitFlag = true; quitNestedMain(); @@ -3851,11 +3824,10 @@ void DSQ::onUpdate(float dt) subtitlePlayer.update(dt); - demo.update(dt); - +#if 0 //KILL if (joystickEnabled) { - if (dsq->getInputMode() != INPUT_JOYSTICK) + if (dsq->getInputMode() != INP_DEV_JOYSTICK) { const float thresh = JOY_AXIS_THRESHOLD; for(size_t i = 0; i < getNumJoysticks(); ++i) @@ -3864,39 +3836,29 @@ void DSQ::onUpdate(float dt) if (j->anyButton() || !j->position.isLength2DIn(thresh) || !j->rightStick.isLength2DIn(thresh)) { //debugLog("setting joystick input mode"); - dsq->setInputMode(INPUT_JOYSTICK); + dsq->setInputMode(INP_DEV_JOYSTICK); } } - else if (dsq->getInputMode() != INPUT_MOUSE) + else if (dsq->getInputMode() != INP_DEV_MOUSE) { - if ((!core->mouse.change.isLength2DIn(5) || (core->getMouseButtonState(0) || core->getMouseButtonState(1))) /*&& !core->joystick.anyButton()*/) + if ((!mouse.change.isLength2DIn(5) || (getKeyState(MOUSE_BUTTON_LEFT) || getKeyState(MOUSE_BUTTON_RIGHT)) /*&& !core->joystick.anyButton()*/) { //debugLog("setting mouse input mode"); - dsq->setInputMode(INPUT_MOUSE); + setInputMode(INP_DEV_MOUSE); } } } - if (dsq->game->avatar) - { - if (dsq->game->avatar->isActing(ACTION_SWIMUP, -1) || - dsq->game->avatar->isActing(ACTION_SWIMDOWN, -1) || - dsq->game->avatar->isActing(ACTION_SWIMLEFT, -1) || - dsq->game->avatar->isActing(ACTION_SWIMRIGHT, -1)) - { - dsq->setInputMode(INPUT_KEYBOARD); - } - } // check the actual values, since mouse.buttons.left might be overwritten by keys - int cb = 0; + int cb = MOUSE_BUTTON_LEFT; if (user.control.flipInputButtons) - cb = 1; + cb = MOUSE_BUTTON_RIGHT; - if (dsq->getInputMode() == INPUT_KEYBOARD && (core->getMouseButtonState(cb))) + if (dsq->getInputMode() == INP_DEV_KEYBOARD && getKeyState(cb)) { - dsq->setInputMode(INPUT_MOUSE); + dsq->setInputMode(INP_DEV_MOUSE); } - +#endif if (isDeveloperKeys() && cmDebug && cmDebug->alpha == 1 && fpsText) @@ -3935,16 +3897,18 @@ void DSQ::onUpdate(float dt) os << "inputMode: "; switch(dsq->getInputMode()) { - case INPUT_MOUSE: + case INP_DEV_MOUSE: os << "mouse"; break; - case INPUT_JOYSTICK: + case INP_DEV_JOYSTICK: os << "joystick"; break; - case INPUT_KEYBOARD: + case INP_DEV_KEYBOARD: + os << "keyboard"; + break; + case INP_DEV_NODEVICE: + os << "nodevice"; break; - case INPUT_NODEVICE: - break; } os << std::endl; Bone *b = dsq->game->avatar->skeletalSprite.getBoneByIdx(1); @@ -3964,7 +3928,7 @@ void DSQ::onUpdate(float dt) os << std::endl; os << "globalScale: " << core->globalScale.x << std::endl; os << "mousePos:(" << core->mouse.position.x << ", " << core->mouse.position.y << ") mouseChange:(" << core->mouse.change.x << ", " << core->mouse.change.y << ")\n"; - for(size_t i = 0; i < getNumJoysticks(); ++i) + /*for(size_t i = 0; i < getNumJoysticks(); ++i) if(Joystick *j = getJoystick(i)) { os << "J[" << i << "," << (j->isEnabled() ? " on" : "off") << "]:["; @@ -3974,7 +3938,7 @@ void DSQ::onUpdate(float dt) else os << '-'; os << "], (" << j->position.x << ", " << j->position.y << "), ("<< j->rightStick.x << ", " << j->rightStick.y << ")\n"; - } + }*/ // FIXME controllerfixup os << "altState: " << core->getKeyState(KEY_LALT) << " | " << core->getKeyState(KEY_RALT) << " mb: " << mouse.buttons.left << mouse.buttons.middle << mouse.buttons.right << std::endl; os << "PMFree: " << particleManager->getFree() << " Active: " << particleManager->getNumActive() << std::endl; os << "cameraPos: (" << dsq->cameraPos.x << ", " << dsq->cameraPos.y << ")" << std::endl; @@ -4226,17 +4190,6 @@ void DSQ::modifyDt(float &dt) gameSpeed.update(dt); dt *= gameSpeed.x; - - if (frameOutputMode) - { - dt = 1.0f/60.0f; - doScreenshot = true; - } - - if (dsq->demo.mode == Demo::DEMOMODE_RECORD) - { - dt = 1.0f/60.0f; - } } void DSQ::removeElement(Element *element) @@ -4485,48 +4438,12 @@ void DSQ::fixupJoysticks() if(Joystick *j = getJoystick(i)) j->setEnabled(false); + // Re-enable joysticks that are in use for(size_t i = 0; i < user.control.actionSets.size(); ++i) { ActionSet& as = user.control.actionSets[i]; as.updateJoystick(); } - - // HACK: why here? kinda dirty, but the joystick ID needs to be propagated - importActionButtons(); -} - -void DSQ::initActionButtons() -{ - clearActionButtons(); - - std::vector allkeys; - // Don't need joysticks keys for this - for(int i = 0; i < MOUSE_BUTTON_EXTRA_END; ++i) - allkeys.push_back(i); - - // create sentinel - ActionButtonStatus *allbtn = new ActionButtonStatus; - allbtn->importQuery(&allkeys[0], allkeys.size()); - actionStatus.push_back(allbtn); - - // create the rest - for(size_t i = 0; i < user.control.actionSets.size(); ++i) - actionStatus.push_back(new ActionButtonStatus); - - importActionButtons(); -} - -void DSQ::importActionButtons() -{ - assert(user.control.actionSets.size()+1 == actionStatus.size()); - - // ignore sentinel - for(size_t i = 1; i < actionStatus.size(); ++i) - { - const ActionSet& as = user.control.actionSets[i-1]; - ActionButtonStatus *abs = actionStatus[i]; - abs->import(as); - } } void DSQ::loadStringBank() @@ -4547,34 +4464,23 @@ void DSQ::loadStringBank() stringbank.load(fname); if (mod.isActive()) { + // FIXME (after controllerfixup) load mod stringbanks HERE, not up there fname = localisePath(mod.getPath() + "stringbank.txt", mod.getPath()); stringbank.load(fname); } } -InputDevice DSQ::getInputMode() const +InputDeviceType DSQ::getInputMode() const { return lastInputMode; } -InputDevice DSQ::getInputMode(int source) const -{ - assert(source >= 0 && size_t(source) < _inputModes.size()); - return _inputModes[source]; -} - -InputDevice DSQ::getInputModeSafe(int source) const -{ - return source < 0 ? lastInputMode : - (size_t(source) < _inputModes.size() ? _inputModes[source] : INPUT_NODEVICE); -} - bool DSQ::useMouseInput() const { - return lastInputMode == INPUT_MOUSE; + return lastInputMode == INP_DEV_MOUSE; } bool DSQ::useJoystickInput() const { - return lastInputMode == INPUT_JOYSTICK; + return lastInputMode == INP_DEV_JOYSTICK; } diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index fb10fb6..2a1834b 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Continuity.h" #include "SubtitlePlayer.h" #include "StringBank.h" - +#include "GameInput.h" #include "TTFFont.h" #define AQUARIA_BUILD_MAPVIS @@ -133,42 +133,6 @@ extern GameplayVariables *vars; #include "UserSettings.h" -struct DemoFrame -{ - float t; - Vector avatarPos, vel, vel2; - Mouse mouse; - float rot; -}; - -class Demo -{ -public: - enum { - DEMOMODE_NONE = -1, - DEMOMODE_RECORD = 0, - DEMOMODE_PLAYBACK = 1 - }; - Demo(); - void toggleRecord(bool on); - void togglePlayback(bool on); - void renderFramesToDisk(); - void clearRecordedFrames(); - - void update(float dt); - - bool getQuitKey(); - - void save(const std::string &name); - void load(const std::string &name); - - unsigned int frame; - float time; - float timeDiff; - std::vector frames; - int mode; -}; - enum NagType { NAG_TOTITLE = 0, @@ -208,7 +172,7 @@ public: void nag(NagType type); - void action(int id, int state, int source, InputDevice device); + void action(int id, int state, int source, InputDeviceType device); void title(bool fadeMusic=true); @@ -343,18 +307,16 @@ public: InterpolatedVector gameSpeed; + GameInput playerInput; private: - InputDevice lastInputMode; // really don't want to expose this one - std::vector _inputModes; // index: FIXME ADD INFO + InputDeviceType lastInputMode; // really don't want to expose this one public: - void setInputMode(InputDevice mode); - InputDevice getInputMode() const; - InputDevice getInputMode(int source) const; - InputDevice getInputModeSafe(int source) const; + void setInputMode(InputDeviceType mode); + InputDeviceType getInputMode() const; bool useMouseInput() const; bool useJoystickInput() const; - void rumble(float leftMotor, float rightMotor, float time, int source, InputDevice device); + void rumble(float leftMotor, float rightMotor, float time, int playerID = -1); void vision(std::string folder, int num, bool ignoreMusic = false); void run(float runTime = -1, bool skipRecurseCheck = false); // same as Core::run() but with recursion check @@ -394,8 +356,6 @@ public: std::string returnToScene; - Demo demo; - DebugFont *fpsText, *cmDebug; #ifdef AQUARIA_BUILD_CONSOLE DebugFont *console; @@ -492,8 +452,6 @@ protected: bool _canSkipCutscene; bool skippingCutscene; - std::vector almb, armb; - void recreateBlackBars(); bool watchQuitFlag, watchForQuit; @@ -550,12 +508,10 @@ protected: virtual void onJoystickAdded(int deviceID); virtual void onJoystickRemoved(int instanceID); - virtual void updateActionButtons(); + //virtual void updateActionButtons(); public: void fixupJoysticks(); - void initActionButtons(); - void importActionButtons(); }; extern DSQ *dsq; diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index 41dbe9a..4dfb6d7 100644 --- a/Aquaria/Entity.cpp +++ b/Aquaria/Entity.cpp @@ -1303,13 +1303,13 @@ bool Entity::updateCurrents(float dt) dist.normalize2D(); float v = dist.x; float scale = 0.2f; - if (getEntityType() == ET_AVATAR) + if (getEntityType() == ET_AVATAR) // FIXME (after controllerfixup) should be moved to avatar update { Avatar *a = dsq->game->avatar; if (v < 0) - dsq->rumble((-v)*scale, (1.0f+v)*scale, 0.2f, a->getLastActionSourceID(), a->getLastActionInputDevice()); + dsq->rumble((-v)*scale, (1.0f+v)*scale, 0.2f); else - dsq->rumble((1.0f-v)*scale, (v)*scale, 0.1f, a->getLastActionSourceID(), a->getLastActionInputDevice()); + dsq->rumble((1.0f-v)*scale, (v)*scale, 0.1f); } } } diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 6271c78..47a979f 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -2511,10 +2511,10 @@ float Game::getHalfTimer(float mod) void Game::toggleHelpScreen() { - action(ACTION_TOGGLEHELPSCREEN, 0, -1, INPUT_NODEVICE); + action(ACTION_TOGGLEHELPSCREEN, 0, -1, INP_DEV_NODEVICE); } -void Game::action(int id, int state, int source, InputDevice device) +void Game::action(int id, int state, int source, InputDeviceType device) { for (size_t i = 0; i < paths.size(); i++) { @@ -2557,16 +2557,6 @@ void Game::action(int id, int state, int source, InputDevice device) { if (id == ACTION_TOGGLEGRID && !state) toggleGridRender(); } - - // Forward these to Lua scripts (because digital swim movement should be seen as menu movement as well) - if(id == ACTION_SWIMLEFT) - action(ACTION_MENULEFT, state, source, device); - else if(id == ACTION_SWIMRIGHT) - action(ACTION_MENURIGHT, state, source, device); - else if(id == ACTION_SWIMUP) - action(ACTION_MENUUP, state, source, device); - else if(id == ACTION_SWIMDOWN) - action(ACTION_MENUDOWN, state, source, device); } void Game::toggleWorldMap() @@ -3219,69 +3209,62 @@ void Game::bindInput() ActionMapper::clearActions(); //ActionMapper::clearCreatedEvents(); - addAction(ACTION_ESC, KEY_ESCAPE, -1); + addAction(ACTION_ESC, KEY_ESCAPE); #ifdef AQUARIA_BUILD_SCENEEDITOR if (dsq->canOpenEditor()) { - addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB, -1); + addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB); } #endif if (dsq->canOpenEditor()) { //addAction(MakeFunctionEvent(Game, toggleMiniMapRender), KEY_M, 0); - addAction(ACTION_TOGGLEGRID, KEY_F9, -1); + addAction(ACTION_TOGGLEGRID, KEY_F9); } - for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + const NamedAction actions[] = { - const ActionSet& as = dsq->user.control.actionSets[i]; - int sourceID = (int)i; + { "PrimaryAction", ACTION_PRIMARY}, + { "SecondaryAction", ACTION_SECONDARY}, - as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID); - as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID); - - as.importAction(this, "Escape", ACTION_ESC, sourceID); - as.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP, sourceID); - as.importAction(this, "ToggleHelp", ACTION_TOGGLEHELPSCREEN, sourceID); + { "Escape", ACTION_ESC}, + { "WorldMap", ACTION_TOGGLEWORLDMAP}, + { "ToggleHelp", ACTION_TOGGLEHELPSCREEN}, // used for scrolling help text - as.importAction(this, "SwimUp", ACTION_SWIMUP, sourceID); - as.importAction(this, "SwimDown", ACTION_SWIMDOWN, sourceID); - as.importAction(this, "SwimLeft", ACTION_SWIMLEFT, sourceID); - as.importAction(this, "SwimRight", ACTION_SWIMRIGHT, sourceID); + { "SwimUp", ACTION_SWIMUP}, + { "SwimDown", ACTION_SWIMDOWN}, + { "SwimLeft", ACTION_SWIMLEFT}, + { "SwimRight", ACTION_SWIMRIGHT}, - as.importAction(this, "MenuUp", ACTION_MENUUP, sourceID); - as.importAction(this, "MenuDown", ACTION_MENUDOWN, sourceID); - as.importAction(this, "MenuLeft", ACTION_MENULEFT, sourceID); - as.importAction(this, "MenuRight", ACTION_MENURIGHT, sourceID); - - as.importAction(this, "PrevPage", ACTION_PREVPAGE, sourceID); - as.importAction(this, "NextPage", ACTION_NEXTPAGE, sourceID); - as.importAction(this, "CookFood", ACTION_COOKFOOD, sourceID); - as.importAction(this, "FoodLeft", ACTION_FOODLEFT, sourceID); - as.importAction(this, "FoodRight", ACTION_FOODRIGHT, sourceID); - as.importAction(this, "FoodDrop", ACTION_FOODDROP, sourceID); + { "PrevPage", ACTION_PREVPAGE}, + { "NextPage", ACTION_NEXTPAGE}, + { "CookFood", ACTION_COOKFOOD}, + { "FoodLeft", ACTION_FOODLEFT}, + { "FoodRight", ACTION_FOODRIGHT}, + { "FoodDrop", ACTION_FOODDROP}, // To capture quick song keys via script - as.importAction(this, "SongSlot1", ACTION_SONGSLOT1, sourceID); - as.importAction(this, "SongSlot2", ACTION_SONGSLOT2, sourceID); - as.importAction(this, "SongSlot3", ACTION_SONGSLOT3, sourceID); - as.importAction(this, "SongSlot4", ACTION_SONGSLOT4, sourceID); - as.importAction(this, "SongSlot5", ACTION_SONGSLOT5, sourceID); - as.importAction(this, "SongSlot6", ACTION_SONGSLOT6, sourceID); - as.importAction(this, "SongSlot7", ACTION_SONGSLOT7, sourceID); - as.importAction(this, "SongSlot8", ACTION_SONGSLOT8, sourceID); - as.importAction(this, "SongSlot9", ACTION_SONGSLOT9, sourceID); - as.importAction(this, "SongSlot10", ACTION_SONGSLOT10, sourceID); + { "SongSlot1", ACTION_SONGSLOT1}, + { "SongSlot2", ACTION_SONGSLOT2}, + { "SongSlot3", ACTION_SONGSLOT3}, + { "SongSlot4", ACTION_SONGSLOT4}, + { "SongSlot5", ACTION_SONGSLOT5}, + { "SongSlot6", ACTION_SONGSLOT6}, + { "SongSlot7", ACTION_SONGSLOT7}, + { "SongSlot8", ACTION_SONGSLOT8}, + { "SongSlot9", ACTION_SONGSLOT9}, + { "SongSlot10", ACTION_SONGSLOT10}, - as.importAction(this, "Revert", ACTION_REVERT, sourceID); + { "Revert", ACTION_REVERT}, - as.importAction(this, "Look", ACTION_LOOK, sourceID); - as.importAction(this, "Roll", ACTION_ROLL, sourceID); - } + { "Look", ACTION_LOOK}, + { "Roll", ACTION_ROLL} + }; + ImportInput(actions); if (avatar) avatar->bindInput(); @@ -3776,7 +3759,7 @@ bool Game::updateMusic() return false; } -void Game::onPressEscape(int source, InputDevice device) +void Game::onPressEscape(int source, InputDeviceType device) { if (dsq->isInCutscene()) { @@ -4240,13 +4223,13 @@ void Game::updateCursor(float dt) { bool rotate = false; - if (dsq->getInputMode() == INPUT_MOUSE) + if (dsq->getInputMode() == INP_DEV_MOUSE) { dsq->cursor->offset.stop(); dsq->cursor->offset = Vector(0,0); //debugLog("offset lerp stop in mouse!"); } - else if (dsq->getInputMode() == INPUT_JOYSTICK) + else if (dsq->getInputMode() == INP_DEV_JOYSTICK) { if (!dsq->game->isPaused() || dsq->game->isInGameMenu() || !dsq->game->avatar->isInputEnabled()) { @@ -4279,7 +4262,7 @@ void Game::updateCursor(float dt) // Don't show the cursor in keyboard/joystick mode if it's not // already visible (this keeps the cursor from appearing for an // instant during map fadeout). - if (dsq->getInputMode() == INPUT_MOUSE || isSceneEditorActive() || dsq->game->isPaused()) + if (dsq->getInputMode() == INP_DEV_MOUSE || isSceneEditorActive() || dsq->game->isPaused()) dsq->cursor->alphaMod = 0.5; /* @@ -4290,7 +4273,7 @@ void Game::updateCursor(float dt) else if (avatar) { //Vector v = avatar->getVectorToCursorFromScreenCentre(); - if (dsq->getInputMode() == INPUT_JOYSTICK)// && !avatar->isSinging() && !dsq->game->isInGameMenu() && !dsq->game->isPaused()) + if (dsq->getInputMode() == INP_DEV_JOYSTICK)// && !avatar->isSinging() && !dsq->game->isInGameMenu() && !dsq->game->isPaused()) { dsq->cursor->alphaMod = 0; if (!avatar->isSinging()) @@ -4518,7 +4501,7 @@ void Game::update(float dt) if (inHelpScreen) { const float helpTextScrollSpeed = 400.0f; - if (isActing(ACTION_SWIMDOWN, -1)) + if (isActing(ACTION_SWIMDOWN)) { helpText->offset.stop(); helpText->offset.y -= helpTextScrollSpeed * dt; @@ -4527,7 +4510,7 @@ void Game::update(float dt) helpText->offset.y = -helpText->getHeight() + core->getVirtualHeight(); } } - if (isActing(ACTION_SWIMUP, -1)) + if (isActing(ACTION_SWIMUP)) { helpText->offset.stop(); helpText->offset.y += helpTextScrollSpeed * dt; @@ -5027,8 +5010,6 @@ void Game::removeState() dsq->overlay->alpha.interpolateTo(1, fadeTime); dsq->run(fadeTime); - dsq->rumble(0,0,0,-1, INPUT_JOYSTICK); - dsq->sound->clearFadingSfx(); diff --git a/Aquaria/Game.h b/Aquaria/Game.h index faccc4f..e20cc52 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -176,7 +176,7 @@ public: void toggleWorldMap(); - void action(int id, int state, int source, InputDevice device); + void action(int id, int state, int source, InputDeviceType device); InGameMenu *getInGameMenu() { return themenu; } @@ -508,7 +508,7 @@ protected: float deathTimer; - void onPressEscape(int source, InputDevice device); + void onPressEscape(int source, InputDeviceType device); bool paused; bool worldPaused; @@ -540,7 +540,7 @@ private: static unsigned char grid[MAX_GRID][MAX_GRID]; }; -extern Game *game; +extern Game *game; // FIXME: dupe of dsq->game, kill this // INLINE FUNCTIONS diff --git a/Aquaria/GameEnums.h b/Aquaria/GameEnums.h index 8f671e6..8a24906 100644 --- a/Aquaria/GameEnums.h +++ b/Aquaria/GameEnums.h @@ -142,7 +142,9 @@ enum AquariaActions ACTION_LOOK , ACTION_TOGGLEHELPSCREEN, ACTION_PLACE_AVATAR, - ACTION_SCREENSHOT + ACTION_SCREENSHOT, + + ACTION_SIZE // for array bounds }; enum AuraType diff --git a/Aquaria/GameInput.cpp b/Aquaria/GameInput.cpp new file mode 100644 index 0000000..f707177 --- /dev/null +++ b/Aquaria/GameInput.cpp @@ -0,0 +1,41 @@ +#include "GameInput.h" +#include "GameKeys.h" +#include "Joystick.h" +#include + +// we use the game actions and 2 analog sticks (where 1 stick is 2 axes) +GameInput::GameInput() : GameControlState(ACTION_SIZE, 2+2) +{ + memset(&_emuActions[0], 0, sizeof(_emuActions)); +} + +Vector GameInput::getStick1() const +{ + return Vector(axes[0], axes[1]); +} + +Vector GameInput::getStick2() const +{ + return Vector(axes[2], axes[3]); +} + +void GameInput::update() +{ + Vector dir = getStick1(); + + // Menu input is fired by sufficient analog input or normal dpad input + emulateAction(ACTION_MENULEFT, dir.x > JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMLEFT]); + emulateAction(ACTION_MENURIGHT, dir.x < -JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMRIGHT]); + emulateAction(ACTION_MENUDOWN, dir.y > JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMDOWN]); + emulateAction(ACTION_MENUUP, dir.y < -JOY_AXIS_THRESHOLD || buttons[ACTION_SWIMUP]); +} + +void GameInput::emulateAction(unsigned ac, bool on) +{ + assert(ac < sizeof(_emuActions)); + if(_emuActions[ac] != on) + { + _emuActions[ac] = on; + IInputMapper::ForwardAction(ac, on, -1, INP_DEV_NODEVICE); + } +} diff --git a/Aquaria/GameInput.h b/Aquaria/GameInput.h new file mode 100644 index 0000000..2b6e2f5 --- /dev/null +++ b/Aquaria/GameInput.h @@ -0,0 +1,21 @@ +#ifndef GAMEINPUT_H +#define GAMEINPUT_H + +#include "Vector.h" +#include "InputMapper.h" +#include "GameEnums.h" + +class GameInput : public GameControlState +{ +public: + GameInput(); + void update(); + Vector getStick1() const; + Vector getStick2() const; + +private: + void emulateAction(unsigned ac, bool on); + bool _emuActions[ACTION_SIZE]; +}; + +#endif diff --git a/Aquaria/GridRender.h b/Aquaria/GridRender.h index 7e6d206..089962c 100644 --- a/Aquaria/GridRender.h +++ b/Aquaria/GridRender.h @@ -91,7 +91,7 @@ public: Vector getAvatarWorldMapPosition(); Vector getWorldToTile(WorldMapTile *tile, Vector position, bool fromCenter, bool tilePos); void setProperTileColor(WorldMapTile *tile); - void action(int id, int state, int source, InputDevice device); + void action(int id, int state, int source, InputDeviceType device); GemMover* addGem(GemData *gemData); void bindInput(); void createGemHint(const std::string &gfx); diff --git a/Aquaria/InGameMenu.cpp b/Aquaria/InGameMenu.cpp index 104ca59..f7777a8 100644 --- a/Aquaria/InGameMenu.cpp +++ b/Aquaria/InGameMenu.cpp @@ -646,7 +646,7 @@ void FoodSlot::onUpdate(float dt) { if (!themenu->recipeMenu.on) { - if (dsq->getInputMode() == INPUT_MOUSE) + if (dsq->getInputMode() == INP_DEV_MOUSE) { Vector diff = core->mouse.position - getWorldPosition(); position += diff; @@ -925,32 +925,25 @@ InGameMenu::~InGameMenu() void InGameMenu::bindInput() { - addAction(ACTION_ESC, KEY_ESCAPE, -1); + addAction(ACTION_ESC, KEY_ESCAPE); - for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + const NamedAction actions[] = { - const ActionSet& as = dsq->user.control.actionSets[i]; - int sourceID = (int)i; + { "PrimaryAction", ACTION_PRIMARY}, + { "SecondaryAction", ACTION_SECONDARY}, - as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID); - as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID); + { "Escape", ACTION_ESC}, + { "WorldMap", ACTION_TOGGLEWORLDMAP}, + { "ToggleHelp", ACTION_TOGGLEHELPSCREEN}, - as.importAction(this, "Escape", ACTION_ESC, sourceID); - as.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP, sourceID); - as.importAction(this, "ToggleHelp", ACTION_TOGGLEHELPSCREEN, sourceID); - - as.importAction(this, "PrevPage", ACTION_PREVPAGE, sourceID); - as.importAction(this, "NextPage", ACTION_NEXTPAGE, sourceID); - as.importAction(this, "CookFood", ACTION_COOKFOOD, sourceID); - as.importAction(this, "FoodLeft", ACTION_FOODLEFT, sourceID); - as.importAction(this, "FoodRight", ACTION_FOODRIGHT, sourceID); - as.importAction(this, "FoodDrop", ACTION_FOODDROP, sourceID); - - as.importAction(this, "MenuUp", ACTION_MENUUP, sourceID); - as.importAction(this, "MenuDown", ACTION_MENUDOWN, sourceID); - as.importAction(this, "MenuLeft", ACTION_MENULEFT, sourceID); - as.importAction(this, "MenuRight", ACTION_MENURIGHT, sourceID); - } + { "PrevPage", ACTION_PREVPAGE}, + { "NextPage", ACTION_NEXTPAGE}, + { "CookFood", ACTION_COOKFOOD}, + { "FoodLeft", ACTION_FOODLEFT}, + { "FoodRight", ACTION_FOODRIGHT}, + { "FoodDrop", ACTION_FOODDROP} + }; + ImportInput(actions); } void InGameMenu::reset() @@ -981,7 +974,7 @@ void InGameMenu::onContinuityReset() lastOptionsMenuPage = MENUPAGE_NONE; } -void InGameMenu::action(int id, int state, int source, InputDevice device) +void InGameMenu::action(int id, int state, int source, InputDeviceType device) { if(game->isIgnoreAction((AquariaActions)id)) return; @@ -1532,25 +1525,25 @@ void InGameMenu::addKeyConfigLine(RenderObject *group, const std::string &label, group->addChild(lb, PM_POINTER); x += KEYCONFIG_FIRST_COL_DISTANCE; - AquariaKeyConfig *m = new AquariaKeyConfig(actionInputName, INPUTSET_MOUSE, 0); + AquariaKeyConfig *m = new AquariaKeyConfig(actionInputName, INP_DEV_MOUSE, 0); m->position = Vector(x,y); group->addChild(m, PM_POINTER); keyConfigs.push_back(m); x += KEYCONFIG_COL_DISTANCE; - AquariaKeyConfig *k1 = new AquariaKeyConfig(actionInputName, INPUTSET_KEY, 0); + AquariaKeyConfig *k1 = new AquariaKeyConfig(actionInputName, INP_DEV_KEYBOARD, 0); k1->position = Vector(x,y); group->addChild(k1, PM_POINTER); keyConfigs.push_back(k1); x += KEYCONFIG_COL_DISTANCE; - AquariaKeyConfig *k2 = new AquariaKeyConfig(actionInputName, INPUTSET_KEY, 1); + AquariaKeyConfig *k2 = new AquariaKeyConfig(actionInputName, INP_DEV_KEYBOARD, 1); k2->position = Vector(x,y); group->addChild(k2, PM_POINTER); keyConfigs.push_back(k2); x += KEYCONFIG_COL_DISTANCE; - AquariaKeyConfig *j1 = new AquariaKeyConfig(actionInputName, INPUTSET_JOY, 0); + AquariaKeyConfig *j1 = new AquariaKeyConfig(actionInputName, INP_DEV_JOYSTICK, 0); j1->position = Vector(x,y); group->addChild(j1, PM_POINTER); keyConfigs.push_back(j1); @@ -1567,6 +1560,7 @@ void InGameMenu::addKeyConfigLine(RenderObject *group, const std::string &label, k2->setDirMove(DIR_LEFT, k1); } +/* FIXME controllerfixup AquariaKeyConfig *InGameMenu::addAxesConfigLine(RenderObject *group, const std::string &label, const std::string &actionInputName, int offx, int y) { TTFText *lb = new TTFText(&dsq->fontArialSmallest); @@ -1584,7 +1578,7 @@ AquariaKeyConfig *InGameMenu::addAxesConfigLine(RenderObject *group, const std:: return i1; } - +*/ void InGameMenu::switchToSongMenu() { @@ -2152,7 +2146,7 @@ void InGameMenu::create() addKeyConfigLine(kk, SB(2127), "Look", offx, y+=yi); y+=yi+yi/2; - AquariaKeyConfig* s1x = addAxesConfigLine(kk, SB(2117), "s1ax", offx, y); + /*AquariaKeyConfig* s1x = addAxesConfigLine(kk, SB(2117), "s1ax", offx, y); AquariaKeyConfig* s1y = addAxesConfigLine(kk, SB(2118), "s1ay", offx+130, y); AquariaKeyConfig* s2x = addAxesConfigLine(kk, SB(2119), "s2ax", offx+260, y); AquariaKeyConfig* s2y = addAxesConfigLine(kk, SB(2120), "s2ay", offx+380, y); @@ -2167,7 +2161,7 @@ void InGameMenu::create() s2x->setDirMove(DIR_RIGHT, s2y); s2y->setDirMove(DIR_LEFT, s2x); - s2y->setDirMove(DIR_RIGHT, s2y); + s2y->setDirMove(DIR_RIGHT, s2y);*/ // FIXME controllerfixup } // PART 2 @@ -4263,10 +4257,10 @@ void InGameMenu::updateJoystickText() if(j) { joystickNameText->setText(j->getName()); - int numb = j->getNumButtons(); - for(int i = 0; i < numb; ++i) + /*int numb = j->getNumButtons(); + for(int i = 0; i < numb; ++i) // FIXME controllerfixup if(j->getButton(i)) - jbt << i << " "; + jbt << i << " ";*/ } else if(as.joystickID == ACTIONSET_REASSIGN_JOYSTICK) { diff --git a/Aquaria/InGameMenu.h b/Aquaria/InGameMenu.h index 3bed495..0529498 100644 --- a/Aquaria/InGameMenu.h +++ b/Aquaria/InGameMenu.h @@ -88,7 +88,7 @@ public: void onContinuityReset(); void bindInput(); - virtual void action(int actionID, int state, int source, InputDevice device); + virtual void action(int actionID, int state, int source, InputDeviceType device); void refreshFoodSlots(bool effects); diff --git a/Aquaria/MiniMapRender.cpp b/Aquaria/MiniMapRender.cpp index 12d7f2f..92c80ff 100644 --- a/Aquaria/MiniMapRender.cpp +++ b/Aquaria/MiniMapRender.cpp @@ -413,7 +413,7 @@ void MiniMapRender::onUpdate(float dt) { doubleClickDelay = 0; if (!core->isStateJumpPending()) - dsq->game->action(ACTION_TOGGLEMENU, 1, -1, INPUT_NODEVICE); + dsq->game->action(ACTION_TOGGLEMENU, 1, -1, INP_DEV_NODEVICE); btn = true; } break; diff --git a/Aquaria/ModSelector.cpp b/Aquaria/ModSelector.cpp index a1c8c3d..4a89c52 100644 --- a/Aquaria/ModSelector.cpp +++ b/Aquaria/ModSelector.cpp @@ -119,7 +119,7 @@ void ModSelectorScreen::onUpdate(float dt) } } - if(!AquariaGuiElement::currentFocus && dsq->getInputMode() == INPUT_JOYSTICK) + if(!AquariaGuiElement::currentFocus && dsq->getInputMode() == INP_DEV_JOYSTICK) { AquariaGuiElement *closest = AquariaGuiElement::getClosestGuiElement(core->mouse.position); if(closest) diff --git a/Aquaria/ModSelector.h b/Aquaria/ModSelector.h index 8b73e2e..63031e7 100644 --- a/Aquaria/ModSelector.h +++ b/Aquaria/ModSelector.h @@ -166,7 +166,7 @@ public: void setSubText(const std::string& s); - virtual void action(int actionID, int state, int source, InputDevice device) {} + virtual void action(int actionID, int state, int source, InputDeviceType device) {} protected: virtual void onUpdate(float dt); diff --git a/Aquaria/Path.cpp b/Aquaria/Path.cpp index 2caef69..9b2146a 100644 --- a/Aquaria/Path.cpp +++ b/Aquaria/Path.cpp @@ -637,7 +637,7 @@ void Path::update(float dt) } } -bool Path::action(int id, int state, int source, InputDevice device) +bool Path::action(int id, int state, int source, InputDeviceType device) { if (hasScript()) { diff --git a/Aquaria/Path.h b/Aquaria/Path.h index 777eb77..e1f7764 100644 --- a/Aquaria/Path.h +++ b/Aquaria/Path.h @@ -91,7 +91,7 @@ public: void addNode(size_t idx); void update(float dt); void setActive(bool v); - bool action(int id, int state, int source, InputDevice device); + bool action(int id, int state, int source, InputDeviceType device); void setEmitter(const std::string& name); PathNode *getPathNode(size_t idx); diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index da7ffe5..ff70e6c 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -577,37 +577,37 @@ void SceneEditor::init() - addAction(ACTION_ZOOMIN, KEY_PGUP, -1); - addAction(ACTION_ZOOMOUT, KEY_PGDN, -1); + addAction(ACTION_ZOOMIN, KEY_PGUP); + addAction(ACTION_ZOOMOUT, KEY_PGDN); - addAction(ACTION_CAMLEFT, KEY_A, -1); - addAction(ACTION_CAMRIGHT, KEY_D, -1); - addAction(ACTION_CAMUP, KEY_W, -1); - addAction(ACTION_CAMDOWN, KEY_S, -1); + addAction(ACTION_CAMLEFT, KEY_A); + addAction(ACTION_CAMRIGHT, KEY_D); + addAction(ACTION_CAMUP, KEY_W); + addAction(ACTION_CAMDOWN, KEY_S); - addAction(ACTION_BGLAYEREND, KEY_0, -1); + addAction(ACTION_BGLAYEREND, KEY_0); - addAction(ACTION_BGLAYER1, KEY_1, -1); - addAction(ACTION_BGLAYER2, KEY_2, -1); - addAction(ACTION_BGLAYER3, KEY_3, -1); - addAction(ACTION_BGLAYER4, KEY_4, -1); - addAction(ACTION_BGLAYER5, KEY_5, -1); - addAction(ACTION_BGLAYER6, KEY_6, -1); - addAction(ACTION_BGLAYER7, KEY_7, -1); - addAction(ACTION_BGLAYER8, KEY_8, -1); - addAction(ACTION_BGLAYER9, KEY_9, -1); + addAction(ACTION_BGLAYER1, KEY_1); + addAction(ACTION_BGLAYER2, KEY_2); + addAction(ACTION_BGLAYER3, KEY_3); + addAction(ACTION_BGLAYER4, KEY_4); + addAction(ACTION_BGLAYER5, KEY_5); + addAction(ACTION_BGLAYER6, KEY_6); + addAction(ACTION_BGLAYER7, KEY_7); + addAction(ACTION_BGLAYER8, KEY_8); + addAction(ACTION_BGLAYER9, KEY_9); - addAction(ACTION_BGLAYER10, KEY_B, -1); - addAction(ACTION_BGLAYER11, KEY_N, -1); - addAction(ACTION_BGLAYER12, KEY_M, -1); + addAction(ACTION_BGLAYER10, KEY_B); + addAction(ACTION_BGLAYER11, KEY_N); + addAction(ACTION_BGLAYER12, KEY_M); - addAction(ACTION_BGLAYER13, KEY_J, -1); + addAction(ACTION_BGLAYER13, KEY_J); - addAction(ACTION_BGLAYER14, KEY_COMMA, -1); - addAction(ACTION_BGLAYER15, KEY_PERIOD, -1); - addAction(ACTION_BGLAYER16, KEY_SLASH, -1); + addAction(ACTION_BGLAYER14, KEY_COMMA); + addAction(ACTION_BGLAYER15, KEY_PERIOD); + addAction(ACTION_BGLAYER16, KEY_SLASH); - addAction(ACTION_MULTISELECT, KEY_LALT, -1); + addAction(ACTION_MULTISELECT, KEY_LALT); placer = new Quad; dsq->game->addRenderObject(placer, LR_HUD); @@ -1845,7 +1845,7 @@ void SceneEditor::removeEntity() void SceneEditor::placeAvatar() { dsq->game->avatar->position = dsq->getGameCursorPosition(); - dsq->game->action(ACTION_PLACE_AVATAR, 0, -1, INPUT_NODEVICE); + dsq->game->action(ACTION_PLACE_AVATAR, 0, -1, INP_DEV_NODEVICE); } void SceneEditor::scaleElementUp() @@ -1952,7 +1952,7 @@ void SceneEditor::updateMultiSelect() } } -void SceneEditor::action(int id, int state, int source, InputDevice device) +void SceneEditor::action(int id, int state, int source, InputDeviceType device) { if (core->getCtrlState() && editingElement) { @@ -2788,11 +2788,11 @@ void SceneEditor::update(float dt) { case ET_ELEMENTS: editingEntity = 0; - if (isActing(ACTION_MULTISELECT, -1) || !selectedElements.empty()) + if (isActing(ACTION_MULTISELECT) || !selectedElements.empty()) { editingElement = 0; } - if (state == ES_SELECTING && !isActing(ACTION_MULTISELECT, -1)) + if (state == ES_SELECTING && !isActing(ACTION_MULTISELECT)) editingElement = this->getElementAtCursor(); if (editingElement) @@ -2825,13 +2825,13 @@ void SceneEditor::update(float dt) int camSpeed = 500/zoom.x; if (core->getShiftState()) camSpeed = 5000/zoom.x; - if (isActing(ACTION_CAMLEFT, -1)) + if (isActing(ACTION_CAMLEFT)) dsq->cameraPos.x -= dt*camSpeed; - if (isActing(ACTION_CAMRIGHT, -1)) + if (isActing(ACTION_CAMRIGHT)) dsq->cameraPos.x += dt*camSpeed; - if (isActing(ACTION_CAMUP, -1)) + if (isActing(ACTION_CAMUP)) dsq->cameraPos.y -= dt*camSpeed; - if (isActing(ACTION_CAMDOWN, -1)) + if (isActing(ACTION_CAMDOWN)) dsq->cameraPos.y += dt*camSpeed; if (core->mouse.buttons.middle && !core->mouse.change.isZero()) { @@ -2841,9 +2841,9 @@ void SceneEditor::update(float dt) float spd = 0.5; const Vector oldZoom = zoom; - if (isActing(ACTION_ZOOMOUT, -1)) + if (isActing(ACTION_ZOOMOUT)) zoom /= (1 + spd*dt); - else if (isActing(ACTION_ZOOMIN, -1)) + else if (isActing(ACTION_ZOOMIN)) zoom *= (1 + spd*dt); else if (core->mouse.scrollWheelChange < 0) { diff --git a/Aquaria/SceneEditor.h b/Aquaria/SceneEditor.h index 7b270c3..d2f8ba9 100644 --- a/Aquaria/SceneEditor.h +++ b/Aquaria/SceneEditor.h @@ -89,7 +89,7 @@ public: void flipElementVert(); void deleteSelectedElement(); void deleteElement(int selectedIdx); - virtual void action(int id, int state, int source, InputDevice device); + virtual void action(int id, int state, int source, InputDeviceType device); void scaleElementUp(); void scaleElementDown(); void scaleElement1(); diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index ca2a34c..eb2fe8c 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2081,7 +2081,7 @@ luaFunc(sendAction) int state = lua_tointeger(L, 2); int mask = lua_tointeger(L, 3); int source = lua_tointeger(L, 4); - InputDevice device = (InputDevice)lua_tointeger(L, 5); + InputDeviceType device = (InputDeviceType)lua_tointeger(L, 5); if(!mask) mask = -1; if(mask & 1) @@ -2117,12 +2117,8 @@ luaFunc(shakeCamera) luaFunc(rumble) { - int source = lua_tointeger(L, 4) - 1; - Avatar *a = dsq->game->avatar; - InputDevice device = (InputDevice)lua_tointeger(L, 5); - if(device == INPUT_NODEVICE) // default: use avatar status - device = a ? a->getLastActionInputDevice() : INPUT_NODEVICE; - dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), source, device); + int playerID = lua_tointeger(L, 4) - 1; + dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), playerID); luaReturnNil(); } @@ -5014,24 +5010,24 @@ luaFunc(screenFadeGo) luaFunc(isEscapeKey) { - int source = lua_tointeger(L, 1) - 1; - bool isDown = dsq->game->isActing(ACTION_ESC, source); + int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup + bool isDown = dsq->game->isActing(ACTION_ESC); luaReturnBool(isDown); } luaFunc(isLeftMouse) { - int source = lua_tointeger(L, 1) - 1; - bool isDown = (source < 0 && core->mouse.buttons.left) - || (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_PRIMARY, source)); + int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup + bool isDown = (playerID < 0 && core->mouse.buttons.left) + || (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_PRIMARY)); luaReturnBool(isDown); } luaFunc(isRightMouse) { - int source = lua_tointeger(L, 1) - 1; - bool isDown = (source < 0 && core->mouse.buttons.right) - || (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_SECONDARY, source)); + int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup + bool isDown = (playerID < 0 && core->mouse.buttons.right) + || (dsq->game->avatar && dsq->game->avatar->isActing(ACTION_SECONDARY)); luaReturnBool(isDown); } @@ -8395,32 +8391,33 @@ luaFunc(disableInput) luaFunc(getInputMode) { - int source = lua_tointeger(L, 1); - luaReturnInt(dsq->getInputModeSafe(source - 1)); + //int playerID = lua_tointeger(L, 1) - 1; // FIXME controllerfixup? + luaReturnInt(dsq->getInputMode()); } -static Joystick *_getJoystick(lua_State *L, int idx = 1) +// FIXME: repair for controllerfixup +/*static Joystick *_getJoystick(lua_State *L, int idx = 1) { int source = lua_tointeger(L, idx) - 1; if(source < 0) return core->getJoystick(0); // HACK: FIXME: do something sensible instead return core->getJoystickForSourceID(source); -} +}*/ luaFunc(getJoystickAxisLeft) { Vector v; - if(Joystick *j = _getJoystick(L)) - v = j->position; + //if(Joystick *j = _getJoystick(L)) + // v = j->position; luaReturnVec2(v.x, v.y); } luaFunc(getJoystickAxisRight) { Vector v; - if(Joystick *j = _getJoystick(L)) - v = j->rightStick; + //if(Joystick *j = _getJoystick(L)) + // v = j->rightStick; luaReturnVec2(v.x, v.y); } @@ -11449,9 +11446,9 @@ static const struct { luaConstant(TILE_SIZE), - luaConstant(INPUT_MOUSE), - luaConstant(INPUT_JOYSTICK), - luaConstant(INPUT_KEYBOARD), + luaConstant(INP_DEV_MOUSE), + luaConstant(INP_DEV_JOYSTICK), + luaConstant(INP_DEV_KEYBOARD), luaConstant(ANIMLAYER_FLOURISH), luaConstant(ANIMLAYER_OVERRIDE), diff --git a/Aquaria/States.cpp b/Aquaria/States.cpp index 2ed1ac7..12fbe44 100644 --- a/Aquaria/States.cpp +++ b/Aquaria/States.cpp @@ -135,8 +135,6 @@ GameOver::GameOver() : StateObject() void GameOver::applyState() { - const bool frameOutputGameOver = false; - core->sound->fadeMusic(SFT_OUT, 1); @@ -147,12 +145,6 @@ void GameOver::applyState() core->sound->playSfx("Death"); - if (frameOutputGameOver) - { - dsq->fpsText->alpha = 0; - core->frameOutputMode = true; - } - Quad *q = new Quad; { q->color = 0; @@ -248,13 +240,6 @@ void GameOver::applyState() } else dsq->title(); - - - - if (frameOutputGameOver) - core->frameOutputMode = false; - - } void GameOver::removeState() diff --git a/Aquaria/UserSettings.cpp b/Aquaria/UserSettings.cpp index a6ff2ec..1434a8a 100644 --- a/Aquaria/UserSettings.cpp +++ b/Aquaria/UserSettings.cpp @@ -218,7 +218,7 @@ void UserSettings::save() { XMLElement *xml_action = doc.NewElement("Action"); const ActionInput& ai = as.inputSet[i]; - xml_action->SetAttribute("name", ai.name.c_str()); + xml_action->SetAttribute("name", ai.getName().c_str()); xml_action->SetAttribute("input", ai.toString().c_str()); xml_actionSet->InsertEndChild(xml_action); @@ -280,30 +280,30 @@ void UserSettings::save() static void ensureDefaultActions(ActionSet& as) { as.clearActions(); - as.addActionInput("PrimaryAction"); - as.addActionInput("SecondaryAction"); - as.addActionInput("SwimUp"); - as.addActionInput("SwimDown"); - as.addActionInput("SwimLeft"); - as.addActionInput("SwimRight"); - as.addActionInput("Roll"); - as.addActionInput("Revert"); - as.addActionInput("WorldMap"); - as.addActionInput("Escape"); - as.addActionInput("PrevPage"); - as.addActionInput("NextPage"); - as.addActionInput("CookFood"); - as.addActionInput("FoodLeft"); - as.addActionInput("FoodRight"); - as.addActionInput("FoodDrop"); - as.addActionInput("Look"); - as.addActionInput("ToggleHelp"); - as.addActionInput("Screenshot"); + as.ensureActionInput("PrimaryAction"); + as.ensureActionInput("SecondaryAction"); + as.ensureActionInput("SwimUp"); + as.ensureActionInput("SwimDown"); + as.ensureActionInput("SwimLeft"); + as.ensureActionInput("SwimRight"); + as.ensureActionInput("Roll"); + as.ensureActionInput("Revert"); + as.ensureActionInput("WorldMap"); + as.ensureActionInput("Escape"); + as.ensureActionInput("PrevPage"); + as.ensureActionInput("NextPage"); + as.ensureActionInput("CookFood"); + as.ensureActionInput("FoodLeft"); + as.ensureActionInput("FoodRight"); + as.ensureActionInput("FoodDrop"); + as.ensureActionInput("Look"); + as.ensureActionInput("ToggleHelp"); + as.ensureActionInput("Screenshot"); for(int i = 1; i <= 10; ++i) { std::ostringstream os; os << "SongSlot" << i; - as.addActionInput(os.str()); + as.ensureActionInput(os.str()); } } @@ -505,8 +505,8 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) const char *input = xml_action->Attribute("input"); if (name && *name && input && *input) { - ActionInput *ai = as.addActionInput(name); - ai->fromString(input); + ActionInput& ai = as.ensureActionInput(name); + ai.fromString(input); } } } @@ -584,30 +584,10 @@ void UserSettings::apply() dsq->loops.updateVolume(); - for(size_t i = 0; i < control.actionSets.size(); ++i) - { - ActionSet& as = control.actionSets[i]; - Joystick *j = core->getJoystick(as.joystickID); - if(j) - { - j->s1ax = as.joycfg.s1ax; - j->s1ay = as.joycfg.s1ay; - j->s2ax = as.joycfg.s2ax; - j->s2ay = as.joycfg.s2ay; - j->deadZone1 = as.joycfg.s1dead; - j->deadZone2 = as.joycfg.s2dead; - } - } - dsq->initActionButtons(); dsq->fixupJoysticks(); core->debugLogActive = system.debugLogOn; - if (dsq->game) - { - dsq->game->bindInput(); - } - dsq->bindInput(); core->settings.prebufferSounds = audio.prebuffer; diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 979a517..6c75291 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -794,21 +794,19 @@ void WorldMapRender::bindInput() clearActions(); clearCreatedEvents(); - addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB, -1); + addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB); - for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + const NamedAction actions[] = { - const ActionSet& as = dsq->user.control.actionSets[i]; - int sourceID = (int)i; + { "PrimaryAction", ACTION_PRIMARY }, + { "SecondaryAction", ACTION_SECONDARY }, - as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID); - as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID); - - as.importAction(this, "SwimLeft", ACTION_SWIMLEFT, sourceID); - as.importAction(this, "SwimRight", ACTION_SWIMRIGHT, sourceID); - as.importAction(this, "SwimUp", ACTION_SWIMUP, sourceID); - as.importAction(this, "SwimDown", ACTION_SWIMDOWN, sourceID); - } + { "SwimLeft", ACTION_SWIMLEFT }, + { "SwimRight", ACTION_SWIMRIGHT }, + { "SwimUp", ACTION_SWIMUP }, + { "SwimDown", ACTION_SWIMDOWN } + }; + ImportInput(actions); } void WorldMapRender::destroy() @@ -992,15 +990,15 @@ void WorldMapRender::onUpdate(float dt) { float scrollSpeed = 2.0f; float amt = (400*dt)/scale.x; - if (isActing(ACTION_SWIMLEFT, -1)) + if (isActing(ACTION_SWIMLEFT)) { internalOffset += Vector(amt, 0); } - if (isActing(ACTION_SWIMRIGHT, -1)) + if (isActing(ACTION_SWIMRIGHT)) { internalOffset += Vector(-amt, 0); } - if (isActing(ACTION_SWIMDOWN, -1)) + if (isActing(ACTION_SWIMDOWN)) { if (core->getShiftState()) { @@ -1012,7 +1010,7 @@ void WorldMapRender::onUpdate(float dt) internalOffset += Vector(0, -amt); } } - if (isActing(ACTION_SWIMUP, -1)) + if (isActing(ACTION_SWIMUP)) { if (core->getShiftState()) { @@ -1024,10 +1022,10 @@ void WorldMapRender::onUpdate(float dt) internalOffset += Vector(0, amt); } } - +#if 0 // FIXME controllerfixup if (core->joystickEnabled) { - if (isActing(ACTION_SECONDARY, -1)) + if (isActing(ACTION_SECONDARY)) { Vector jpos; for(size_t i = 0; i < core->getNumJoysticks(); ++i) @@ -1061,6 +1059,7 @@ void WorldMapRender::onUpdate(float dt) internalOffset += jpos * (-400*dt / scale.x); } } +#endif } if (activeTile && activeTile->layer == 1) @@ -1501,7 +1500,7 @@ void WorldMapRender::updateEditor() areaLabel->setText(os.str()); } -void WorldMapRender::action (int id, int state, int source, InputDevice device) +void WorldMapRender::action (int id, int state, int source, InputDeviceType device) { if (isOn()) { diff --git a/BBGE/ActionInput.cpp b/BBGE/ActionInput.cpp index 8264c6f..8648ab8 100644 --- a/BBGE/ActionInput.cpp +++ b/BBGE/ActionInput.cpp @@ -26,267 +26,267 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "GameKeyNames.h" #include "StringBank.h" - -static std::string inputcode2string(int k) -{ - if(k <= 0) - return std::string(); - if(k < KEY_MAXARRAY) - { - // Returns KEY_* or NULL - const std::string& str = getKeyNameFromInputCode(k); - if(str.length()) - return str; - - // fallback - std::ostringstream os; - os << "K:" << k; - return os.str(); - } - - if(k >= JOY_BUTTON_0 && k < JOY_BUTTON_END) - { - std::ostringstream os; - os << "JB:" << (k - JOY_BUTTON_0); - return os.str(); - } - - if(k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS) - { - std::ostringstream os; - os << "AX:+" << (k - JOY_AXIS_0_POS); - return os.str(); - } - - if(k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG) - { - std::ostringstream os; - os << "AX:-" << (k - JOY_AXIS_0_NEG); - return os.str(); - } - - if(k >= JOY_HAT_BEGIN && k < JOY_HAT_END) - { - if(k >= JOY_HAT_0_LEFT && k < JOY_HAT_END_LEFT) - { - std::ostringstream os; - os << "HL" << (k - JOY_HAT_0_LEFT); - return os.str(); - } - else if(k >= JOY_HAT_0_RIGHT && k < JOY_HAT_END_RIGHT) - { - std::ostringstream os; - os << "HR" << (k - JOY_HAT_0_RIGHT); - return os.str(); - } - else if(k >= JOY_HAT_0_UP && k < JOY_HAT_END_UP) - { - std::ostringstream os; - os << "HU" << (k - JOY_HAT_0_UP); - return os.str(); - } - else if(k >= JOY_HAT_0_DOWN && k < JOY_HAT_END_DOWN) - { - std::ostringstream os; - os << "HD" << (k - JOY_HAT_0_DOWN); - return os.str(); - } - } - - switch(k) - { - case MOUSE_BUTTON_LEFT: - return "LMB"; - case MOUSE_BUTTON_RIGHT: - return "RMB"; - case MOUSE_BUTTON_MIDDLE: - return "MMB"; - default: - if(k >= MOUSE_BUTTON_EXTRA_START && k < MOUSE_BUTTON_EXTRA_START+mouseExtraButtons) - { - std::ostringstream os; - os << "MB:" << (k - MOUSE_BUTTON_LEFT); - return os.str(); - } - } - - return std::string(); -} - -static const char *jaxisname(int joystickID, int axis) +static const char *jaxisname(int joystickID, unsigned axis) { Joystick *j = core->getJoystick(joystickID); - return j ? j->getAxisName(axis) : NULL; + const char *s = j ? j->getAxisName(axis - 1) : NULL; + return s && *s ? s : NULL; } -static const char *jbtnname(int joystickID, int btn) +static const char *jbtnname(int joystickID, unsigned btn) { Joystick *j = core->getJoystick(joystickID); - return j ? j->getButtonName(btn) : NULL; + const char *s = j ? j->getButtonName(btn - 1) : NULL; + return s && *s ? s : NULL; } -std::string getInputCodeToString(int k) +struct JoyHatDir { - std::string s = inputcode2string(k); - return s.empty() ? "0" : s; + char c, pretty; + int x, y; +}; +static const JoyHatDir s_joyhat[] = +{ + { 'u', '^', 0, -1 }, + { 'd', 'v', 0, 1 }, + { 'l', '<', -1, 0 }, + { 'r', '>', 0, 1 }, + { 0, 0, 0, 0 }, // terminator +}; + +static std::string num2str(unsigned x) +{ + std::ostringstream os; + os << x; + return os.str(); } -std::string getInputCodeToUserString(unsigned int k, size_t joystickID) +static std::string getMouseButtonToString(unsigned b) { - const char *pretty = NULL, *tail = NULL; + static const char *buf[] = { "LMB", "MMB", "RMB" }; + if(b && b < 4) // 1 2 3 + return buf[b-1]; + return num2str(b); +} +static const char *getRawSDLKeyName(unsigned k) +{ + const char *s = NULL; +#ifdef BBGE_BUILD_SDL2 + s = SDL_GetScancodeName((SDL_Scancode)k); +#else + s = SDL_GetKeyName((SDLKey)k); +#endif + return s && *s ? s : NULL; +} + +static const char *getPrettySDLKeyName(unsigned k) +{ + const char *s; +#ifdef BBGE_BUILD_SDL2 // Special case keyboard input: // Return key name for current keyboard layout! // It's just confusing to see Y instead of Z with a german keyboard layout... - if(k && k < KEY_MAXARRAY) - { -#ifdef BBGE_BUILD_SDL2 - pretty = SDL_GetScancodeName((SDL_Scancode)k); - const SDL_Keycode kcode = SDL_GetKeyFromScancode((SDL_Scancode)k); - if(kcode != SDLK_UNKNOWN) - pretty = SDL_GetKeyName(kcode); -#else - pretty = SDL_GetKeyName((SDLKey)k); -#endif - } - if(k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS) - { - pretty = jaxisname(joystickID, k - JOY_AXIS_0_POS); - tail = "(+)"; - } - else if(k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG) - { - pretty = jaxisname(joystickID, k - JOY_AXIS_0_NEG); - tail = "(-)"; - } - else if(k >= JOY_BUTTON_0 && k < JOY_BUTTON_END) - pretty = jbtnname(joystickID, k - JOY_BUTTON_0); - - std::string s; - if(pretty && *pretty) - { - s = pretty; - if(tail) - s += tail; - return s; - } - - if(k >= JOY_HAT_BEGIN && k < JOY_HAT_END) - { - if(k >= JOY_HAT_0_LEFT && k < JOY_HAT_END_LEFT) - { - std::ostringstream os; - os << "H" << (k - JOY_HAT_0_LEFT) << "<"; - return os.str(); - } - else if(k >= JOY_HAT_0_RIGHT && k < JOY_HAT_END_RIGHT) - { - std::ostringstream os; - os << "H" << (k - JOY_HAT_0_RIGHT) << ">"; - return os.str(); - } - else if(k >= JOY_HAT_0_UP && k < JOY_HAT_END_UP) - { - std::ostringstream os; - os << "H" << (k - JOY_HAT_0_UP) << "^"; - return os.str(); - } - else if(k >= JOY_HAT_0_DOWN && k < JOY_HAT_END_DOWN) - { - std::ostringstream os; - os << "H" << (k - JOY_HAT_0_DOWN) << "v"; - return os.str(); - } - } - - s = inputcode2string(k); - return s.empty() ? stringbank.get(SB_BBGE_NO_KEY) : s; -} - -static int checkInp(const char *s, int category, int limit, StringBankIndexBBGE errid) -{ - const int k = atoi(s); - if(!k) - return 0; - if(k < limit) - return k + category; - - std::ostringstream os; - os << stringbank.get(errid) << k; - errorLog(os.str()); - return 0; -} - -int getStringToInputCode(const std::string& s) -{ - int k = 0; - - if(s == "LMB") - k = MOUSE_BUTTON_LEFT; - else if(s == "RMB") - k = MOUSE_BUTTON_RIGHT; - else if(s == "MMB") - k = MOUSE_BUTTON_MIDDLE; - else if(!strncmp(s.c_str(), "K:", 2)) - k = checkInp(s.c_str() + 2, 0, KEY_MAXARRAY, SB_BBGE_INVALID_KEY_ID); - else if(!strncmp(s.c_str(), "JB:", 3)) - k = checkInp(s.c_str() + 3, JOY_BUTTON_0, JOY_BUTTON_END, SB_BBGE_INVALID_JOY_BTN); - else if(!strncmp(s.c_str(), "MB:", 3)) - k = checkInp(s.c_str() + 3, MOUSE_BUTTON_LEFT, MOUSE_BUTTON_EXTRA_END, SB_BBGE_INVALID_MOUSE_BTN); - else if(s.length() > 4 && !strncmp(s.c_str(), "AX:", 3)) - { - switch(s[3]) - { - case '+': - k = checkInp(s.c_str() + 4, JOY_AXIS_0_POS, JOY_AXIS_END_POS, SB_BBGE_INVALID_JOY_AXIS_POS); - break; - case '-': - k = checkInp(s.c_str() + 4, JOY_AXIS_0_NEG, JOY_AXIS_END_NEG, SB_BBGE_INVALID_JOY_AXIS_NEG); - break; - default: - return 0; - } - } - else if(s.length() > 2 && s[0] == 'H') // joystick hat - { - JoyHatDirection hd; - switch(s[1]) - { - case 'L': hd = JOY_HAT_DIR_LEFT; break; - case 'R': hd = JOY_HAT_DIR_RIGHT; break; - case 'U': hd = JOY_HAT_DIR_UP; break; - case 'D': hd = JOY_HAT_DIR_DOWN; break; - default: return 0; - } - unsigned hatID = atoi(s.c_str() + 2); - return joyHatToActionButton(hatID, hd); - } + const SDL_Keycode kcode = SDL_GetKeyFromScancode((SDL_Scancode)k); + if(kcode == SDLK_UNKNOWN) + s = SDL_GetScancodeName((SDL_Scancode)k); else + s = SDL_GetKeyName(kcode); +#else + s = SDL_GetKeyName((SDLKey)k); +#endif + return s && *s ? s : NULL; +} + +static unsigned getKeyCodeFromSDLName(const char *s) +{ +#ifdef BBGE_BUILD_SDL2 + return SDL_GetScancodeFromName(s); +#endif + return SDL_GetKeyFromName(s); +} + +static std::string getKeyToString(unsigned k) +{ + assert(k < KEY_MAXARRAY); + const char *s = getLegacyKeyNameFromInputCode(k); + if(s) + return s; + s = getRawSDLKeyName(k); + if(s) + return s; + + return num2str(k); +} + +static std::string getJoystickDataToString(const ActionInput::JoyData& jd) +{ + std::ostringstream os; + + switch(jd.ctrlType) { - // Maybe we're upgrading from an old config? - // This handles KEY_* and some old mouse/joystick names. - k = getInputCodeFromKeyName(s.c_str()); + case INP_CTRL_BUTTON: + os << jd.ctrlID; + break; + case INP_CTRL_AXIS: + os << 'A' << ((jd.x < 0 || jd.y < 0) ? '-' : '+') << jd.ctrlID; + break; + case INP_CTRL_HAT: + os << 'H'; + for(const JoyHatDir *hd = &s_joyhat[0]; hd->c; ++hd) + if(jd.x == hd->x && jd.y == hd->y) + { + os << hd->c << jd.ctrlID; + break; + } + break; } + return os.str(); +} - // Non-configurable keys - if(k == KEY_ESCAPE) - return 0; - - if(k < ACTION_BUTTON_ENUM_SIZE) - return k; +static std::string getJoystickDataToPrettyString(const ActionInput::JoyData& jd, int joystickID) +{ + if(!jd.ctrlID) + return std::string(); std::ostringstream os; - os << "ActionButton out of range: [" << s << "] = " << k; - errorLog(os.str()); - return 0; + static const char *axislabels[] = { "(-)", "", "(+)" }; + + switch(jd.ctrlType) + { + case INP_CTRL_BUTTON: + { + const char *s = jbtnname(joystickID, jd.ctrlID); + if(s) + os << s; + else + os << jd.ctrlID; + } + break; + + case INP_CTRL_AXIS: + { + const char *s = jaxisname(joystickID, jd.ctrlID); + if(s) + os << s; + else + os << "A:" << jd.ctrlID; + os << axislabels[jd.x + 1] << axislabels[jd.y + 1]; + } + break; + + case INP_CTRL_HAT: + { + os << "H:" << jd.ctrlID << ":"; + for(const JoyHatDir *hd = &s_joyhat[0]; hd->c; ++hd) + if(jd.x == hd->x && jd.y == hd->y) + { + os << hd->pretty; + break; + } + } + break; + } + return os.str(); +} + +static unsigned getMouseButtonFromString_Legacy(const std::string& s) +{ + if(s == "LMB") + return MOUSE_BUTTON_LEFT; + else if(s == "RMB") + return MOUSE_BUTTON_RIGHT; + else if(s == "MMB") + return MOUSE_BUTTON_MIDDLE; + + return getLegacyInputCodeFromKeyName(s.c_str()); } - -ActionInput::ActionInput() +static unsigned getMouseButtonFromString(const std::string& s) { - for (int i = 0; i < INP_COMBINED_SIZE; i++) - data.all[i] = 0; + if(s.empty() || s == "0") + return 0; + + unsigned k = getMouseButtonFromString_Legacy(s); + switch(k) + { + case MOUSE_BUTTON_LEFT: return 1; + case MOUSE_BUTTON_RIGHT: return 2; + case MOUSE_BUTTON_MIDDLE: return 3; + default: ; + } + + return atoi(s.c_str()); +} + +static unsigned getKeyFromString(const std::string& s) +{ + if(s.empty() || s == "0") + return 0; + + unsigned k = getLegacyInputCodeFromKeyName(s.c_str()); // fallback + if(k) + return k; + k = getKeyCodeFromSDLName(s.c_str()); + if(k) + return k; + + return atoi(s.c_str()); +} + +static ActionInput::JoyData getJostickDataFromString(const std::string& s) +{ + ActionInput::JoyData jd; + + if(s.length() && s != "0") + { + switch(s[0]) + { + case 'A': // axis + { + jd.ctrlType = INP_CTRL_AXIS; + int ax = atoi(s.c_str() + 1); + jd.ctrlID = ax < 0 ? -ax : ax; + jd.x = ax < 0 ? -1 : 1; + } + break; + + case 'H': // hat + jd.ctrlType = INP_CTRL_HAT; + if(s.length() > 1) + for(const JoyHatDir *hd = &s_joyhat[0]; hd->c; ++hd) + if(hd->c == s[1]) + { + jd.x = hd->x; + jd.y = hd->y; + jd.ctrlID = atoi(s.c_str() + 2); + break; + } + break; + + default: // button + jd.ctrlType = INP_CTRL_BUTTON; + jd.ctrlID = atoi(s.c_str() + 1); + } + } + + return jd; +} + +ActionInput::JoyData::JoyData() +{ + memset(this, 0, sizeof(*this)); +} + +ActionInput::ActionInput(const std::string& name_) +: name(name_) +{ + for (int i = 0; i < INP_MSESIZE; i++) + mse[i] = 0; + for (int i = 0; i < INP_KEYSIZE; i++) + key[i] = 0; + // joy[] inited by its own ctor } std::string ActionInput::toString() const @@ -295,15 +295,15 @@ std::string ActionInput::toString() const for (int i = 0; i < INP_MSESIZE; i++) { - os << getInputCodeToString(data.single.mse[i]) << " "; + os << getMouseButtonToString(mse[i]) << " "; } for (int i = 0; i < INP_KEYSIZE; i++) { - os << getInputCodeToString(data.single.key[i]) << " "; + os << getKeyToString(key[i]) << " "; } for (int i = 0; i < INP_JOYSIZE; i++) { - os << getInputCodeToString(data.single.joy[i]) << " "; + os << getJoystickDataToString(joy[i]) << " "; } return os.str(); @@ -316,17 +316,231 @@ void ActionInput::fromString(const std::string &read) for (int i = 0; i < INP_MSESIZE; i++) { is >> str; - data.single.mse[i] = getStringToInputCode(str); + mse[i] = getMouseButtonFromString(str); } for (int i = 0; i < INP_KEYSIZE; i++) { is >> str; - data.single.key[i] = getStringToInputCode(str); + key[i] = getKeyFromString(str); } for (int i = 0; i < INP_JOYSIZE; i++) { is >> str; - data.single.joy[i] = getStringToInputCode(str); + joy[i] = getJostickDataFromString(str); } } +struct TypeAndSlot +{ + InputDeviceType type; + unsigned slot; +}; +static TypeAndSlot getTypeAndSlot(unsigned field) +{ + TypeAndSlot ts; + if(field < INP_MSESIZE) + { + ts.type = INP_DEV_MOUSE; + ts.slot = field; + } + else if(field < INP_MSESIZE + INP_KEYSIZE) + { + ts.type = INP_DEV_KEYBOARD; + ts.slot = field - INP_MSESIZE; + } + else if(field < INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE) + { + ts.type = INP_DEV_JOYSTICK; + ts.slot = field - (INP_MSESIZE + INP_KEYSIZE); + } + else + { + assert(false); + ts.type = InputDeviceType(-1); + ts.slot = unsigned(-1); + } + return ts; +} + +unsigned ActionInput::GetField(InputDeviceType dev, unsigned slot) +{ + unsigned base = 0; + switch(dev) + { + case INP_DEV_MOUSE: + base = 0; + assert(slot < INP_MSESIZE); + break; + case INP_DEV_KEYBOARD: + base = INP_MSESIZE; + assert(slot < INP_KEYSIZE); + break; + case INP_DEV_JOYSTICK: + base = INP_MSESIZE+INP_KEYSIZE; + assert(slot < INP_JOYSIZE); + break; + default: + assert(false); + } + return base + slot; +} + + +std::string ActionInput::prettyPrintField(unsigned field, int joystickID /* = -1 */) const +{ + TypeAndSlot ts = getTypeAndSlot(field); + switch(ts.type) + { + case INP_DEV_MOUSE: + return getMouseButtonToString(mse[field]); + case INP_DEV_KEYBOARD: + { + unsigned k = key[ts.slot]; + const char *s = getPrettySDLKeyName(k); + if(s) + return s; + return getKeyToString(k); + } + case INP_DEV_JOYSTICK: + { + const JoyData& jd = joy[ts.slot]; + return getJoystickDataToPrettyString(jd, joystickID); + } + } + assert(false); + return std::string(); +} + +bool ActionInput::ImportField(const RawInput& inp, unsigned field) +{ + TypeAndSlot ts = getTypeAndSlot(field); + return ts.type == inp.src.deviceType && Import(inp, ts.slot); +} + +bool ActionInput::Import(const RawInput& inp, unsigned slot) +{ + switch(inp.src.deviceType) + { + case INP_DEV_MOUSE: + { + if(slot >= INP_MSESIZE) + return false; + if(inp.src.ctrlID == INP_CTRL_BUTTON) + { + mse[slot] = inp.src.ctrlID + 1; + return true; + } + } + break; + + case INP_DEV_KEYBOARD: + { + if(slot >= INP_KEYSIZE) + return false; + if(inp.src.ctrlID == INP_CTRL_BUTTON) + { + key[slot] = inp.src.ctrlID; + return true; + } + } + break; + + case INP_DEV_JOYSTICK: + { + if(slot >= INP_JOYSIZE) + return false; + JoyData jd; + InputControlType t = inp.src.ctrlType; + if(t == INP_CTRL_BUTTON || t == INP_CTRL_AXIS || t == INP_CTRL_HAT) + { + jd.ctrlType = t; + jd.ctrlID = inp.src.ctrlID + 1; + jd.x = inp.u.ivec.x; + jd.y = inp.u.ivec.y; + if(t == INP_CTRL_AXIS) + jd.x = inp.u.axis < 0 ? -1 : 1; + return true; + } + } + break; + } + + return false; +} + +bool ActionInput::Export(RawInput& inp, unsigned field) const +{ + TypeAndSlot ts = getTypeAndSlot(field); + inp.src.deviceType = ts.type; + inp.src.ctrlType = INP_CTRL_BUTTON; + inp.u.pressed = 1; + + switch(ts.type) + { + case INP_DEV_MOUSE: + { + unsigned m = mse[ts.slot]; + if(!m) + return false; + inp.src.ctrlID = m - 1; + return true; + } + + case INP_DEV_KEYBOARD: + { + unsigned k = key[ts.slot]; + if(!k) + return false; + inp.src.ctrlID = k; + } + case INP_DEV_JOYSTICK: + { + const JoyData& jd = joy[field - (INP_MSESIZE + INP_KEYSIZE)]; + if(!jd.ctrlID) + return false; + inp.src.ctrlType = jd.ctrlType; + inp.src.ctrlID = jd.ctrlID - 1; + inp.u.ivec.x = jd.x; + inp.u.ivec.y = jd.y; + if(jd.ctrlType == INP_CTRL_AXIS) + inp.u.axis = jd.x < 0 ? -1 : 1; + return true; + } + } + assert(false); + return false; +} + +bool ActionInput::hasEntry(unsigned field) const +{ + TypeAndSlot ts = getTypeAndSlot(field); + + switch(ts.type) + { + case INP_DEV_MOUSE: + return mse[ts.slot]; + case INP_DEV_KEYBOARD: + return key[ts.slot]; + case INP_DEV_JOYSTICK: + return joy[ts.slot].ctrlID; + } + return false; +} + +void ActionInput::clearEntry(unsigned field) +{ + TypeAndSlot ts = getTypeAndSlot(field); + + switch(ts.type) + { + case INP_DEV_MOUSE: + mse[ts.slot] = 0; + break; + case INP_DEV_KEYBOARD: + key[ts.slot] = 0; + break; + case INP_DEV_JOYSTICK: + joy[ts.slot].ctrlID = 0; + break; + } +} diff --git a/BBGE/ActionInput.h b/BBGE/ActionInput.h index 26f5120..6a05383 100644 --- a/BBGE/ActionInput.h +++ b/BBGE/ActionInput.h @@ -22,56 +22,60 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define ACTIONINPUT_H #include +#include "InputSystem.h" +// Slots for each input/key type enum ActionInputSize { INP_MSESIZE = 1, INP_KEYSIZE = 2, INP_JOYSIZE = 1, - INP_COMBINED_SIZE = INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE + INP_NUMFIELDS = INP_MSESIZE + INP_KEYSIZE + INP_JOYSIZE }; -std::string getInputCodeToString(int k); std::string getInputCodeToUserString(unsigned int k, size_t joystickID); -int getStringToInputCode(const std::string& s); +// Mapping for one input action ("Cook", "SwimLeft", etc) class ActionInput { -public: - ActionInput(); - - std::string name; - - union +public: // only public because some static funcs in the cpp file need this. Don't use elsewhere! + struct JoyData { - struct - { - unsigned int mse[INP_MSESIZE]; - unsigned int key[INP_KEYSIZE]; - unsigned int joy[INP_JOYSIZE]; - } single; - int all[INP_COMBINED_SIZE]; - } data; + JoyData(); + InputControlType ctrlType; + unsigned ctrlID; // 0 = not set, otherwise actual id + 1 + int x, y; // each [-1..+1]: (x,y) for hat direction, (x) for axis direction + }; + inline const std::string& getName() const { return name; } +private: + unsigned mse[INP_MSESIZE]; // stores button+1, 0 = not set + unsigned key[INP_KEYSIZE]; // 0 = no key + JoyData joy[INP_JOYSIZE]; + std::string name; +public: + ActionInput(const std::string& name_); + + // indexing: + // slot -> per-category (start at 0 for each INP_*) + // field: absolute, [0 ..INP_NUMFIELDS) + + static unsigned GetField(InputDeviceType dev, unsigned slot); + + bool Import(const RawInput& inp, unsigned slot); // autodetects type, slot is per-category + bool ImportField(const RawInput& inp, unsigned field); // returns false if field and type of inp don't match + bool Export(RawInput& inp, unsigned field) const; // returns false if no mapping present + + // for checking whether a key/button/etc is configured + bool hasEntry(unsigned field) const; + void clearEntry(unsigned field); + + // for config (de-)serialization std::string toString() const; void fromString(const std::string &read); -}; -enum InputSetType -{ - INPUTSET_NONE = 0, - INPUTSET_KEY = 1, - INPUTSET_JOY = 2, - INPUTSET_MOUSE = 3, - INPUTSET_OTHER = 4 -}; - -enum InputDevice -{ - INPUT_NODEVICE = 0, - INPUT_MOUSE, - INPUT_JOYSTICK, - INPUT_KEYBOARD + // for the UI (field is in [0..INP_COMBINED_SIZE]) + std::string prettyPrintField(unsigned field, int joystickID = -1) const; }; #endif diff --git a/BBGE/ActionMapper.cpp b/BBGE/ActionMapper.cpp index 51b025f..23af97e 100644 --- a/BBGE/ActionMapper.cpp +++ b/BBGE/ActionMapper.cpp @@ -18,76 +18,70 @@ See the GNU General Public License for more details. #include "ActionMapper.h" #include "Core.h" +typedef std::vector ButtonList; -InputDevice getDeviceForActionbutton(int k) +// TODO: clean this up, make single vector of tagged unions, sorted by key +struct LegacyActionData { - if(k <= KEY_MAXARRAY) - return INPUT_KEYBOARD; - if(k < MOUSE_BUTTON_EXTRA_END) - return INPUT_MOUSE; - return INPUT_JOYSTICK; -} + LegacyActionData() + : id(-1), state(-1) + , event(0) + { + } + + int id; // -1 if no associated event + int state; // -1, 0, or 1 + Event *event; + ButtonList buttonList; +}; + +enum ActionState +{ + ACSTATE_ACTIVE = 0x1, // action is active right now (button is held down) + ACSTATE_ACCEPTED = 0x2 // handle that action when it comes in +}; ActionMapper::ActionMapper() { cleared = false; inputEnabled = true; inUpdate = false; - //memset(keyStatus, 0, sizeof(keyStatus)); + InputMapper::RegisterActionMapper(this); } ActionMapper::~ActionMapper() { + InputMapper::UnregisterActionMapper(this); clearCreatedEvents(); } -ActionData *ActionMapper::getActionDataByIDAndSource(int actionID, int source) +LegacyActionData *ActionMapper::getActionDataByID(int actionID) { for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i) { - if (i->id == actionID && i->source == source) + if (i->id == actionID) return &(*i); } return 0; } -bool ActionMapper::isActing(int actionID, int source) +bool ActionMapper::isActing(unsigned actionID) const { - if(source < 0) - { - for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i) - { - ActionData& ad = *i; - if(ad.id == actionID) - for (ButtonList::iterator ii = ad.buttonList.begin(); ii != ad.buttonList.end(); ++ii) - if (getKeyState(*ii, source)) - return true; - } - return false; - } - - ActionData *ad = getActionDataByIDAndSource(actionID, source); - if (ad) - { - ButtonList::iterator i = ad->buttonList.begin(); - for (; i != ad->buttonList.end(); i++) - { - if (getKeyState(*i, source)) - return true; - } - } - return false; + return actionID < _activeActions.size() ? _activeActions[actionID] : false; } -void ActionMapper::addAction(int actionID, int k, int source) +void ActionMapper::addAction(unsigned actionID, unsigned k) { - ActionData *ad = getActionDataByIDAndSource(actionID, source); + assert(k); + if(!k) + return; + + LegacyActionData *ad = getActionDataByID(actionID); if (!ad) { - ActionData data; + LegacyActionData data; data.id = actionID; - data.source = source; actionData.push_back(data); ad = &actionData.back(); } @@ -96,19 +90,16 @@ void ActionMapper::addAction(int actionID, int k, int source) { if(std::find(ad->buttonList.begin(), ad->buttonList.end(), k) == ad->buttonList.end()) ad->buttonList.push_back(k); - //keyStatus[k] = core->getKeyState(k); } } -void ActionMapper::addAction(Event *event, int k, int state) +void ActionMapper::addAction(Event *event, unsigned k, int state) { - ActionData data; + LegacyActionData data; data.event = event; data.state = state; data.buttonList.push_back(k); actionData.push_back(data); - - //keyStatus[k] = core->getKeyState(k); } Event* ActionMapper::addCreatedEvent(Event *event) @@ -141,89 +132,77 @@ void ActionMapper::disableInput() inputEnabled = false; } -/* -bool ActionMapper::pollAction(int actionID, int source) -{ - if(source < 0) - { - for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); i++) - if(i->id == actionID && _pollActionData(*i)) - return true; - return false; - } - - ActionData *ad = getActionDataByIDAndSource(actionID, source); - return ad && _pollActionData(*ad); -} - -bool ActionMapper::_pollActionData(const ActionData& ad) -{ - const ButtonList& blist = ad.buttonList; - for (ButtonList::const_iterator j = blist.begin(); j != blist.end(); j++) - if (getKeyState((*j))) - return true; - return false; -} -*/ - void ActionMapper::onUpdate (float dt) { - if (inUpdate) - return; - - inUpdate = true; - cleared = false; - - for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i) + if(inputEnabled && !inUpdate) { - for (ButtonList::iterator j = i->buttonList.begin(); j != i->buttonList.end(); j++) - { - const int k = (*j); - const ActionData *ad = &(*i); - const bool keyChanged = isKeyChanged(k, ad->source); + inUpdate = true; + updateDirectInput(); + updateActions(); + inUpdate = false; + } - if (keyChanged) + _actionChanges.clear(); + _inputChanges.clear(); + +} + +void ActionMapper::updateActions() +{ + // Trigger queued events and propagate changes + for(size_t i = 0; i < _actionChanges.size(); ++i) + { + const ActionUpdate& am = _actionChanges[i]; + if(am.id >= _activeActions.size()) + _activeActions.resize(am.id); + _activeActions[am.id] = am.state; + action(am.id, am.state, am.playerID, am.device); + } +} + +void ActionMapper::updateDirectInput() +{ + cleared = false; + for(size_t q = 0; q < _inputChanges.size(); ++q) + { + int ik = _inputChanges[q]; + bool keyState; + unsigned k; + if(ik < 0) + { + keyState = false; + k = -ik; + } + else + { + keyState = true; + k = ik; + } + + for (ActionDataSet::iterator i = actionData.begin(); i != actionData.end(); ++i) + { + const LegacyActionData& ad = (*i); + for (ButtonList::const_iterator j = ad.buttonList.begin(); j != ad.buttonList.end(); j++) { - bool keyState = getKeyState(k, ad->source); - if (inputEnabled) + if(k == (*j)) { - if (ad->event) + if (ad.event) { - if (ad->state==-1 || keyState == !!ad->state) + if (ad.state==-1 || keyState == !!ad.state) { - ad->event->act(); + ad.event->act(); } } else { - action(ad->id, keyState, ad->source, getDeviceForActionbutton(k)); + action(ad.id, keyState, -1, INP_DEV_NODEVICE); } - if (core->loopDone) goto out; + if (core->loopDone || cleared) + return; } - if (cleared) { cleared = false; goto out; } // actionData has been cleared, stop iteration } } } - -out: - inUpdate = false; -} - -bool ActionMapper::getKeyState(int k, int sourceID) -{ - if(sourceID < 0) - return getKeyState(k); - return core->getActionStatus(sourceID)->getKeyState(k); -} - -bool ActionMapper::getKeyState(int k) -{ - // all including sentinel - const int m = core->getMaxActionStatusIndex(); - for(int i = -1; i <= m; ++i) - if(core->getActionStatus(i)->getKeyState(k)) - return true; - return false; } void ActionMapper::clearActions() @@ -232,19 +211,47 @@ void ActionMapper::clearActions() actionData.clear(); } -bool ActionMapper::isKeyChanged(int k, int sourceID) +void ActionMapper::recvAction(unsigned actionID, bool keyState, int playerID, InputDeviceType device) { - if(sourceID < 0) - return isKeyChanged(k); - return core->getActionStatus(sourceID)->isKeyChanged(k); + if(!inputEnabled) + return; + + // enqueue change for later + // Since the update order isn't actually *defined* anywhere but it'm almost sure there + // will be subtle bugs if things aren't updated in the "right" order + // (aka as it happened to be, so far), + // use a queue so that the code can keep believing it's polling changes, while in fact + // under the hood it's a push-based system. + // Pushing every change to a queue also ensures we can't miss a button press that + // lasts shorter than one frame. + ActionUpdate am; + am.id = actionID; + am.state = keyState; + am.playerID = playerID; + am.device = device; + _actionChanges.push_back(am); } -bool ActionMapper::isKeyChanged(int k) +void ActionMapper::recvDirectInput(unsigned k, bool keyState) { - // all including sentinel - const int m = core->getMaxActionStatusIndex(); - for(int i = -1; i <= m; ++i) - if(core->getActionStatus(i)->isKeyChanged(k)) - return true; - return false; + if(!inputEnabled) + return; + + _inputChanges.push_back(keyState ? (int)k : -(int)k); +} + +void ActionMapper::ImportInput(const NamedAction *actions, size_t N) +{ + // FIXME controllerfixup + InputMapper *im = NULL; + ActionSet as; + + /* + for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + { + const ActionSet& as = dsq->user.control.actionSets[i]; + */ + + for(size_t i = 0; i < N; ++i) + as.importAction(im, actions[i].name, actions[i].actionID); } diff --git a/BBGE/ActionMapper.h b/BBGE/ActionMapper.h index 246d32f..4cafbb9 100644 --- a/BBGE/ActionMapper.h +++ b/BBGE/ActionMapper.h @@ -24,43 +24,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Base.h" #include "ActionInput.h" -InputDevice getDeviceForActionbutton(int k); - class Event; class ActionMapper; -#include "ActionStatus.h" #include "ActionSet.h" #include "Joystick.h" -typedef std::vector ButtonList; - -struct ActionData -{ - ActionData() - : id(-1), state(-1), source(-1) - , event(0) - { - } - - int id, state, source; - Event *event; - ButtonList buttonList; -}; +struct LegacyActionData; class ActionMapper { public: + struct NamedAction // for importing + { + const char * const name; + unsigned actionID; + }; // funcs ActionMapper(); virtual ~ActionMapper(); - void addAction(Event *event, int k, int state=-1); - void addAction(int actionID, int k, int source); + // Overridden to react to events (both legacy and input-mapped) + virtual void action(int actionID, int state, int playerID, InputDeviceType device) = 0; - bool isActing(int actionID, int source); - virtual void action(int actionID, int state, int source, InputDevice device) = 0; + + // Legacy actions -- binds keys directly to actions. + // This bypasses the input mapper and checks for keys directly! + void addAction(Event *event, unsigned k, int state = -1); + void addAction(unsigned actionID, unsigned k); + bool isActing(unsigned actionID) const; void clearActions(); @@ -69,7 +62,7 @@ public: // vars - typedef std::vector ActionDataSet; + typedef std::vector ActionDataSet; ActionDataSet actionData; bool cleared; @@ -80,22 +73,41 @@ public: Event *addCreatedEvent(Event *event); void clearCreatedEvents(); - //bool pollAction(int actionID, int source); - bool getKeyState(int k); - bool getKeyState(int k, int sourceID); - ActionData *getActionDataByIDAndSource(int actionID, int source); + // called by InputMapper whenever stuff happens + void recvAction(unsigned actionID, bool state, int playerID, InputDeviceType device); + void recvDirectInput(unsigned k, bool state); + protected: + template static void ImportInput(const NamedAction (&a)[N]) + { + ImportInput(&a[0], N); + } + static void ImportInput(const NamedAction *actions, size_t N); - std::vectorcreatedEvents; + std::vector createdEvents; - bool inUpdate; bool inputEnabled; void onUpdate (float dt); + private: - bool isKeyChanged(int k); - bool isKeyChanged(int k, int sourceID); - //bool _pollActionData(const ActionData& ad); + void updateDirectInput(); + void updateActions(); + + LegacyActionData *getActionDataByID(int actionID); + + struct ActionUpdate + { + unsigned id; + int playerID; + bool state; + InputDeviceType device; + }; + std::vector _actionChanges; + std::vector _inputChanges; // >0: pressed, <0: released + + bool inUpdate; + std::vector _activeActions; }; #endif diff --git a/BBGE/ActionSet.cpp b/BBGE/ActionSet.cpp index 2d3a053..97a99c2 100644 --- a/BBGE/ActionSet.cpp +++ b/BBGE/ActionSet.cpp @@ -33,7 +33,6 @@ JoystickConfig::JoystickConfig() ActionSet::ActionSet() { - inputMode = INPUT_NODEVICE; enabled = true; joystickID = ACTIONSET_REASSIGN_JOYSTICK; } @@ -132,11 +131,11 @@ void ActionSet::updateJoystick() j->setEnabled(true); } -ActionInput *ActionSet::getActionInputByName(const std::string &name) +const ActionInput *ActionSet::getActionInputByName(const std::string &name) const { - for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++) + for (ActionInputSet::const_iterator i = inputSet.begin(); i != inputSet.end(); i++) { - if (nocasecmp((*i).name, name) == 0) + if (nocasecmp(i->getName(), name) == 0) { return &(*i); } @@ -144,52 +143,34 @@ ActionInput *ActionSet::getActionInputByName(const std::string &name) return 0; } -void ActionSet::importAction(ActionMapper *mapper, const std::string &name, int actionID, int sourceID) const +void ActionSet::importAction(InputMapper *mapper, const std::string &name, unsigned actionID) const { if (!enabled) return; if (!mapper) return; - for (size_t i = 0; i < inputSet.size(); i++) + const ActionInput *ac = getActionInputByName(name); + if(!ac) { - const ActionInput *actionInput = &inputSet[i]; - if (actionInput->name == name) - { - for (int i = 0; i < INP_COMBINED_SIZE; i++) - if (actionInput->data.all[i]) - mapper->addAction(actionID, actionInput->data.all[i], sourceID); - return; - } + errorLog("ActionSet::importAction: Undefined action name: " + name); + return; } + + RawInput raw; + for(unsigned i = 0; i < INP_NUMFIELDS; ++i) + if(ac->Export(raw, i)) + if(!mapper->addMapping(InputMapper::TO_BUTTON, raw, actionID)) + errorLog("Failed to map action: " + name); } -void ActionSet::importAction(ActionMapper *mapper, const std::string &name, Event *event, int state) const +ActionInput& ActionSet::ensureActionInput(const std::string &name) { - if (!enabled) return; - if (!mapper) return; + for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++) + if (nocasecmp(i->getName(), name) == 0) + return *i; - for (size_t i = 0; i < inputSet.size(); i++) - { - const ActionInput *actionInput = &inputSet[i]; - if (actionInput->name == name) - { - for (int i = 0; i < INP_COMBINED_SIZE; i++) - if (actionInput->data.all[i]) - mapper->addAction(event, actionInput->data.all[i], state); - return; - } - } -} - -ActionInput *ActionSet::addActionInput(const std::string &name) -{ - ActionInput *a = getActionInputByName(name); - if(a) - return a; - - ActionInput newa; - newa.name = name; + ActionInput newa(name); inputSet.push_back(newa); - return &inputSet.back(); + return inputSet.back(); } /* diff --git a/BBGE/ActionSet.h b/BBGE/ActionSet.h index 91c88d7..7707138 100644 --- a/BBGE/ActionSet.h +++ b/BBGE/ActionSet.h @@ -27,9 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ActionInput.h" -typedef std::vector ActionInputSet; - -class ActionMapper; +class InputMapper; class Event; const int ACTIONSET_REASSIGN_JOYSTICK = -2; @@ -41,14 +39,16 @@ struct JoystickConfig float s1dead, s2dead; }; +// One ActionSet is a serializable configuration of input mappings. class ActionSet { + typedef std::vector ActionInputSet; + public: ActionSet(); - // import this ActionSet into ActionMapper - void importAction(ActionMapper *mapper, const std::string &name, Event *event, int state) const; - void importAction(ActionMapper *mapper, const std::string &name, int actionID, int sourceID) const; + // import this ActionSet into InputMapper. Should be called via ActionMapper::ImportInput() only! + void importAction(InputMapper *mapper, const std::string &name, unsigned actionID) const; void clearActions(); int assignJoystickByName(bool force); // -1 if no such joystick found void assignJoystickIdx(int idx, bool updateValues); @@ -56,11 +56,10 @@ public: // note: this only ENABLES joysticks if they are needed, but never disables any void updateJoystick(); - ActionInput *addActionInput(const std::string &name); - ActionInput *getActionInputByName(const std::string &name); + ActionInput& ensureActionInput(const std::string &name); + const ActionInput *getActionInputByName(const std::string &name) const; - InputDevice inputMode; - size_t joystickID; // >= 0: use that, -1 = no joystick, or ACTIONSET_REASSIGN_JOYSTICK + int joystickID; // >= 0: use that, -1 = no joystick, or ACTIONSET_REASSIGN_JOYSTICK // --- Saved in config --- ActionInputSet inputSet; diff --git a/BBGE/ActionStatus.cpp b/BBGE/ActionStatus.cpp deleted file mode 100644 index ec23836..0000000 --- a/BBGE/ActionStatus.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "ActionStatus.h" -#include "Core.h" -#include "ActionSet.h" - - -ActionButtonStatus::ActionButtonStatus() -: joystickID(-1) -{ - memset(status, 0, sizeof(status)); - memset(changed, 0, sizeof(changed)); -} - -void ActionButtonStatus::import(const ActionSet& as) -{ - joystickID = as.joystickID; - - unsigned char found[ACTION_BUTTON_ENUM_SIZE]; - memset(found, 0, sizeof(found)); - for(size_t i = 0; i < as.inputSet.size(); ++i) - { - const ActionInput& inp = as.inputSet[i]; - for(int j = 0; j < INP_COMBINED_SIZE; ++j) - if(unsigned(inp.data.all[j]) < ACTION_BUTTON_ENUM_SIZE) - found[inp.data.all[j]] = 1; - } - - toQuery.clear(); - for(int k = 1; k < sizeof(found); ++k) // ignore [0] - if(found[k]) - toQuery.push_back(k); - - memset(status, 0, sizeof(status)); - memset(changed, 0, sizeof(changed)); - - update(); -} - -void ActionButtonStatus::importQuery(const int *pKeys, size_t num) -{ - unsigned char found[ACTION_BUTTON_ENUM_SIZE]; - memset(found, 0, sizeof(found)); - for(size_t i = 0; i < num; ++i) - if(unsigned(pKeys[i]) < ACTION_BUTTON_ENUM_SIZE) - found[pKeys[i]] = 1; - - toQuery.clear(); - for(int k = 1; k < sizeof(found); ++k) // ignore [0] - if(found[k]) - toQuery.push_back(k); - - memset(status, 0, sizeof(status)); - memset(changed, 0, sizeof(changed)); - - update(); -} - -void ActionButtonStatus::update() -{ - _queryAllStatus(); -} - -void ActionButtonStatus::_queryAllStatus() -{ - // k==0 is always 0 - for(size_t i = 0; i < toQuery.size(); ++i) - { - const int k = toQuery[i]; - bool state = _queryStatus(k); - changed[k] = !!status[k] != state; - status[k] = state; - } -} - -bool ActionButtonStatus::_queryStatus(int k) const -{ - if (k > 0 && k < KEY_MAXARRAY) - return core->getKeyState(k); - - if (k == MOUSE_BUTTON_LEFT) - return core->mouse.buttons.left == DOWN; - - if (k == MOUSE_BUTTON_RIGHT) - return core->mouse.buttons.right == DOWN; - - if (k == MOUSE_BUTTON_MIDDLE) - return core->mouse.buttons.middle == DOWN; - - if (k >= MOUSE_BUTTON_EXTRA_START && k < MOUSE_BUTTON_EXTRA_END) - return core->mouse.buttons.extra[k - MOUSE_BUTTON_EXTRA_START]; - - // --- joystick from here --- - - Joystick *j = core->getJoystick(joystickID); - if(!j || !j->isEnabled()) - return false; - - if (k >= JOY_BUTTON_0 && k < JOY_BUTTON_END) - return j->getButton(k - JOY_BUTTON_0); - - if (k >= JOY_AXIS_0_POS && k < JOY_AXIS_END_POS) - { - float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_POS); - return ax > JOY_AXIS_THRESHOLD; - } - - if (k >= JOY_AXIS_0_NEG && k < JOY_AXIS_END_NEG) - { - float ax = j->getAxisUncalibrated(k - JOY_AXIS_0_NEG); - return ax < -JOY_AXIS_THRESHOLD; - } - - if(k >= JOY_HAT_BEGIN && k < JOY_HAT_END) - { - if (k >= JOY_HAT_0_LEFT && k < JOY_HAT_END_LEFT) - return j->getHat(k - JOY_HAT_0_LEFT); - - if (k >= JOY_HAT_0_RIGHT && k < JOY_HAT_END_RIGHT) - return j->getHat(k - JOY_HAT_0_RIGHT); - - if (k >= JOY_HAT_0_UP && k < JOY_HAT_END_UP) - return j->getHat(k - JOY_HAT_0_UP); - - if (k >= JOY_HAT_0_DOWN && k < JOY_HAT_END_DOWN) - return j->getHat(k - JOY_HAT_0_DOWN); - } - - return false; -} - -ActionButtonType joyHatToActionButton(unsigned hatID, JoyHatDirection dir) -{ - unsigned ret = 0; - if(hatID < MAX_JOYSTICK_HATS) - { - if(dir & JOY_HAT_DIR_LEFT) - ret = JOY_HAT_0_LEFT; - else if(dir & JOY_HAT_DIR_RIGHT) - ret = JOY_HAT_0_RIGHT; - else if(dir & JOY_HAT_DIR_UP) - ret = JOY_HAT_0_UP; - else if(dir & JOY_HAT_DIR_DOWN) - ret = JOY_HAT_0_DOWN; - - if(ret) - ret += hatID; - } - - return (ActionButtonType)ret; -} - diff --git a/BBGE/ActionStatus.h b/BBGE/ActionStatus.h deleted file mode 100644 index 6f17fff..0000000 --- a/BBGE/ActionStatus.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef ACTIONSTATUS_H -#define ACTIONSTATUS_H - -#include "GameKeys.h" -#include "Joystick.h" - -class ActionSet; - -const unsigned mouseExtraButtons = 8; - -// *_END is non-inclusive! -enum ActionButtonType -{ - MOUSE_BUTTON_LEFT = KEY_MAXARRAY + 1, - MOUSE_BUTTON_RIGHT, - MOUSE_BUTTON_MIDDLE, - MOUSE_BUTTON_EXTRA_START, - MOUSE_BUTTON_EXTRA_END = MOUSE_BUTTON_EXTRA_START + mouseExtraButtons, - - JOY_BUTTON_0 = MOUSE_BUTTON_EXTRA_END, - JOY_BUTTON_END = JOY_BUTTON_0 + MAX_JOYSTICK_BTN, - - JOY_AXIS_0_POS = JOY_BUTTON_END, - JOY_AXIS_END_POS = JOY_AXIS_0_POS + MAX_JOYSTICK_AXIS, - - JOY_AXIS_0_NEG = JOY_AXIS_END_POS, - JOY_AXIS_END_NEG = JOY_AXIS_0_NEG + MAX_JOYSTICK_AXIS, - - JOY_HAT_BEGIN = JOY_AXIS_END_NEG, - JOY_HAT_0_LEFT = JOY_HAT_BEGIN, - JOY_HAT_END_LEFT = JOY_HAT_0_LEFT + MAX_JOYSTICK_HATS, - - JOY_HAT_0_RIGHT = JOY_HAT_END_LEFT, - JOY_HAT_END_RIGHT = JOY_HAT_0_RIGHT + MAX_JOYSTICK_HATS, - - JOY_HAT_0_UP = JOY_HAT_END_RIGHT, - JOY_HAT_END_UP = JOY_HAT_0_UP + MAX_JOYSTICK_HATS, - - JOY_HAT_0_DOWN = JOY_HAT_END_UP, - JOY_HAT_END_DOWN = JOY_HAT_0_DOWN + MAX_JOYSTICK_HATS, - JOY_HAT_END = JOY_HAT_END_DOWN, - - ACTION_BUTTON_ENUM_SIZE = JOY_HAT_END -}; - -ActionButtonType joyHatToActionButton(unsigned hatID, JoyHatDirection dir); - -class ActionButtonStatus -{ -public: - ActionButtonStatus(); - void update(); - inline bool getKeyState(int k) const { return !!status[k]; } - inline bool isKeyChanged(int k) { return !!changed[k]; } - void import(const ActionSet& as); - void importQuery(const int *pKeys, size_t num); - inline const std::vector& getToQuery() const {return toQuery; } - inline int getJoystickID() const { return joystickID; } -private: - void _queryAllStatus(); - bool _queryStatus(int k) const; - - int joystickID; - unsigned char status[ACTION_BUTTON_ENUM_SIZE]; - unsigned char changed[ACTION_BUTTON_ENUM_SIZE]; - std::vector toQuery; -}; - - -#endif diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index 1201a5f..106aeec 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -360,8 +360,6 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n mouseCircle = 0; overrideStartLayer = 0; overrideEndLayer = 0; - frameOutputMode = false; - updateMouse = true; particlesPaused = false; joystickAsMouse = false; currentLayerPass = 0; @@ -384,11 +382,6 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n loopDone = false; core = this; - for (int i = 0; i < KEY_MAXARRAY; i++) - { - keys[i] = 0; - } - globalResolutionScale = globalScale = Vector(1,1,1); initRenderObjectLayers(numRenderLayers); @@ -476,8 +469,6 @@ std::string Core::getUserDataFolder() Core::~Core() { - clearActionButtons(); - if (particleManager) { delete particleManager; @@ -534,7 +525,7 @@ void Core::init() { setupFileAccess(); - unsigned sdlflags = SDL_INIT_EVERYTHING; + unsigned sdlflags = SDL_INIT_EVERYTHING & ~SDL_INIT_TIMER; quitNestedMainFlag = false; #ifdef BBGE_BUILD_SDL2 @@ -587,27 +578,9 @@ Vector Core::getGamePosition(const Vector &v) return cameraPos + (v * invGlobalScale); } -bool Core::getMouseButtonState(int m) +bool Core::getKeyState(unsigned k) const { - int mcode=m; - - switch(m) - { - case 0: mcode=1; break; - case 1: mcode=3; break; - case 2: mcode=2; break; - } - - Uint8 mousestate = SDL_GetMouseState(0,0); - - return mousestate & SDL_BUTTON(mcode); - return false; -} - -bool Core::getKeyState(int k) -{ - assert(k < KEY_MAXARRAY); - return k > 0 && k < KEY_MAXARRAY ? keys[k] : 0; + return rawInput.isKeyPressed(k); } void Core::initJoystickLibrary() @@ -652,12 +625,6 @@ void Core::detectJoysticks() bool Core::initInputLibrary() { core->mouse.position = Vector(getWindowWidth()/2, getWindowHeight()/2); - - for (int i = 0; i < KEY_MAXARRAY; i++) - { - keys[i] = 0; - } - return true; } @@ -1255,6 +1222,10 @@ bool Core::doMouseConstraint() void Core::onEvent(const SDL_Event& event) { const bool focus = window->hasFocus(); + + if(focus) + InputSystem::handleSDLEvent(&event); + switch (event.type) { case SDL_KEYDOWN: @@ -1263,37 +1234,12 @@ void Core::onEvent(const SDL_Event& event) { setInputGrab(!grabInput); } - else if (focus) - { -#ifdef BBGE_BUILD_SDL2 - unsigned kidx = event.key.keysym.scancode; -#else - unsigned kidx = event.key.keysym.sym; -#endif - if(kidx < KEY_MAXARRAY) - keys[kidx] = 1; - } - } - break; - - case SDL_KEYUP: - { - if (focus) - { -#ifdef BBGE_BUILD_SDL2 - unsigned kidx = event.key.keysym.scancode; -#else - unsigned kidx = event.key.keysym.sym; -#endif - if(kidx < KEY_MAXARRAY) - keys[kidx] = 0; - } } break; case SDL_MOUSEMOTION: { - if (focus && updateMouse) + if (focus) { mouse.lastPosition = mouse.position; @@ -1309,19 +1255,6 @@ void Core::onEvent(const SDL_Event& event) break; #ifdef BBGE_BUILD_SDL2 - - case SDL_MOUSEWHEEL: - { - if (focus && updateMouse) - { - if (event.wheel.y > 0) - mouse.scrollWheelChange = 1; - else if (event.wheel.y < 0) - mouse.scrollWheelChange = -1; - } - } - break; - case SDL_JOYDEVICEADDED: onJoystickAdded(event.jdevice.which); break; @@ -1329,82 +1262,12 @@ void Core::onEvent(const SDL_Event& event) case SDL_JOYDEVICEREMOVED: onJoystickRemoved(event.jdevice.which); break; - -#else - case SDL_MOUSEBUTTONDOWN: - { - if (focus && updateMouse) - { - switch(event.button.button) - { - case 4: - mouse.scrollWheelChange = 1; - break; - case 5: - mouse.scrollWheelChange = -1; - break; - } - } - } - break; - - case SDL_MOUSEBUTTONUP: - { - if (focus && updateMouse) - { - switch(event.button.button) - { - case 4: - mouse.scrollWheelChange = 1; - break; - case 5: - mouse.scrollWheelChange = -1; - break; - } - } - } - break; #endif } } void Core::pollEvents(float dt) { - bool warpMouse=false; - - - - if (updateMouse) - { - int x, y; - unsigned mousestate = SDL_GetMouseState(&x,&y); - - if (mouse.buttonsEnabled) - { - mouse.buttons.left = mousestate & SDL_BUTTON(1)?DOWN:UP; - mouse.buttons.right = mousestate & SDL_BUTTON(3)?DOWN:UP; - mouse.buttons.middle = mousestate & SDL_BUTTON(2)?DOWN:UP; - - for(unsigned i = 0; i < mouseExtraButtons; ++i) - mouse.buttons.extra[i] = mousestate & SDL_BUTTON(3+i)?DOWN:UP; - - mouse.pure_buttons = mouse.buttons; - mouse.rawButtonMask = mousestate; - - if (flipMouseButtons) - { - std::swap(mouse.buttons.left, mouse.buttons.right); - } - } - else - { - mouse.buttons.left = mouse.buttons.right = mouse.buttons.middle = UP; - } - - mouse.scrollWheelChange = 0; - mouse.change = Vector(0,0); - } - window->handleInput(); for(size_t i = 0; i < joysticks.size(); ++i) @@ -1412,8 +1275,8 @@ void Core::pollEvents(float dt) joysticks[i]->update(dt); // all input done; update button states - updateActionButtons(); - + //updateActionButtons(); + rawInput.update(); } #define _VLN(x, y, x2, y2) glVertex2f(x, y); glVertex2f(x2, y2); @@ -2442,11 +2305,9 @@ void Core::onJoystickAdded(int deviceID) if(!joysticks[i]) { joysticks[i] = j; - goto done; + return; } joysticks.push_back(j); -done: - ; } void Core::onJoystickRemoved(int instanceID) @@ -2467,26 +2328,6 @@ Joystick *Core::getJoystick(size_t idx) return i < joysticks.size() ? joysticks[i] : NULL; } -void Core::updateActionButtons() -{ - for(size_t i = 0; i < actionStatus.size(); ++i) - actionStatus[i]->update(); -} - -void Core::clearActionButtons() -{ - for(size_t i = 0; i < actionStatus.size(); ++i) - delete actionStatus[i]; - actionStatus.clear(); -} - -Joystick *Core::getJoystickForSourceID(int sourceID) -{ - if(unsigned(sourceID+1) < (unsigned)actionStatus.size()) - return getJoystick(actionStatus[sourceID+1]->getJoystickID()); - return NULL; -} - #include bool Core::pngSave(const char *filename, unsigned width, unsigned height, unsigned char *data) diff --git a/BBGE/Core.h b/BBGE/Core.h index c6173c2..5847353 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "DarkLayer.h" #include "GameKeys.h" +#include "InputMapperRaw.h" class ParticleEffect; class Joystick; @@ -81,7 +82,6 @@ struct MouseButtons } ButtonState left, right, middle; - ButtonState extra[mouseExtraButtons]; }; struct Mouse @@ -96,7 +96,7 @@ struct Mouse MouseButtons pure_buttons; unsigned rawButtonMask; Vector change; - bool buttonsEnabled; + bool buttonsEnabled; //KILL int scrollWheelChange; }; @@ -273,7 +273,7 @@ public: void setMouseConstraint(bool on); void setMouseConstraintCircle(const Vector& pos, float mouseCircle); - virtual void action(int id, int state, int source, InputDevice device){} + virtual void action(int id, int state, int playerID, InputDeviceType device) {} bool exists(const std::string &file); @@ -372,11 +372,10 @@ public: void clearRenderObjects(); - bool getKeyState(int k); - bool getMouseButtonState(int m); + bool getKeyState(unsigned k) const; + bool isKeyChanged(unsigned k) const; int currentLayerPass; - int keys[KEY_MAXARRAY]; virtual void debugLog(const std::string &s); virtual void errorLog(const std::string &s); void messageBox(const std::string &title, const std::string &msg); @@ -404,12 +403,9 @@ public: int flipMouseButtons; FrameBuffer frameBuffer; void updateRenderObjects(float dt); - bool joystickAsMouse; + bool joystickAsMouse; //KILL? virtual void prepScreen(bool t){} - bool updateMouse; - bool frameOutputMode; - int overrideStartLayer, overrideEndLayer; ParticleEffect* createParticleEffect(const std::string &name, const Vector &position, int layer, float rotz=0); @@ -536,20 +532,13 @@ protected: void setupFileAccess(); std::string _extraDataDir; - std::vector actionStatus; // contains at least 1 element (the sentinel) - virtual void updateActionButtons(); - void clearActionButtons(); + InputMapperRaw rawInput; public: - // inclusive! - inline int getMaxActionStatusIndex() const { return int(actionStatus.size()) - 2; } - // pass -1 for is a sentinel that captures all input - inline ActionButtonStatus *getActionStatus(size_t idx) { return actionStatus[idx + 1]; } Joystick *getJoystick(size_t idx); // warning: may return NULL/contain holes // not the actual number of joysticks! size_t getNumJoysticks() const { return joysticks.size(); } - Joystick *getJoystickForSourceID(int sourceID); private: std::vector joysticks; }; diff --git a/BBGE/Event.cpp b/BBGE/Event.cpp index 30df3eb..765dab4 100644 --- a/BBGE/Event.cpp +++ b/BBGE/Event.cpp @@ -64,7 +64,7 @@ void EventPtr::call() } if (actionMapperCallback) { - actionMapperCallback->action(actionValue, stateToCall, -1, INPUT_NODEVICE); + actionMapperCallback->action(actionValue, stateToCall, -1, INP_DEV_NODEVICE); } } diff --git a/BBGE/GameKeyNames.cpp b/BBGE/GameKeyNames.cpp index 2cfd1b5..73c612f 100644 --- a/BBGE/GameKeyNames.cpp +++ b/BBGE/GameKeyNames.cpp @@ -1,12 +1,12 @@ #include "GameKeyNames.h" -#include "ActionStatus.h" +#include "GameKeys.h" #include #include typedef std::map InputCodeMap; -InputCodeMap inputCodeMap; -static std::string keyNames[ACTION_BUTTON_ENUM_SIZE]; +static InputCodeMap inputCodeMap; +static const char *keyNames[ACTION_BUTTON_ENUM_SIZE]; static void initInputCodeMap() { @@ -101,38 +101,31 @@ static void initInputCodeMap() K(KEY_RBRACKET) K(KEY_TILDE) - K(MOUSE_BUTTON_LEFT) K(MOUSE_BUTTON_RIGHT) K(MOUSE_BUTTON_MIDDLE) #undef K - for (int jb = JOY_BUTTON_0; jb < JOY_BUTTON_END; jb++) - { - char buf[32]; - sprintf(buf, "JOY_BUTTON_%d", jb - JOY_BUTTON_0); - inputCodeMap[buf] = jb; - } - // ---------------------- + for(size_t i = 0; i < ACTION_BUTTON_ENUM_SIZE; ++i) + keyNames[i] = NULL; + // Can just use pointers to the strings in the map; they'll stay where they are in memory for(InputCodeMap::iterator it = inputCodeMap.begin(); it != inputCodeMap.end(); ++it) - keyNames[it->second] = it->first; + keyNames[it->second] = it->first.c_str(); } -int getInputCodeFromKeyName(const char *name) +unsigned getLegacyInputCodeFromKeyName(const std::string& name) { + if(inputCodeMap.empty()) + initInputCodeMap(); return inputCodeMap[name]; } -const std::string& getKeyNameFromInputCode(int k) +const char *getLegacyKeyNameFromInputCode(unsigned k) { + if(inputCodeMap.empty()) + initInputCodeMap(); return keyNames[k]; } - -struct KeyNameInitializer -{ - KeyNameInitializer() { initInputCodeMap(); } -}; -static KeyNameInitializer s_kinit; diff --git a/BBGE/GameKeyNames.h b/BBGE/GameKeyNames.h index f83e6f3..bd8ab6a 100644 --- a/BBGE/GameKeyNames.h +++ b/BBGE/GameKeyNames.h @@ -3,7 +3,7 @@ #include -int getInputCodeFromKeyName(const char *name); -const std::string& getKeyNameFromInputCode(int k); +unsigned getLegacyInputCodeFromKeyName(const std::string& name); +const char *getLegacyKeyNameFromInputCode(unsigned k); #endif diff --git a/BBGE/GameKeys.h b/BBGE/GameKeys.h index 45b032f..e4d6b15 100644 --- a/BBGE/GameKeys.h +++ b/BBGE/GameKeys.h @@ -241,4 +241,17 @@ #endif // BBGE_BUILD_SDL2 + +// Extra symbolic names that the engine may use when referencing keys +// For use with ActionMapper::addAction() +// (also see GameKeyNames.cpp) +enum ActionButtonType +{ + MOUSE_BUTTON_LEFT = KEY_MAXARRAY + 1, + MOUSE_BUTTON_RIGHT, + MOUSE_BUTTON_MIDDLE, + + ACTION_BUTTON_ENUM_SIZE +}; + #endif // BBGE_GAME_KEYS_H diff --git a/BBGE/InputMapper.cpp b/BBGE/InputMapper.cpp new file mode 100644 index 0000000..5ae5d36 --- /dev/null +++ b/BBGE/InputMapper.cpp @@ -0,0 +1,267 @@ +#include "InputMapper.h" +#include "InputSystem.h" +#include "ActionMapper.h" +#include +#include +#include + +std::vector IInputMapper::s_actionmappers; + +GameControlState::GameControlState(size_t numbuttons, size_t numaxes) +: buttons(numbuttons), axes(numaxes) +, mouseX(0), mouseY(0), wheelDelta(0) +, lastDevice(INP_DEV_NODEVICE) +{ +} + +void GameControlState::clear() +{ + std::fill(axes.begin(), axes.end(), 0.0f); + std::fill(buttons.begin(), buttons.end(), 0); +} + +// ----------------- + +void IInputMapper::RegisterActionMapper(ActionMapper *mapper) +{ + s_actionmappers.push_back(mapper); +} + +void IInputMapper::UnregisterActionMapper(ActionMapper *mapper) +{ + s_actionmappers.erase(std::remove(s_actionmappers.begin(), s_actionmappers.end(), mapper), s_actionmappers.end()); +} + +void IInputMapper::ForwardAction(unsigned idx, bool state, int playerID, InputDeviceType dev) +{ + const size_t N = s_actionmappers.size(); + for(size_t i = 0; i < N; ++i) + s_actionmappers[i]->recvAction(idx, state, playerID, dev); +} + +void IInputMapper::ForwardDirectInput(unsigned k, bool state) +{ + const size_t N = s_actionmappers.size(); + for(size_t i = 0; i < N; ++i) + s_actionmappers[i]->recvDirectInput(k, state); +} + + +// ------------------ + + +IInputMapper::IInputMapper() +{ + InputSystem::addMapper(this); +} + +IInputMapper::~IInputMapper() +{ + InputSystem::addMapper(this); +} + +// ------------------ + +InputMapper::InputMapper(int playerID) +: acceptMouse(true), acceptMouseID(-1), playerID(playerID) +{ +} + +InputMapper::~InputMapper() +{ + InputSystem::removeMapper(this); +} + +static float rescale(float t, float lower, float upper, float rangeMin, float rangeMax) +{ + if(upper == lower) + return rangeMin; + + return (((t - lower) / (upper - lower)) * (rangeMax - rangeMin)) + rangeMin; +} + +static float clamp(float x, float a, float b) +{ + return std::max(a, std::min(x, b)); +} + +static float rescaleClamp(float t, float lower, float upper, float rangeMin, float rangeMax) +{ + return clamp(rescale(t, lower, upper, rangeMin, rangeMax), std::min(rangeMin, rangeMax), std::max(rangeMin, rangeMax)); +} + +unsigned char InputMapper::MapToButton(const Mapping& m) +{ + assert(m.buttonOrAxis > 0); + + switch(m.raw.src.ctrlType) + { + case INP_CTRL_BUTTON: + return m.raw.u.pressed; + + case INP_CTRL_AXIS: // when axis is beyond threshold, register as button press + return m.val.axis > 0 + ? m.raw.u.axis > m.val.axis + : m.raw.u.axis < m.val.axis; + + case INP_CTRL_HAT: + return !memcmp(&m.raw.u.ivec, &m.val.ivec, sizeof(m.raw.u.ivec)); + + default: + ; + } + + return 0; +} + +float InputMapper::MapToAxis(const Mapping& m) +{ + assert(m.buttonOrAxis < 0); + + switch(m.raw.src.ctrlType) + { + case INP_CTRL_BUTTON: + return m.raw.u.pressed ? m.val.axis : 0.0f; + + case INP_CTRL_WHEEL: + return m.raw.u.axis * m.val.axis; + + case INP_CTRL_AXIS: + return m.raw.u.axis < 0 + ? rescaleClamp(m.raw.u.axis, m.val.axis, 1.0f, 0.0f, 1.0f) + : rescaleClamp(m.raw.u.axis, -m.val.axis, -1.0f, 0.0f, -1.0f); + + case INP_CTRL_HAT: // hat to axis; one hat direction should be 0 + return m.val.axis * m.raw.u.ivec.x + m.val.axis * m.raw.u.ivec.y; + + default: + ; + } + + return 0.0f; +} + +void InputMapper::accumulate(GameControlState *ctrl) +{ + ctrl->wheelDelta = wheelDelta; + ctrl->mouseX = mouseX; + ctrl->mouseY = mouseY; + + // walk over all inputs, check the values, apply to state + const size_t N = mappings.size(); + for(size_t i = 0; i < N; ++i) + { + const Mapping& m = mappings[i]; + if(m.buttonOrAxis > 0) + ctrl->buttons[m.buttonOrAxis - 1] += MapToButton(m); + if(m.buttonOrAxis < 0) + ctrl->axes[-m.buttonOrAxis - 1] += MapToAxis(m); + + ctrl->lastDevice = m.raw.src.deviceType; + } + + wheelDelta = 0; +} + +// TODO controllerfixup: need "follow-up" mapping +// means "axis A -> mapped axis 0 ==> if mapped axis 0 > thresh -> trigger action +// same for buttons: ACTION_SWIMLEFT -> ACTION_MENULEFT + +void InputMapper::input(const RawInput *inp) +{ + size_t N = mappings.size(); + if(inp->src.deviceType == INP_DEV_MOUSE && acceptMouse && (acceptMouseID < 0 || inp->src.deviceID == acceptMouseID)) + { + switch(inp->src.ctrlType) + { + case INP_CTRL_POSITION: + mouseX = inp->u.ivec.x; + mouseY = inp->u.ivec.y; + break; + + case INP_CTRL_WHEEL: + wheelDelta += inp->u.axis; // accumulate deltas until fetched + break; + } + } + + for(size_t i = 0; i < N; ++i) + { + Mapping& m = mappings[i]; + if(!memcmp(&m.raw.src, &inp->src, sizeof(m.raw.src))) + { + memcpy(&m.raw.u, &inp->u, sizeof(m.raw.u)); // store raw inputs if source matches + + if(m.buttonOrAxis > 0) // Mapped to an action? + { + unsigned char state = MapToButton(m); // Does this count as a button press? + if(m.buttonState != state) // Did it actually change? (filter Axis movements that don't actually "release" the button) + ForwardAction(m.buttonOrAxis - 1, state, playerID, inp->src.deviceType); + } + } + } +} + +// don't trigger if we just released a button or wiggled an analog stick by 1/10th millimeter. +bool InputMapper::CleanupForMapping(InputControlType c, InputMapper::MapType mt, InputValue& val) +{ + switch(c) + { + case INP_CTRL_BUTTON: + if(!val.pressed) + return false; + val.pressed = 1; + return true; + + case INP_CTRL_AXIS: + //if(fabsf(val.axis) < 0.6f) + // return false; + if(mt == TO_AXIS && val.axis < 0) + val.axis = -val.axis; + return true; + + case INP_CTRL_HAT: + if(!!val.ivec.x + !!val.ivec.y != 1) // exactly one hat axis, not centered, not diagonal + return false; + if(mt == TO_AXIS) + { + // make sure the axis goes in the right direction + if(val.ivec.x < 0) + val.ivec.x = -val.ivec.x; + if(val.ivec.y < 0) + val.ivec.y = -val.ivec.y; + } + return true; + + case INP_CTRL_POSITION: + return false; + + case INP_CTRL_WHEEL: + if(!val.axis) + return false; + if(mt == TO_AXIS && val.axis < 0) + val.axis = -val.axis; + } + + return false; +} + + +bool InputMapper::addMapping(MapType mt, const RawInput& inp, unsigned targetID) +{ + Mapping m; + m.buttonOrAxis = 1 + (mt == TO_BUTTON ? int(targetID) : -int(targetID)); + m.raw = inp; + m.val = inp.u; + + if(!CleanupForMapping(inp.src.ctrlType, mt, m.val)) + return false; + + mappings.push_back(m); + return true; +} + +void InputMapper::clearMapping() +{ + mappings.clear(); +} diff --git a/BBGE/InputMapper.h b/BBGE/InputMapper.h new file mode 100644 index 0000000..b3a182b --- /dev/null +++ b/BBGE/InputMapper.h @@ -0,0 +1,89 @@ +#ifndef BBGE_INPUTMAPPER_H +#define BBGE_INPUTMAPPER_H + +#include "InputSystem.h" +#include + +class ActionMapper; + +// This is what the engine sees to handle the current state. +// Changes are not tracked here! +struct GameControlState +{ + GameControlState(size_t numbuttons, size_t numaxes); + int mouseX, mouseY; + float wheelDelta; + InputDeviceType lastDevice; + std::vector buttons; // actually bool + std::vector axes; // uncalibrated floats, -1 .. +1 + + void clear(); // Call before InputMapper::accumulate() +}; + +class IInputMapper +{ +public: + IInputMapper(); + virtual void input(const RawInput *inp) = 0; + + // Called by ActionMapper ctor/dtor to register itself + static void RegisterActionMapper(ActionMapper *mapper); + static void UnregisterActionMapper(ActionMapper *mapper); + + // Forward actions to all registered input mappers + static void ForwardAction(unsigned idx, bool state, int playerID, InputDeviceType dev); + static void ForwardDirectInput(unsigned k, bool state); + +protected: + virtual ~IInputMapper(); + +private: + // shared between all InputMapper instances + static std::vector s_actionmappers; +}; + +// Maps raw device input to player input. +// One mapper per player. +class InputMapper : public IInputMapper +{ +public: + InputMapper(int playerID); + ~InputMapper(); + + bool acceptMouse; + int acceptMouseID; // -1: accept all, otherwise: that id + + // raw data go in + virtual void input(const RawInput *inp); + + // output: apply changes to ctrl + void accumulate(GameControlState *ctrl); + + enum MapType + { + TO_BUTTON, + TO_AXIS + }; + bool addMapping(MapType mt, const RawInput& inp, unsigned targetID); + void clearMapping(); + +private: + struct Mapping + { + RawInput raw; // last input that came in, also contains src to check for + int buttonOrAxis; + InputValue val; // used as min. axis value to trigger, deadzone, hat direction, etc + unsigned char buttonState; // for buttons: consider this pressed? + }; + const int playerID; + const GameControlState *target; + float wheelDelta; + int mouseX, mouseY; + std::vector mappings; + + static unsigned char MapToButton(const InputMapper::Mapping& m); + static float MapToAxis(const InputMapper::Mapping& m); + static bool CleanupForMapping(InputControlType c, InputMapper::MapType mt, InputValue& val); // modifies val, returns whether acceptable +}; + +#endif diff --git a/BBGE/InputMapperRaw.cpp b/BBGE/InputMapperRaw.cpp new file mode 100644 index 0000000..b5f357b --- /dev/null +++ b/BBGE/InputMapperRaw.cpp @@ -0,0 +1,60 @@ +#include "InputMapperRaw.h" +#include + +InputMapperRaw::InputMapperRaw() +{ + memset(&keyState[0], 0, sizeof(keyState)); +} + +InputMapperRaw::~InputMapperRaw() +{ +} + +void InputMapperRaw::input(const RawInput *inp) +{ + if(inp->src.ctrlType != INP_CTRL_BUTTON) + return; + + unsigned idx = inp->src.ctrlID; + switch(inp->src.deviceType) + { + case INP_DEV_MOUSE: + if(idx > 2) + return; // only want left, middle, right button + idx += MOUSE_BUTTON_LEFT; + // fall through + case INP_DEV_KEYBOARD: + break; // all good + default: // not interested in joystick etc buttons, those are only used via InputMapper + return; + } + + // record change as soon as a change event comes in, + // so we don't lose button presses that are shorter than 1 frame. + unsigned char ch = !!inp->u.pressed; + keyChanged[idx] |= (keyState[idx] != ch) << 1; // bit 1 becomes bit 0 in next frame + keyState[idx] |= ch; + + +} + +void InputMapperRaw::update() +{ + // make sure that the change bit lives for at least 1 frame + for(size_t i = 0; i < sizeof(keyChanged); ++i) + keyChanged[i] >>= 1; +} + +bool InputMapperRaw::isKeyPressed(unsigned k) const +{ + assert(k < sizeof(keyState)); + return k < sizeof(keyState) ? !!keyState[k] : false; +} + +bool InputMapperRaw::isKeyChanged(unsigned k) const +{ + assert(k < sizeof(keyChanged)); + return k < sizeof(keyChanged) ? !!keyChanged[k] : false; +} + + diff --git a/BBGE/InputMapperRaw.h b/BBGE/InputMapperRaw.h new file mode 100644 index 0000000..329545c --- /dev/null +++ b/BBGE/InputMapperRaw.h @@ -0,0 +1,27 @@ +#ifndef BBGE_INPUTMAPPERRAW_H +#define BBGE_INPUTMAPPERRAW_H + +#include "InputMapper.h" +#include "GameKeys.h" + +// Legacy mapper: Raw keys to game actions. Required by e.g. editor. +// Used by legacy parts of ActionMapper. +class InputMapperRaw : public IInputMapper +{ +public: + InputMapperRaw(); + virtual ~InputMapperRaw(); + virtual void input(const RawInput *inp); + void update(); + + bool isKeyPressed(unsigned k) const; + bool isKeyChanged(unsigned k) const; + +private: + // actually bools + unsigned char keyState[ACTION_BUTTON_ENUM_SIZE]; + unsigned char keyChanged[ACTION_BUTTON_ENUM_SIZE]; +}; + + +#endif diff --git a/BBGE/InputSystem.cpp b/BBGE/InputSystem.cpp new file mode 100644 index 0000000..0038553 --- /dev/null +++ b/BBGE/InputSystem.cpp @@ -0,0 +1,28 @@ +#include "InputSystem.h" +#include "InputMapper.h" +#include +#include + +namespace InputSystem { + +static std::vector s_mappers; + +void handleRawInput(const RawInput *inp) +{ + size_t N = s_mappers.size(); + for(size_t i = 0; i < N; ++i) + s_mappers[i]->input(inp); +} + +void addMapper(IInputMapper *mapper) +{ + removeMapper(mapper); + s_mappers.push_back(mapper); +} + +void removeMapper(IInputMapper *mapper) +{ + s_mappers.erase(std::remove(s_mappers.begin(), s_mappers.end(), mapper), s_mappers.end()); +} + +} // end namespace InputSystem diff --git a/BBGE/InputSystem.h b/BBGE/InputSystem.h new file mode 100644 index 0000000..d5bccb3 --- /dev/null +++ b/BBGE/InputSystem.h @@ -0,0 +1,55 @@ +#ifndef BBGE_INPUTSYSTEM_H +#define BBGE_INPUTSYSTEM_H + +enum InputDeviceType +{ + INP_DEV_NODEVICE, + INP_DEV_KEYBOARD, + INP_DEV_MOUSE, + INP_DEV_JOYSTICK, +}; + +enum InputControlType +{ + INP_CTRL_BUTTON, // keyboard key or joystick button + INP_CTRL_AXIS, // joystick axis + INP_CTRL_HAT, // "digital axis" + INP_CTRL_WHEEL, // no absolute position, only knows relative changes + INP_CTRL_POSITION, // only absolute position +}; + +struct InputSource +{ + InputDeviceType deviceType; + unsigned deviceID; + InputControlType ctrlType; + unsigned ctrlID; +}; + +union InputValue +{ + float axis; // abs. axis value or wheel delta + unsigned pressed; // used as bool + // TODO constrollerfixup: add uchar .hat, SDL uses a bitmask! + struct { int x, y; } ivec; // -1, 0, +1 as hat values, window coords, etc +}; + +struct RawInput +{ + InputSource src; + InputValue u; +}; + +union SDL_Event; +class IInputMapper; + +namespace InputSystem +{ + void handleSDLEvent(const SDL_Event *ev); + void handleRawInput(const RawInput *inp); + + void addMapper(IInputMapper *mapper); + void removeMapper(IInputMapper *mapper); +}; + +#endif diff --git a/BBGE/InputSystemSDL.cpp b/BBGE/InputSystemSDL.cpp new file mode 100644 index 0000000..4a2b586 --- /dev/null +++ b/BBGE/InputSystemSDL.cpp @@ -0,0 +1,156 @@ +#include "InputSystem.h" +#include + +#if SDL_VERSION_ATLEAST(2,0,0) +#define USESDL2 +#endif + +void InputSystem::handleSDLEvent(const SDL_Event *ev) +{ + RawInput raw; + + switch(ev->type) + { + case SDL_MOUSEMOTION: + { + raw.src.deviceType = INP_DEV_MOUSE; + raw.src.deviceID = ev->motion.which; + raw.src.ctrlType = INP_CTRL_POSITION; + raw.src.ctrlID = ev->motion.which; + raw.u.ivec.x = ev->motion.x; + raw.u.ivec.y = ev->motion.y; + } + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + raw.src.deviceType = INP_DEV_MOUSE; + raw.src.deviceID = ev->button.which; + +#ifndef USESDL2 + // SDL1 uses buttons 4 and 5 as wheel + unsigned b = ev->button.button; + if(b == 4 || b == 5) + { + raw.src.ctrlType = INP_CTRL_WHEEL; + raw.src.ctrlID = 0; + int dir = b == 4 ? 1 : -1; + raw.u.axis = dir; + break; + } +#endif + raw.src.ctrlType = INP_CTRL_BUTTON; + raw.src.ctrlID = ev->button.which; + raw.u.pressed = ev->button.state; + } + break; + +#ifdef USESDL2 + case SDL_MOUSEWHEEL: + { + raw.src.deviceType = INP_DEV_MOUSE; + raw.src.deviceID = ev->wheel.which; + raw.src.ctrlType = INP_CTRL_WHEEL; + raw.src.ctrlID = ev->wheel.which; + raw.u.axis = ev->button.state; + } + break; +#endif + + case SDL_KEYDOWN: + case SDL_KEYUP: + { +#ifdef USESDL2 + unsigned kidx = ev->key.keysym.scancode; +#else + unsigned kidx= event.key.keysym.sym; +#endif + raw.src.deviceType = INP_DEV_KEYBOARD; + raw.src.deviceID = 0; // SDL doesn't seem to support multiple keyboards + raw.src.ctrlType = INP_CTRL_BUTTON; + raw.src.ctrlID = kidx; + raw.u.pressed = ev->key.state; + } + break; + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + { + raw.src.deviceType = INP_DEV_KEYBOARD; + raw.src.deviceID = ev->jbutton.which; + raw.src.ctrlType = INP_CTRL_BUTTON; + raw.src.ctrlID = ev->jbutton.button; + raw.u.pressed = ev->jbutton.state; + } + + case SDL_JOYAXISMOTION: + { + raw.src.deviceType = INP_DEV_JOYSTICK; + raw.src.deviceID = ev->jaxis.which; + raw.src.ctrlType = INP_CTRL_AXIS; + raw.src.ctrlID = ev->jaxis.axis; + raw.u.axis = ev->jaxis.value / 32768.0f; + } + break; + + case SDL_JOYHATMOTION: + { + raw.src.deviceType = INP_DEV_JOYSTICK; + raw.src.deviceID = ev->jhat.which; + raw.src.ctrlType = INP_CTRL_HAT; + raw.src.ctrlID = ev->jhat.hat; + int x, y; + switch(ev->jhat.value) + { + case SDL_HAT_CENTERED: x = 0; y = 0; break; + case SDL_HAT_UP: x = 0; y = -1; break; + case SDL_HAT_DOWN: x = 0; y = +1; break; + case SDL_HAT_LEFT: x = -1; y = 0; break; + case SDL_HAT_RIGHT: x = +1; y = 0; break; + case SDL_HAT_LEFTUP: x = -1; y = -1; break; + case SDL_HAT_LEFTDOWN: x = -1; y = +1; break; + case SDL_HAT_RIGHTUP: x = +1; y = -1; break; + case SDL_HAT_RIGHTDOWN: x = +1; y = +1; break; + } + raw.u.ivec.x = (signed short)x; + raw.u.ivec.y = (signed short)y; + } + break; + + case SDL_CONTROLLERAXISMOTION: + { + raw.src.deviceType = INP_DEV_JOYSTICK; + raw.src.deviceID = ev->caxis.which; + raw.src.ctrlType = INP_CTRL_AXIS; + raw.src.ctrlID = ev->caxis.axis; + raw.u.axis = ev->caxis.value / float(0x7fff); + } + break; + + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + { + raw.src.deviceType = INP_DEV_JOYSTICK; + raw.src.deviceID = ev->cbutton.which; + raw.src.ctrlType = INP_CTRL_BUTTON; + raw.src.ctrlID = ev->cbutton.button; + raw.u.pressed = ev->cbutton.state; + } + break; + + /*case SDL_WINDOWEVENT: + switch(ev->window.event) + { + case SDL_WINDOWEVENT_RESIZED: + s_winSizeXInv = 1.0f / (float)ev->window.data1; + s_winSizeYInv = 1.0f / (float)ev->window.data2; + break; + }*/ + // fall through + default: + return; + } + + handleRawInput(&raw); +} diff --git a/BBGE/Joystick.cpp b/BBGE/Joystick.cpp index 373d28c..33f5b4a 100644 --- a/BBGE/Joystick.cpp +++ b/BBGE/Joystick.cpp @@ -39,21 +39,7 @@ Joystick::Joystick() debugLog("Failed to init haptic subsystem"); # endif sdl_joy = NULL; - buttonBitmask = 0; - deadZone1 = 0.3f; - deadZone2 = 0.3f; - clearRumbleTime= 0; - numJoyAxes = 0; - numHats = 0; - numButtons = 0; - clearAxes(); - - s1ax = 0; - s1ay = 1; - s2ax = 4; - s2ay = 3; - enabled = false; } @@ -80,7 +66,6 @@ const char *Joystick::getGUID() const bool Joystick::init(int stick) { stickIndex = stick; - numJoyAxes = 0; #ifdef BBGE_BUILD_SDL2 if (SDL_IsGameController(stick)) @@ -119,10 +104,7 @@ bool Joystick::init(int stick) guid = &guidbuf[0]; debugLog(std::string("Initialized Joystick [") + name + "], GUID [" + guid + "]"); if (sdl_controller) - { debugLog("Joystick is a Game Controller"); - numJoyAxes = SDL_CONTROLLER_AXIS_MAX; - } if (sdl_haptic) debugLog("Joystick has force feedback support"); instanceID = SDL_JoystickInstanceID(sdl_joy); @@ -133,14 +115,11 @@ bool Joystick::init(int stick) instanceID = SDL_JoystickIndex(sdl_joy); #endif - if(!numJoyAxes) - numJoyAxes = SDL_JoystickNumAxes(sdl_joy); - if(numJoyAxes > MAX_JOYSTICK_AXIS) - numJoyAxes = MAX_JOYSTICK_AXIS; - - numHats = SDL_JoystickNumHats(sdl_joy); - numButtons = SDL_JoystickNumButtons(sdl_joy); - + std::ostringstream os; + os << "Joystick has " << SDL_JoystickNumAxes(sdl_joy) << " axes, " + << SDL_JoystickNumButtons(sdl_joy) << " buttons, " + << SDL_JoystickNumHats(sdl_joy) << " hats."; + debugLog(os.str()); return true; } @@ -171,14 +150,6 @@ void Joystick::shutdown() SDL_JoystickClose(sdl_joy); sdl_joy = 0; } - - numJoyAxes = 0; - clearAxes(); -} - -void Joystick::clearAxes() -{ - memset(axisRaw, 0, sizeof(axisRaw)); } void Joystick::rumble(float leftMotor, float rightMotor, float time) @@ -204,7 +175,7 @@ void Joystick::rumble(float leftMotor, float rightMotor, float time) } } -void Joystick::calibrate(Vector &calvec, float deadZone) +void Joystick::Calibrate(Vector &calvec, float deadZone) { if (calvec.isLength2DIn(deadZone)) { @@ -244,20 +215,6 @@ void Joystick::update(float dt) shutdown(); return; } - if (sdl_controller) - { - for(unsigned i = 0; i < numJoyAxes; ++i) - { - Sint16 ax = SDL_GameControllerGetAxis(sdl_controller, (SDL_GameControllerAxis)i); - axisRaw[i] = float(ax)/32768.0f; - } - - position.x = axisRaw[SDL_CONTROLLER_AXIS_LEFTX]; - position.y = axisRaw[SDL_CONTROLLER_AXIS_LEFTY]; - rightStick.x = axisRaw[SDL_CONTROLLER_AXIS_RIGHTX]; - rightStick.y = axisRaw[SDL_CONTROLLER_AXIS_RIGHTY]; - } - else #else if (!SDL_JoystickOpened(stickIndex)) { @@ -266,38 +223,6 @@ void Joystick::update(float dt) return; } #endif - // Note: this connects with the else above when the SDL2 path is compiled! - { - for(unsigned i = 0; i < numJoyAxes; ++i) - { - Sint16 ax = SDL_JoystickGetAxis(sdl_joy, i); - axisRaw[i] = float(ax)/32768.0f; - } - position.x = s1ax >= 0 ? axisRaw[s1ax] : 0.0f; - position.y = s1ay >= 0 ? axisRaw[s1ay] : 0.0f; - rightStick.x = s2ax >= 0 ? axisRaw[s2ax] : 0.0f; - rightStick.y = s2ay >= 0 ? axisRaw[s2ay] : 0.0f; - } - - calibrate(position, deadZone1); - calibrate(rightStick, deadZone2); - - buttonBitmask = 0; - -#ifdef BBGE_BUILD_SDL2 - if (sdl_controller) - { - for (unsigned i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) - buttonBitmask |= !!SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)i) << i; - } - else -#endif - { - for (unsigned i = 0; i < numButtons; i++) - buttonBitmask |= !!SDL_JoystickGetButton(sdl_joy, i) << i; - - //for (unsigned i = 0; i < numHats; i++) - } } if (clearRumbleTime >= 0) @@ -310,60 +235,8 @@ void Joystick::update(float dt) } } -bool Joystick::anyButton() const -{ - return !!buttonBitmask;; -} - -unsigned Joystick::getNumAxes() const -{ -#ifdef BBGE_BUILD_SDL2 - return sdl_controller ? SDL_CONTROLLER_AXIS_MAX : numJoyAxes; -#else - return numJoyAxes; -#endif -} - -unsigned Joystick::getNumButtons() const -{ - return numButtons; -} - -unsigned Joystick::getNumHats() const -{ - return numHats; -} - -float Joystick::getAxisUncalibrated(unsigned id) const -{ - return id < MAX_JOYSTICK_AXIS ? axisRaw[id] : 0.0f; -} - -JoyHatDirection Joystick::getHat(unsigned id) const -{ - unsigned dir = SDL_JoystickGetHat(sdl_joy, id); - unsigned ret = JOY_HAT_DIR_CENTERED; - switch(dir) - { - case SDL_HAT_UP: ret = JOY_HAT_DIR_UP; break; - case SDL_HAT_DOWN: ret = JOY_HAT_DIR_DOWN; break; - case SDL_HAT_LEFT: ret = JOY_HAT_DIR_LEFT; break; - case SDL_HAT_RIGHT: ret = JOY_HAT_DIR_RIGHT; break; - - case SDL_HAT_LEFTUP: ret = JOY_HAT_DIR_UP | JOY_HAT_DIR_LEFT; break; - case SDL_HAT_RIGHTUP: ret = JOY_HAT_DIR_UP | JOY_HAT_DIR_RIGHT; break; - case SDL_HAT_LEFTDOWN: ret = JOY_HAT_DIR_DOWN | JOY_HAT_DIR_LEFT; break; - case SDL_HAT_RIGHTDOWN: ret = JOY_HAT_DIR_DOWN | JOY_HAT_DIR_RIGHT; break; - - default: ; - } - return (JoyHatDirection)ret; -} - const char *Joystick::getAxisName(unsigned axis) const { - if(axis >= numJoyAxes) - return NULL; #ifdef BBGE_BUILD_SDL2 if(sdl_controller) return SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)axis); diff --git a/BBGE/Joystick.h b/BBGE/Joystick.h index 3e4bddb..3fa8a72 100644 --- a/BBGE/Joystick.h +++ b/BBGE/Joystick.h @@ -11,20 +11,6 @@ #include "Vector.h" -#define MAX_JOYSTICK_BTN 32 -#define MAX_JOYSTICK_AXIS 32 -#define MAX_JOYSTICK_HATS 8 - -enum JoyHatDirection // bitmask -{ - JOY_HAT_DIR_CENTERED = 0, - JOY_HAT_DIR_UP = 1, - JOY_HAT_DIR_DOWN = 2, - JOY_HAT_DIR_LEFT = 4, - JOY_HAT_DIR_RIGHT = 8 -}; - - const static float JOY_AXIS_THRESHOLD = 0.6f; class Joystick @@ -40,19 +26,8 @@ public: //Ranges from 0 to 1 (full speed). void rumble(float leftMotor, float rightMotor, float time); void update(float dt); - Vector position; - float deadZone1, deadZone2; - float clearRumbleTime; - - void calibrate(Vector &vec, float dead); - bool anyButton() const; - bool getButton(size_t id) const { return !!(buttonBitmask & (1u << id)); } - float getAxisUncalibrated(unsigned id) const; - JoyHatDirection getHat(unsigned id) const; - unsigned getNumAxes() const; - unsigned getNumButtons() const; - unsigned getNumHats() const; + static void Calibrate(Vector &vec, float dead); int getIndex() const { return stickIndex; } int getInstanceID() const { return instanceID; } inline bool isEnabled() const { return enabled; } @@ -63,19 +38,12 @@ public: const char *getName() const; const char *getGUID() const; - Vector rightStick; - - int s1ax, s1ay, s2ax, s2ay; - private: - void clearAxes(); + float clearRumbleTime; bool enabled; int stickIndex; int instanceID; - unsigned buttonBitmask; - unsigned numJoyAxes, numHats, numButtons; SDL_Joystick *sdl_joy; - float axisRaw[MAX_JOYSTICK_AXIS]; std::string name; std::string guid; diff --git a/BBGE/StateManager.h b/BBGE/StateManager.h index 485578b..c0a3f7b 100644 --- a/BBGE/StateManager.h +++ b/BBGE/StateManager.h @@ -65,7 +65,7 @@ public: void removeRenderObject(RenderObject *renderObject); std::string name; - virtual void action(int actionID, int state, int source, InputDevice device) {} + virtual void action(int actionID, int state, int playerID, InputDeviceType device) {} protected: void registerState(StateObject *sb, const std::string &name); diff --git a/BBGE/StringBank.h b/BBGE/StringBank.h index 4c89c98..5647336 100644 --- a/BBGE/StringBank.h +++ b/BBGE/StringBank.h @@ -4,17 +4,6 @@ #include #include -// Some strings used in BBGE -enum StringBankIndexBBGE -{ - SB_BBGE_NO_KEY = 2153, - SB_BBGE_INVALID_KEY_ID = 2154, - SB_BBGE_INVALID_JOY_BTN = 2155, - SB_BBGE_INVALID_MOUSE_BTN = 2156, - SB_BBGE_INVALID_JOY_AXIS_POS = 2157, - SB_BBGE_INVALID_JOY_AXIS_NEG = 2158, -}; - class StringBank { public: diff --git a/win/vc90/Aquaria.vcproj b/win/vc90/Aquaria.vcproj index 2afa0ec..3ff4361 100644 --- a/win/vc90/Aquaria.vcproj +++ b/win/vc90/Aquaria.vcproj @@ -423,10 +423,6 @@ RelativePath="..\..\Aquaria\Damage.h" > - - @@ -475,6 +471,14 @@ RelativePath="..\..\Aquaria\GameEnums.h" > + + + + diff --git a/win/vc90/BBGE.vcproj b/win/vc90/BBGE.vcproj index 13f67cc..39d6ad7 100644 --- a/win/vc90/BBGE.vcproj +++ b/win/vc90/BBGE.vcproj @@ -333,14 +333,6 @@ RelativePath="..\..\BBGE\ActionSet.h" > - - - - @@ -461,6 +453,34 @@ RelativePath="..\..\BBGE\Gradient.h" > + + + + + + + + + + + + + +