From bf94d541cdf1d09121c5b9fc462588dea8a78b79 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sat, 16 Jul 2016 22:08:39 +0200 Subject: [PATCH] More WIP towards multiple input sets --- Aquaria/AquariaComboBox.cpp | 22 +- Aquaria/AquariaMenuItem.cpp | 403 +++++++++++++++++++++--------------- Aquaria/AquariaMenuItem.h | 21 +- Aquaria/Avatar.cpp | 11 +- Aquaria/Avatar.h | 4 + Aquaria/DSQ.cpp | 23 +- Aquaria/DSQ.h | 2 +- Aquaria/Entity.cpp | 4 +- Aquaria/Game.cpp | 2 +- Aquaria/InGameMenu.cpp | 129 ++++++++++-- Aquaria/InGameMenu.h | 8 +- Aquaria/ModSelector.cpp | 2 +- Aquaria/ScriptInterface.cpp | 3 +- Aquaria/UserSettings.cpp | 9 + BBGE/ActionSet.cpp | 13 +- BBGE/ActionSet.h | 3 +- BBGE/Core.h | 2 +- BBGE/DebugFont.cpp | 6 +- BBGE/DebugFont.h | 3 +- BBGE/Joystick.cpp | 10 +- BBGE/Joystick.h | 1 + 21 files changed, 449 insertions(+), 232 deletions(-) diff --git a/Aquaria/AquariaComboBox.cpp b/Aquaria/AquariaComboBox.cpp index 864f552..40961d5 100644 --- a/Aquaria/AquariaComboBox.cpp +++ b/Aquaria/AquariaComboBox.cpp @@ -67,11 +67,6 @@ AquariaComboBox::AquariaComboBox(Vector textscale) : RenderObject() this->textscale = textscale; } -void AquariaComboBox::destroy() -{ - RenderObject::destroy(); -} - void AquariaComboBox::enqueueSelectItem(int index) { enqueuedSelectItem = index; @@ -131,6 +126,8 @@ void AquariaComboBox::onUpdate(float dt) scrollDelay -= dt; if (scrollDelay < 0) scrollDelay = 0; + bool clickedInside = false; + if (isopen) { if (!core->mouse.buttons.left) @@ -141,6 +138,7 @@ void AquariaComboBox::onUpdate(float dt) if (core->mouse.buttons.left && scrollBtnDown->isCoordinateInsideWorldRect(core->mouse.position, 20, 32)) { + clickedInside = true; if (scrollDelay == 0) { doScroll(1); @@ -164,6 +162,7 @@ void AquariaComboBox::onUpdate(float dt) if (core->mouse.buttons.left && scrollBtnUp->isCoordinateInsideWorldRect(core->mouse.position, 20, 32)) { + clickedInside = true; if (scrollDelay == 0) { doScroll(0); @@ -190,6 +189,7 @@ void AquariaComboBox::onUpdate(float dt) if (bar->isCoordinateInsideWorld(core->mouse.position)) { + clickedInside = true; if (!mb && core->mouse.buttons.left) { mb = true; @@ -221,6 +221,18 @@ void AquariaComboBox::onUpdate(float dt) { doScroll(1); } + + if(!clickedInside && core->mouse.buttons.left) + { + for(size_t i = 0; i < shownItems.size(); ++i) + if(shownItems[i]->mb) + { + clickedInside = true; + break; + } + if(!clickedInside) + close(); + } } } diff --git a/Aquaria/AquariaMenuItem.cpp b/Aquaria/AquariaMenuItem.cpp index 2b4f2ec..c7654c0 100644 --- a/Aquaria/AquariaMenuItem.cpp +++ b/Aquaria/AquariaMenuItem.cpp @@ -27,12 +27,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "tinyxml2.h" using namespace tinyxml2; +const float moveDelay = 0.2; + float AquariaGuiElement::guiMoveTimer = 0; AquariaGuiElement::GuiElements AquariaGuiElement::guiElements; bool AquariaGuiElement::canDirMoveGlobal = true; int AquariaGuiElement::currentGuiInputLevel = 0; - AquariaGuiElement *AquariaGuiElement::currentFocus = 0; AquariaGuiElement::AquariaGuiElement() @@ -41,7 +42,6 @@ AquariaGuiElement::AquariaGuiElement() { dirMove[i] = 0; } - hasFocus = false; guiMoveTimer = 0; @@ -79,10 +79,13 @@ void AquariaGuiElement::setCanDirMove(bool on) canDirMove = on; } +bool AquariaGuiElement::hasFocus() const +{ + return this == currentFocus; +} + void AquariaGuiElement::setFocus(bool v) { - hasFocus = v; - if (v) { currentFocus = this; @@ -105,151 +108,23 @@ void AquariaGuiElement::setFocus(bool v) void AquariaGuiElement::updateMovement(float dt) { - - if (hasFocus && isGuiVisible() && canDirMove && canDirMoveGlobal && hasInput()) + if (hasFocus() && isGuiVisible() && canDirMove && canDirMoveGlobal && hasInput()) { - - - - if (guiMoveTimer > 0) - { - guiMoveTimer -= dt; - if (guiMoveTimer < 0) guiMoveTimer = 0; - } - if (guiMoveTimer==0) { - Direction dir = DIR_NONE; - 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)) - { - 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(); - 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; - } - } + Direction dir = GetDirection(); if (dir == DIR_NONE) return; - const float moveDelay = 0.2; - AquariaGuiElement *gui = 0; if (dir > DIR_NONE && dir < DIR_MAX) { gui = dirMove[dir]; + if (!gui) + gui = FindClosestTo(this, getGuiPosition(), dir); if (gui) { gui->setFocus(true); - - - - guiMoveTimer = moveDelay; - } - } - - if (!gui) - { - debugLog("updating closest"); - int smallDist = -1, dist = 0; - - AquariaGuiElement *gui = 0, *closest = 0; - int ch = 64; - for (GuiElements::iterator i = guiElements.begin(); i != guiElements.end(); i++) - { - gui = (*i); - if (gui != this && gui->isGuiVisible() && gui->canDirMove) - { - int go = 0; - Vector p1 = getGuiPosition(); - Vector p2 = gui->getGuiPosition(); - - if (dir == DIR_DOWN) - { - if (fabsf(p1.x - p2.x) < ch) - { - if (p2.y > p1.y) go = 1; - p1.x = p2.x = 0; - } - } - else if (dir == DIR_UP) - { - if (fabsf(p1.x - p2.x) < ch) - { - if (p2.y < p1.y) go = 1; - p1.x = p2.x = 0; - } - } - else if (dir == DIR_RIGHT) - { - if (fabsf(p1.y - p2.y) < ch) - { - if (p2.x > p1.x) go = 1; - p1.y = p2.y = 0; - } - } - else if (dir == DIR_LEFT) - { - if (fabsf(p1.y - p2.y) < ch) - { - if (p2.x < p1.x) go = 1; - p1.y = p2.y = 0; - } - } - else - { - continue; - } - - if (go) - { - dist = (p1 - p2).getSquaredLength2D(); - - if (smallDist == -1 || dist < smallDist) - { - closest = gui; - smallDist = dist; - } - } - else - { - continue; - } - } - } - - if (closest) - { - closest->setFocus(true); - guiMoveTimer = moveDelay; } } @@ -257,6 +132,151 @@ void AquariaGuiElement::updateMovement(float dt) } } +AquariaGuiElement *AquariaGuiElement::FocusClosestToMouse(Direction dir) +{ + if (dir > DIR_NONE && dir < DIR_MAX) + { + AquariaGuiElement *gui = FindClosestTo(NULL, core->mouse.position, dir); + if (gui) + { + gui->setFocus(true); + guiMoveTimer = moveDelay; + return gui; + } + } + return NULL; +} + +void AquariaGuiElement::UpdateGlobalFocus(float dt) +{ + if (guiMoveTimer > 0) + { + guiMoveTimer -= dt; + if (guiMoveTimer < 0) guiMoveTimer = 0; + } + + if(!currentFocus && guiMoveTimer == 0) + FocusClosestToMouse(GetDirection()); +} + +Direction AquariaGuiElement::GetDirection() +{ + Direction dir = DIR_NONE; + 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)) + { + 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(); + 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; + } + } + return dir; +} + +AquariaGuiElement *AquariaGuiElement::FindClosestTo(AquariaGuiElement *cur, Vector pos, Direction dir) +{ + + debugLog("updating closest"); + int smallDist = -1, dist = 0; + + AquariaGuiElement *gui = 0, *closest = 0; + int ch = 64; + for (GuiElements::iterator i = guiElements.begin(); i != guiElements.end(); i++) + { + gui = (*i); + if (gui != cur && gui->isGuiVisible() && gui->canDirMove) + { + int go = 0; + Vector p1 = pos; + Vector p2 = gui->getGuiPosition(); + + if (dir == DIR_DOWN) + { + if (fabsf(p1.x - p2.x) < ch) + { + if (p2.y > p1.y) go = 1; + p1.x = p2.x = 0; + } + } + else if (dir == DIR_UP) + { + if (fabsf(p1.x - p2.x) < ch) + { + if (p2.y < p1.y) go = 1; + p1.x = p2.x = 0; + } + } + else if (dir == DIR_RIGHT) + { + if (fabsf(p1.y - p2.y) < ch) + { + if (p2.x > p1.x) go = 1; + p1.y = p2.y = 0; + } + } + else if (dir == DIR_LEFT) + { + if (fabsf(p1.y - p2.y) < ch) + { + if (p2.x < p1.x) go = 1; + p1.y = p2.y = 0; + } + } + else + { + continue; + } + + if (go) + { + dist = (p1 - p2).getSquaredLength2D(); + + if (smallDist == -1 || dist < smallDist) + { + closest = gui; + smallDist = dist; + } + } + else + { + continue; + } + } + } + + return closest; +} + AquariaGuiElement *AquariaGuiElement::getClosestGuiElement(const Vector& pos) { AquariaGuiElement *gui = 0, *closest = 0; @@ -462,7 +482,6 @@ AquariaKeyConfig *AquariaKeyConfig::waitingForInput = 0; AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputSetType inputSetType, int inputIdx) : AquariaGuiElement(), RenderObject(), actionInputName(actionInputName), inputSetType(inputSetType), inputIdx(inputIdx) { - bg = new Quad(); if (inputSetType == INPUTSET_OTHER) bg->setWidthHeight(40, 20); @@ -579,18 +598,16 @@ void AquariaKeyConfig::onUpdate(float dt) } } - int *value = 0; - if (inputSetType == INPUTSET_OTHER) { if (actionInputName == "s1ax") - value = &as.joycfg.s1ax; + k = &as.joycfg.s1ax; else if (actionInputName == "s1ay") - value = &as.joycfg.s1ay; + k = &as.joycfg.s1ay; else if (actionInputName == "s2ax") - value = &as.joycfg.s2ax; + k = &as.joycfg.s2ax; else if (actionInputName == "s2ay") - value = &as.joycfg.s2ay; + k = &as.joycfg.s2ay; } if (waitingForInput == this) @@ -606,15 +623,22 @@ void AquariaKeyConfig::onUpdate(float dt) } else { - if (k) + if (inputSetType != INPUTSET_OTHER) { keyConfigFont->setText(getInputCodeToUserString(*k, as.joystickID)); } - else if (value) + else { - std::ostringstream os; - os << (*value); - keyConfigFont->setText(os.str()); + if(*k >= 0) + { + std::ostringstream os; + os << (*k); + keyConfigFont->setText(os.str()); + } + else + { + keyConfigFont->setText(getInputCodeToUserString(0, as.joystickID)); + } } } @@ -624,29 +648,73 @@ void AquariaKeyConfig::onUpdate(float dt) { case INPUTSET_OTHER: { - if (value) + 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_ESCAPE) + if(i == KEY_BACKSPACE || i == KEY_DELETE) + clear = true; + else if (i == KEY_ESCAPE) + abort = true; + else { - if (i >= KEY_0 && i <= KEY_9) + switch(i) { - *value = i-KEY_0; + #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.1); + dsq->run(0.1f); } + } + } - toggleEnterKey(0); - waitingForInput = 0; - AquariaGuiElement::canDirMoveGlobal = true; - break; + 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); + break; + } + } + } + + if(ac >= 0 || abort || clear) + { + toggleEnterKey(0); + waitingForInput = 0; + AquariaGuiElement::canDirMoveGlobal = true; + if(!abort) + { + if(clear || ac == *k) + *k = -1; + else + *k = ac; } } } @@ -684,14 +752,19 @@ void AquariaKeyConfig::onUpdate(float dt) case INPUTSET_MOUSE: { bool clear = false; + bool abort = false; 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); clear = true; } else if(core->getKeyState(KEY_ESCAPE)) { - // do nothing + while(core->getKeyState(KEY_ESCAPE)) + dsq->run(0.1f); + abort = true; } else if(dsq->mouse.rawButtonMask) { @@ -717,16 +790,19 @@ void AquariaKeyConfig::onUpdate(float dt) } } - if(ac || clear) + if(ac || clear || abort) { toggleEnterKey(0); waitingForInput = 0; AquariaGuiElement::canDirMoveGlobal = true; - if(clear || *k == ac) // clear key if pressed again - *k = 0; - else - *k = ac; + if(!abort) + { + if(clear || *k == ac) // clear key if pressed again + *k = 0; + else + *k = ac; + } } } break; @@ -846,7 +922,6 @@ void AquariaKeyConfig::setAcceptEsc(bool a) AquariaMenuItem::AquariaMenuItem() : Quad(), ActionMapper(), AquariaGuiElement() { quad = glow = 0; - choice = -1; int sz = 20; shareAlpha = 0; diff --git a/Aquaria/AquariaMenuItem.h b/Aquaria/AquariaMenuItem.h index 863578f..dfe436c 100644 --- a/Aquaria/AquariaMenuItem.h +++ b/Aquaria/AquariaMenuItem.h @@ -52,8 +52,14 @@ protected: static GuiElements guiElements; static float guiMoveTimer; void updateMovement(float dt); - bool hasFocus, canDirMove; + bool hasFocus() const; + bool canDirMove; AquariaGuiElement *dirMove[DIR_MAX]; + static AquariaGuiElement *FindClosestTo(AquariaGuiElement *cur, Vector pos, Direction dir); + static Direction GetDirection(); + static AquariaGuiElement *FocusClosestToMouse(Direction dir); +public: + static void UpdateGlobalFocus(float dt); }; class AquariaGuiQuad : public Quad, public AquariaGuiElement @@ -77,7 +83,6 @@ public: void setLabel(const std::string &label); EventPtr event; BitmapText *font, *glowFont; - int choice; Quad *glow, *quad; bool useQuad(const std::string &tex); void useGlow(const std::string &tex, int w, int h); @@ -192,6 +197,7 @@ class AquariaComboBox; class AquariaComboBoxItem : public Quad { + friend class AquariaComboBox; public: AquariaComboBoxItem(const std::string &str, int idx, AquariaComboBox *combo, Vector textscale); @@ -209,12 +215,9 @@ class AquariaComboBox : public RenderObject { public: AquariaComboBox(Vector textscale = Vector(1, 1)); - - void destroy(); - int addItem(const std::string &n); - void open(float t=0.1); - void close(float t=0.1); + void open(float t=0.1f); + void close(float t=0.1f); void setSelectedItem(int index); bool setSelectedItem(const std::string &item); int getSelectedItem(); @@ -222,6 +225,7 @@ public: void setScroll(int sc); std::string getSelectedItemString(); void doScroll(int dir); + bool isOpen() const { return isopen; } protected: void onUpdate(float dt); @@ -232,9 +236,8 @@ protected: int enqueuedSelectItem; std::vector items; - std::vector itemTexts; - Quad *bar, *window, *scrollBtnUp, *scrollBtnDown, *scrollBar; + Quad *bar, *scrollBtnUp, *scrollBtnDown; BitmapText *selectedItemLabel; int selectedItem; diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index ea201ec..7f9d798 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -1093,7 +1093,7 @@ void Avatar::onDamage(DamageData &d) if (healthWillBe<=0) t = 2; - dsq->rumble(d.damage, d.damage, 0.4); + dsq->rumble(d.damage, d.damage, 0.4, _lastActionSourceID); if (d.damage > 0) { //dsq->shakeCamera(5, t); @@ -3887,6 +3887,7 @@ Avatar::Avatar() : Entity(), ActionMapper() blockBackFlip = false; elementEffectMult = 1; + _lastActionSourceID = 9999; } void Avatar::revert() @@ -4059,7 +4060,7 @@ void Avatar::startBurst() { if (!bursting && burst == 1) { - dsq->rumble(0.2, 0.2, 0.2); + dsq->rumble(0.2, 0.2, 0.2, _lastActionSourceID); if (dsq->continuity.form != FORM_BEAST) wakeEmitter.start(); dsq->game->playBurstSound(pushingOffWallEffect>0); @@ -4132,7 +4133,7 @@ void Avatar::startWallBurst(bool useCursor) { lastBurstType = BURST_WALL; - dsq->rumble(0.22, 0.22, 0.2); + dsq->rumble(0.22, 0.22, 0.2, _lastActionSourceID); bittenEntities.clear(); if (useCursor) { @@ -4242,6 +4243,8 @@ void Avatar::action(int id, int state, int source) if(dsq->game->isIgnoreAction((AquariaActions)id)) return; + _lastActionSourceID = source; + if (id == ACTION_PRIMARY) { if (state) lmbd(); else lmbu(); } if (id == ACTION_SECONDARY) { if (state) rmbd(); else rmbu(); } @@ -4510,7 +4513,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.08,0.05,22,0.2f, 1.2)); - dsq->rumble(0.7, 0.7, 0.2); + dsq->rumble(0.7, 0.7, 0.2, _lastActionSourceID); plungeEmitter.start(); core->sound->playSfx("GoUnder"); diff --git a/Aquaria/Avatar.h b/Aquaria/Avatar.h index afb396c..59a4f70 100644 --- a/Aquaria/Avatar.h +++ b/Aquaria/Avatar.h @@ -331,6 +331,8 @@ public: bool blockBackFlip; + int getLastActionSourceID() { return _lastActionSourceID; } + protected: void setSongIconPositions(); @@ -465,6 +467,8 @@ protected: int _collisionAvoidRange; float _collisionAvoidMod; + int _lastActionSourceID; + }; #endif diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index d59132b..33ad818 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -269,11 +269,24 @@ void DSQ::forceInputGrabOff() SDL_ShowCursor(SDL_DISABLE); } -void DSQ::rumble(float leftMotor, float rightMotor, float time) +void DSQ::rumble(float leftMotor, float rightMotor, float time, int source) { - //if (this->inputMode == INPUT_JOYSTICK) - // core->joystick.rumble(leftMotor, rightMotor, time); - //assert(false); // FIXME + if (this->inputMode == 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()) + { + const ActionSet& as = user.control.actionSets[source]; + if(Joystick *j = core->getJoystick(as.joystickID)) + j->rumble(leftMotor, rightMotor, time); + } + } } void DSQ::newGame() @@ -4104,6 +4117,8 @@ void DSQ::onUpdate(float dt) Network::update(); Shot::clearShotGarbage(); + + AquariaGuiElement::UpdateGlobalFocus(dt); } void DSQ::lockMouse() diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 7f74756..3445329 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -359,7 +359,7 @@ public: InputMode inputMode; void setInputMode(InputMode mode); - void rumble(float leftMotor, float rightMotor, float time); + void rumble(float leftMotor, float rightMotor, float time, int source); void vision(std::string folder, int num, bool ignoreMusic = false); void watch(float t, int canQuit = 0); diff --git a/Aquaria/Entity.cpp b/Aquaria/Entity.cpp index 6224b15..b7e40b2 100644 --- a/Aquaria/Entity.cpp +++ b/Aquaria/Entity.cpp @@ -1311,9 +1311,9 @@ bool Entity::updateCurrents(float dt) if (getEntityType() == ET_AVATAR) { if (v < 0) - dsq->rumble((-v)*scale, (1.0f+v)*scale, 0.2); + dsq->rumble((-v)*scale, (1.0f+v)*scale, 0.2, dsq->game->avatar->getLastActionSourceID()); else - dsq->rumble((1.0f-v)*scale, (v)*scale, 0.1); + dsq->rumble((1.0f-v)*scale, (v)*scale, 0.1, dsq->game->avatar->getLastActionSourceID()); } } } diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index b213767..86a9e20 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -5032,7 +5032,7 @@ void Game::removeState() dsq->overlay->alpha.interpolateTo(1, fadeTime); dsq->run(fadeTime); - dsq->rumble(0,0,0); + dsq->rumble(0,0,0,-1); dsq->sound->clearFadingSfx(); diff --git a/Aquaria/InGameMenu.cpp b/Aquaria/InGameMenu.cpp index 604b9c6..3df22a3 100644 --- a/Aquaria/InGameMenu.cpp +++ b/Aquaria/InGameMenu.cpp @@ -9,6 +9,7 @@ #include "Avatar.h" #include "GridRender.h" #include "DebugFont.h" +#include "ActionSet.h" static InGameMenu *themenu = 0; @@ -911,6 +912,7 @@ InGameMenu::InGameMenu() ripplesCheck = 0; menu_blackout = 0; menuSelectDelay = 0; + selectedActionSetIdx = 0; } InGameMenu::~InGameMenu() @@ -1525,25 +1527,32 @@ void InGameMenu::addKeyConfigLine(RenderObject *group, const std::string &label, AquariaKeyConfig *m = new AquariaKeyConfig(actionInputName, INPUTSET_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); k1->position = Vector(x,y); group->addChild(k1, PM_POINTER); + keyConfigs.push_back(k1); k1->setAcceptEsc(acceptEsc); x += KEYCONFIG_COL_DISTANCE; AquariaKeyConfig *k2 = new AquariaKeyConfig(actionInputName, INPUTSET_KEY, 1); k2->position = Vector(x,y); group->addChild(k2, PM_POINTER); + keyConfigs.push_back(k2); k2->setAcceptEsc(acceptEsc); x += KEYCONFIG_COL_DISTANCE; AquariaKeyConfig *j1 = new AquariaKeyConfig(actionInputName, INPUTSET_JOY, 0); j1->position = Vector(x,y); group->addChild(j1, PM_POINTER); + keyConfigs.push_back(j1); x += KEYCONFIG_COL_DISTANCE; + m->setDirMove(DIR_RIGHT, k1); + k1->setDirMove(DIR_LEFT, m); + k1->setDirMove(DIR_RIGHT, k2); k2->setDirMove(DIR_RIGHT, j1); @@ -1560,7 +1569,7 @@ AquariaKeyConfig *InGameMenu::addAxesConfigLine(RenderObject *group, const std:: AquariaKeyConfig *i1 = new AquariaKeyConfig(actionInputName, INPUTSET_OTHER, 0); i1->position = Vector(80+offx,y); - //i1->setLock(l1); + keyConfigs.push_back(i1); group->addChild(i1, PM_POINTER); i1->setDirMove(DIR_RIGHT, 0); @@ -1966,9 +1975,36 @@ void InGameMenu::create() keyConfigBg->setHidden(true); game->addRenderObject(keyConfigBg, LR_OVERLAY); - int offy = 20 - keyConfigBg->position.y; - const int offx = 140 - keyConfigBg->position.x; - const int yi = 20; + float offy = 30 - keyConfigBg->position.y; + const float offx = 140 - keyConfigBg->position.x; + const float yi = 20; + + { + float x = offx; + TTFText *header_actionset = new TTFText(&dsq->fontArialSmall); + header_actionset->setText(SB(2133)); + header_actionset->position = Vector(x, offy); + keyConfigBg->addChild(header_actionset, PM_POINTER); + x += header_actionset->getActualWidth() + 20 + 100; + + actionSetBox = new AquariaComboBox; + actionSetBox->position = Vector(x, offy); + keyConfigBg->addChild(actionSetBox, PM_POINTER); + updateActionSetComboBox(); + x += 200; + + TTFText *header_enabled = new TTFText(&dsq->fontArialSmall); + header_enabled->setText(SB(2134)); + header_enabled->position = Vector(x, offy+5); + keyConfigBg->addChild(header_enabled, PM_POINTER); + x += header_enabled->getActualWidth() + 20; + + actionSetCheck = new AquariaCheckBox; + actionSetCheck->position = Vector(x, offy); + keyConfigBg->addChild(actionSetCheck, PM_POINTER); + } + offy += 40; + TTFText *header_tabs = new TTFText(&dsq->fontArialSmall); header_tabs->setText(SB(2130)); @@ -1976,6 +2012,8 @@ void InGameMenu::create() keyConfigBg->addChild(header_tabs, PM_POINTER); keyCategoryButtons.clear(); + keyConfigs.clear(); + for(int i = 0; i < NUM_KEY_CONFIG_PAGES; ++i) { const float w = 100; @@ -2091,6 +2129,8 @@ void InGameMenu::create() } } + actionSetBox->moveToFront(); + #undef SB @@ -2681,7 +2721,7 @@ void InGameMenu::onUseTreasure(int flag) } -bool ingType(const std::vector &list, IngredientType type, int amount=1) +static bool ingType(const std::vector &list, IngredientType type, int amount=1) { int c = 0; for (int i = 0; i < list.size(); i++) @@ -2699,7 +2739,7 @@ bool ingType(const std::vector &list, IngredientType type, int return false; } -bool ingName(const std::vector &list, const std::string &name, int amount=1) +static bool ingName(const std::vector &list, const std::string &name, int amount=1) { int c = 0; for (int i = 0; i < list.size(); i++) @@ -3692,22 +3732,6 @@ void InGameMenu::toggleKeyConfigMenu(bool f) keyConfigBg->setHidden(false); keyConfigBg->alpha = 1; - for(unsigned i = 0; i < NUM_KEY_CONFIG_PAGES; ++i) - { - // FG: FIXME: changed layout: m, k1, k2, j - RenderObject::Children::reverse_iterator it = group_keyConfig[i]->children.rbegin(); - AquariaKeyConfig *upright0 = (AquariaKeyConfig*)(*it++); - AquariaKeyConfig *upright = (AquariaKeyConfig*)(*it++); - AquariaKeyConfig *upleft = (AquariaKeyConfig*)(*it++); - - //opt_cancel->setDirMove(DIR_UP, upright); - upright->setDirMove(DIR_DOWN, opt_cancel); - upright0->setDirMove(DIR_DOWN, opt_cancel); - - //opt_save->setDirMove(DIR_UP, upleft); - upleft->setDirMove(DIR_DOWN, opt_save); - } - switchToKeyConfigPage(0); dsq->user_bcontrol = dsq->user; @@ -3754,6 +3778,19 @@ void InGameMenu::switchToKeyConfigPage(int page) keyCategoryButtons[page]->inactiveAlpha = 0.7f; group_keyConfig[page]->setHidden(false); group_keyConfig[page]->alpha = 1; + + // FG: FIXME: changed layout: m, k1, k2, j + /*RenderObject::Children::reverse_iterator it = group_keyConfig[page]->children.rbegin(); + AquariaKeyConfig *upright0 = (AquariaKeyConfig*)(*it++); + AquariaKeyConfig *upright = (AquariaKeyConfig*)(*it++); + AquariaKeyConfig *upleft = (AquariaKeyConfig*)(*it++); + + opt_cancel->setDirMove(DIR_UP, upright); + upright->setDirMove(DIR_DOWN, opt_cancel); + upright0->setDirMove(DIR_DOWN, opt_cancel); + + opt_save->setDirMove(DIR_UP, upleft); + upleft->setDirMove(DIR_DOWN, opt_save);*/ } void InGameMenu::toggleOptionsMenu(bool f, bool skipBackup, bool isKeyConfig) @@ -3788,6 +3825,8 @@ void InGameMenu::toggleOptionsMenu(bool f, bool skipBackup, bool isKeyConfig) if (ripplesCheck) ripplesCheck->setValue(core->afterEffectManager!=0); + switchToActionSet(selectedActionSetIdx); + if (resBox) { std::ostringstream os; @@ -3839,6 +3878,8 @@ void InGameMenu::toggleOptionsMenu(bool f, bool skipBackup, bool isKeyConfig) } else if (!f && optionsMenu) { + AquariaMenuItem::currentGuiInputLevel = 0; + lips->alpha = 0; keyConfigButton->alpha = 0; @@ -3892,6 +3933,26 @@ void InGameMenu::toggleOptionsMenu(bool f, bool skipBackup, bool isKeyConfig) } } +void InGameMenu::updateKeyConfigMenu(float dt) +{ + if(!keyConfigMenu) + return; + + bool isopen = actionSetBox->isOpen(); + AquariaMenuItem::currentGuiInputLevel = isopen ? 50 : 0; + float a = isopen ? 0.0f : 1.0f; + // HACK: debug buttons ignore input at < 1 alpha + for(size_t i = 0; i < keyCategoryButtons.size(); ++i) + keyCategoryButtons[i]->alpha = a; + + dsq->user.control.actionSets[selectedActionSetIdx].enabled + = actionSetCheck->getValue(); + + const int curAS = actionSetBox->getSelectedItem(); + if(selectedActionSetIdx != curAS) + switchToActionSet(curAS); +} + void InGameMenu::updateOptionsMenu(float dt) { if (!optionsMenu) @@ -4080,6 +4141,8 @@ void InGameMenu::update(float dt) } } } + + updateKeyConfigMenu(dt); } } @@ -4092,3 +4155,25 @@ void InGameMenu::onDebugSave() dsq->doSaveSlotMenu(SSM_SAVE); dsq->game->togglePause(false); } + +void InGameMenu::switchToActionSet(int idx) +{ + selectedActionSetIdx = idx; + actionSetBox->setSelectedItem(idx); + actionSetCheck->setValue(dsq->user.control.actionSets[idx].enabled); + for(size_t i = 0; i < keyConfigs.size(); ++i) + keyConfigs[i]->setActionSetIndex(idx); +} + +void InGameMenu::updateActionSetComboBox() +{ + for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + { + std::ostringstream os; + os << '#' << (i+1); + const std::string& name = dsq->user.control.actionSets[i].name; + if(name.length()) + os << ": " << name; + actionSetBox->addItem(os.str()); + } +} diff --git a/Aquaria/InGameMenu.h b/Aquaria/InGameMenu.h index b8c35c5..3b12c20 100644 --- a/Aquaria/InGameMenu.h +++ b/Aquaria/InGameMenu.h @@ -77,7 +77,6 @@ public: void create(); void update(float dt); - void updateOptions(float dt); void hide(bool effects=true, bool cancel=false); void show(bool force=false, bool optionsOnly=false, MenuPage menuPage = MENUPAGE_NONE); bool isInGameMenu() const { return inGameMenu; } @@ -97,6 +96,7 @@ public: private: void updateOptionsMenu(float dt); + void updateKeyConfigMenu(float dt); void sortFood(); void updatePreviewRecipe(); @@ -207,9 +207,15 @@ private: RenderObject *group_keyConfig[NUM_KEY_CONFIG_PAGES]; RoundedRect *keyConfigBg; std::vector keyCategoryButtons; + std::vector keyConfigs; RenderObject *createBasicKeyConfig(); void switchToKeyConfigPage(int page); Quad *options; + AquariaComboBox *actionSetBox; + AquariaCheckBox *actionSetCheck; + int selectedActionSetIdx; + void updateActionSetComboBox(); + void switchToActionSet(int idx); void onExitCheckNo(); void onExitCheckYes(); diff --git a/Aquaria/ModSelector.cpp b/Aquaria/ModSelector.cpp index 272ba52..8d04ee9 100644 --- a/Aquaria/ModSelector.cpp +++ b/Aquaria/ModSelector.cpp @@ -426,7 +426,7 @@ void BasicIcon::onUpdate(float dt) AquariaMenuItem::onUpdate(dt); // Autoscroll if selecting icon outside of screen - if(hasFocus && dsq->modSelectorScr) + if(hasFocus() && dsq->modSelectorScr) { Vector pos = getRealPosition(); if(pos.y < 20 || pos.y > 580) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index efee4f3..312605b 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -2066,7 +2066,8 @@ luaFunc(shakeCamera) luaFunc(rumble) { - dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3)); + int source = lua_tonumber(L, 4) - 1; + dsq->rumble(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), source); luaReturnNil(); } diff --git a/Aquaria/UserSettings.cpp b/Aquaria/UserSettings.cpp index 8b995bf..353dfeb 100644 --- a/Aquaria/UserSettings.cpp +++ b/Aquaria/UserSettings.cpp @@ -182,6 +182,12 @@ void UserSettings::save() } xml_control->InsertEndChild(xml_flip); + XMLElement *xml_minas = doc.NewElement("MinActionSets"); + { + xml_minas->SetAttribute("num", control.flipInputButtons); + } + xml_control->InsertEndChild(xml_minas); + for(size_t i = 0; i < control.actionSets.size(); ++i) { const ActionSet& as = control.actionSets[i]; @@ -448,6 +454,8 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) readInt(xml_control, "MinActionSets", "num", &control.minActionSets); readInt(xml_control, "ToolTipsOn", "on", &control.toolTipsOn); + if(control.minActionSets < 1) + control.minActionSets = 1; control.actionSets.clear(); control.actionSets.reserve(control.minActionSets); @@ -578,6 +586,7 @@ void UserSettings::apply() j->deadZone1 = as.joycfg.s1dead; j->deadZone2 = as.joycfg.s2dead; } + as.updateJoystick(); } core->debugLogActive = system.debugLogOn; diff --git a/BBGE/ActionSet.cpp b/BBGE/ActionSet.cpp index e1b4114..e59fd62 100644 --- a/BBGE/ActionSet.cpp +++ b/BBGE/ActionSet.cpp @@ -24,9 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. JoystickConfig::JoystickConfig() { s1ax = 0; - s1ay = 0; - s2ax = 0; - s2ay = 0; + s1ay = 1; + s2ax = 2; + s2ay = 3; s1dead = 0.3f; s2dead = 0.3f; } @@ -92,6 +92,13 @@ int ActionSet::_whichJoystickForName() return -1; } +void ActionSet::updateJoystick() +{ + Joystick *j = core->getJoystick(joystickID); + if(j) + j->setEnabled(enabled); +} + ActionInput *ActionSet::getActionInputByName(const std::string &name) { for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++) diff --git a/BBGE/ActionSet.h b/BBGE/ActionSet.h index c01425f..f37c979 100644 --- a/BBGE/ActionSet.h +++ b/BBGE/ActionSet.h @@ -50,6 +50,7 @@ public: void clearActions(); int assignJoystickByName(); // -1 if no such joystick found void assignJoystickIdx(int idx); + void updateJoystick(); ActionInput *addActionInput(const std::string &name); ActionInput *getActionInputByName(const std::string &name); @@ -67,7 +68,7 @@ public: //std::string insertInputIntoString(const std::string &string); private: - int _whichJoystickForName(); // -1 if no souch joystick found + int _whichJoystickForName(); // -1 if no such joystick found }; #endif diff --git a/BBGE/Core.h b/BBGE/Core.h index 14fa798..6fc33ce 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -34,12 +34,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "FrameBuffer.h" #include "Shader.h" -#include "Joystick.h" #include "GameKeys.h" class ParticleEffect; +class Joystick; class ParticleManager; diff --git a/BBGE/DebugFont.cpp b/BBGE/DebugFont.cpp index a65f7b6..9b7a420 100644 --- a/BBGE/DebugFont.cpp +++ b/BBGE/DebugFont.cpp @@ -163,8 +163,8 @@ void DebugFont::setAlign(Align align) #include "../BBGE/Quad.h" -DebugButton::DebugButton(int buttonID, DebugButtonReceiver *receiver, int bgWidth, int fsize, bool quitMain) - : RenderObject(), label(0), highlight(0), quitMain(quitMain), receiver(receiver), buttonID(buttonID) +DebugButton::DebugButton(int buttonID, DebugButtonReceiver *receiver, int bgWidth, int fsize) + : RenderObject(), label(0), highlight(0), receiver(receiver), buttonID(buttonID) , activeAlpha(0.5f), activeColor(1,1,1), inactiveAlpha(0.5f), inactiveColor(0,0,0) { if (bgWidth == 0) @@ -214,8 +214,6 @@ void DebugButton::onUpdate(float dt) if (doit) { - if (quitMain) - core->quitNestedMain(); event.call(); if (receiver) receiver->buttonPress(this); diff --git a/BBGE/DebugFont.h b/BBGE/DebugFont.h index 7c46149..6d86ded 100644 --- a/BBGE/DebugFont.h +++ b/BBGE/DebugFont.h @@ -53,10 +53,9 @@ class DebugButtonReceiver; class DebugButton : public RenderObject { public: - DebugButton(int buttonID=-1, DebugButtonReceiver *receiver=0, int bgWidth=0, int fsize=0, bool quitMain=false); + DebugButton(int buttonID=-1, DebugButtonReceiver *receiver=0, int bgWidth=0, int fsize=0); DebugFont *label; EventPtr event; - bool quitMain; int buttonID; float activeAlpha; Vector activeColor; diff --git a/BBGE/Joystick.cpp b/BBGE/Joystick.cpp index 1cd8bb5..6c40bb5 100644 --- a/BBGE/Joystick.cpp +++ b/BBGE/Joystick.cpp @@ -193,7 +193,6 @@ void Joystick::rumble(float leftMotor, float rightMotor, float time) void Joystick::calibrate(Vector &calvec, float deadZone) { - if (calvec.isLength2DIn(deadZone)) { calvec = Vector(0,0,0); @@ -232,7 +231,6 @@ void Joystick::update(float dt) shutdown(); return; } - if (sdl_controller) { for(int i = 0; i < numJoyAxes; ++i) @@ -262,10 +260,10 @@ void Joystick::update(float dt) Sint16 ax = SDL_JoystickGetAxis(sdl_joy, i); axisRaw[i] = float(ax)/32768.0f; } - position.x = axisRaw[s1ax]; - position.y = axisRaw[s1ay]; - rightStick.x = axisRaw[s2ax]; - rightStick.y = axisRaw[s2ay]; + 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); diff --git a/BBGE/Joystick.h b/BBGE/Joystick.h index 2901619..f9c469d 100644 --- a/BBGE/Joystick.h +++ b/BBGE/Joystick.h @@ -39,6 +39,7 @@ public: int getIndex() const { return stickIndex; } int getInstanceID() const { return instanceID; } inline bool isEnabled() const { return enabled; } + inline void setEnabled(bool on) { enabled = on; } const char *getAxisName(int axis) const; const char *getButtonName(int btn) const;