From 2fd181913e928e4e2463f64b6f11e15a305281cf Mon Sep 17 00:00:00 2001 From: fgenesis Date: Fri, 15 Jul 2016 03:22:27 +0200 Subject: [PATCH] Preparations for multiple ActionSets support --- Aquaria/AnimationEditor.cpp | 8 +- Aquaria/AquariaMenuItem.cpp | 44 ++++++---- Aquaria/AquariaMenuItem.h | 10 +-- Aquaria/Avatar.cpp | 60 +++++++------ Aquaria/DSQ.cpp | 101 ++++++++++++--------- Aquaria/DSQ.h | 2 +- Aquaria/Game.cpp | 81 +++++++++-------- Aquaria/InGameMenu.cpp | 24 +++-- Aquaria/SceneEditor.cpp | 50 +++++------ Aquaria/UserSettings.cpp | 171 +++++++++++++++++++++--------------- Aquaria/UserSettings.h | 12 +-- Aquaria/WorldMapRender.cpp | 35 ++++---- BBGE/ActionInput.cpp | 10 +-- BBGE/ActionInput.h | 2 +- BBGE/ActionMapper.cpp | 14 +-- BBGE/ActionMapper.h | 2 +- BBGE/ActionSet.cpp | 90 +++++++++++++++---- BBGE/ActionSet.h | 30 +++++-- BBGE/Core.cpp | 6 ++ BBGE/Core.h | 4 + BBGE/Joystick.cpp | 25 +++++- BBGE/Joystick.h | 4 + 22 files changed, 481 insertions(+), 304 deletions(-) diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 6dfb671..41c8fdb 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -291,10 +291,10 @@ void AnimationEditor::applyState() - addAction(ACTION_SWIMLEFT, KEY_J); - addAction(ACTION_SWIMRIGHT, KEY_K); - addAction(ACTION_SWIMUP, KEY_UP); - addAction(ACTION_SWIMDOWN, KEY_DOWN); + addAction(ACTION_SWIMLEFT, KEY_J, -1); + addAction(ACTION_SWIMRIGHT, KEY_K, -1); + addAction(ACTION_SWIMUP, KEY_UP, -1); + addAction(ACTION_SWIMDOWN, KEY_DOWN, -1); diff --git a/Aquaria/AquariaMenuItem.cpp b/Aquaria/AquariaMenuItem.cpp index 33f0029..cc15a70 100644 --- a/Aquaria/AquariaMenuItem.cpp +++ b/Aquaria/AquariaMenuItem.cpp @@ -24,6 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ActionInput.h" #include "InGameMenu.h" +#include "tinyxml2.h" +using namespace tinyxml2; + float AquariaGuiElement::guiMoveTimer = 0; AquariaGuiElement::GuiElements AquariaGuiElement::guiElements; bool AquariaGuiElement::canDirMoveGlobal = true; @@ -118,11 +121,11 @@ void AquariaGuiElement::updateMovement(float dt) { Direction dir = DIR_NONE; Vector p; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) { - p = core->joysticks[i]->position; + p = core->getJoystick(i)->position; if(!p.isLength2DIn(0.4f)) break; } @@ -356,11 +359,11 @@ bool AquariaSlider::doSliderInput(float dt) float inputAmount; // How much to adjust by? Vector jpos; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) { - jpos = core->joysticks[i]->position; + jpos = core->getJoystick(i)->position; if(fabsf(jpos.x) > SLIDER_JOY_THRESHOLD) break; } @@ -481,7 +484,7 @@ AquariaKeyConfig::AquariaKeyConfig(const std::string &actionInputName, InputSetT keyDown = false; acceptEsc = false; - joystickID = 0; + actionSetIndex = 0; toggleEnterKey(false); } @@ -540,6 +543,11 @@ void AquariaKeyConfig::onUpdate(float dt) if (!hasInput() || alpha.x <= 0) return; + if(actionSetIndex >= dsq->user.control.actionSets.size()) + return; + + ActionSet& as = dsq->user.control.actionSets[actionSetIndex]; + inLoop = true; int *k = 0; @@ -548,7 +556,7 @@ void AquariaKeyConfig::onUpdate(float dt) if (inputSetType != INPUTSET_OTHER) { - ai = dsq->user.control.actionSet.getActionInputByName(actionInputName); + ai = as.getActionInputByName(actionInputName); if (!ai) { @@ -576,18 +584,19 @@ void AquariaKeyConfig::onUpdate(float dt) if (inputSetType == INPUTSET_OTHER) { if (actionInputName == "s1ax") - value = &dsq->user.control.s1ax; + value = &as.joycfg.s1ax; else if (actionInputName == "s1ay") - value = &dsq->user.control.s1ay; + value = &as.joycfg.s1ay; else if (actionInputName == "s2ax") - value = &dsq->user.control.s2ax; + value = &as.joycfg.s2ax; else if (actionInputName == "s2ay") - value = &dsq->user.control.s2ay; + value = &as.joycfg.s2ay; } if (waitingForInput == this) { std::string s; + s.reserve(6); s = "_"; for (int i = 0; i < int(dsq->game->getTimer(5)); i++) { @@ -599,7 +608,7 @@ void AquariaKeyConfig::onUpdate(float dt) { if (k) { - keyConfigFont->setText(getInputCodeToUserString(*k, joystickID)); + keyConfigFont->setText(getInputCodeToUserString(*k, as.joystickID)); } else if (value) { @@ -735,7 +744,7 @@ void AquariaKeyConfig::onUpdate(float dt) } else { - Joystick *j = core->joysticks[joystickID]; + Joystick *j = core->getJoystick(as.joystickID); if(j) { for (int i = 0; i < MAX_JOYSTICK_BTN; i++) @@ -824,6 +833,11 @@ void AquariaKeyConfig::onUpdate(float dt) inLoop = false; } +void AquariaKeyConfig::setActionSetIndex(int idx) +{ + actionSetIndex = idx; +} + void AquariaKeyConfig::setAcceptEsc(bool a) { acceptEsc = a; @@ -833,8 +847,6 @@ AquariaMenuItem::AquariaMenuItem() : Quad(), ActionMapper(), AquariaGuiElement() { quad = glow = 0; choice = -1; - ability = 0; - xmlItem = 0; int sz = 20; shareAlpha = 0; diff --git a/Aquaria/AquariaMenuItem.h b/Aquaria/AquariaMenuItem.h index 942a92b..863578f 100644 --- a/Aquaria/AquariaMenuItem.h +++ b/Aquaria/AquariaMenuItem.h @@ -29,8 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "../BBGE/TTFFont.h" #include "../BBGE/RoundedRect.h" -#include "tinyxml2.h" -using namespace tinyxml2; +namespace tinyxml2 { class XMLDocument; } class AquariaGuiElement { @@ -78,7 +77,6 @@ public: void setLabel(const std::string &label); EventPtr event; BitmapText *font, *glowFont; - XMLElement *ability, *xmlItem; int choice; Quad *glow, *quad; bool useQuad(const std::string &tex); @@ -114,7 +112,7 @@ public: bool mbDown; - static std::string getSaveDescription(const XMLDocument &doc); + static std::string getSaveDescription(const tinyxml2::XMLDocument &doc); protected: void onUpdate(float dt); @@ -171,7 +169,7 @@ public: static AquariaKeyConfig *waitingForInput; void setAcceptEsc(bool a); - void setJoystickID(int id); + void setActionSetIndex(int idx); protected: void toggleEnterKey(int on); @@ -186,7 +184,7 @@ protected: int inputIdx; TTFText *keyConfigFont; Quad *bg; - int joystickID; + int actionSetIndex; bool acceptEsc; }; diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index d0d89f0..92c85ce 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -128,28 +128,34 @@ void Avatar::bindInput() ActionMapper::clearActions(); ActionMapper::clearCreatedEvents(); - dsq->user.control.actionSet.importAction(this, "PrimaryAction", ACTION_PRIMARY); - dsq->user.control.actionSet.importAction(this, "SecondaryAction", ACTION_SECONDARY); + for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + { + const ActionSet& as = dsq->user.control.actionSets[i]; + int sourceID = (int)i; - dsq->user.control.actionSet.importAction(this, "SwimUp", ACTION_SWIMUP); - dsq->user.control.actionSet.importAction(this, "SwimDown", ACTION_SWIMDOWN); - dsq->user.control.actionSet.importAction(this, "SwimLeft", ACTION_SWIMLEFT); - dsq->user.control.actionSet.importAction(this, "SwimRight", ACTION_SWIMRIGHT); + as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID); + as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID); - dsq->user.control.actionSet.importAction(this, "SongSlot1", ACTION_SONGSLOT1); - dsq->user.control.actionSet.importAction(this, "SongSlot2", ACTION_SONGSLOT2); - dsq->user.control.actionSet.importAction(this, "SongSlot3", ACTION_SONGSLOT3); - dsq->user.control.actionSet.importAction(this, "SongSlot4", ACTION_SONGSLOT4); - dsq->user.control.actionSet.importAction(this, "SongSlot5", ACTION_SONGSLOT5); - dsq->user.control.actionSet.importAction(this, "SongSlot6", ACTION_SONGSLOT6); - dsq->user.control.actionSet.importAction(this, "SongSlot7", ACTION_SONGSLOT7); - dsq->user.control.actionSet.importAction(this, "SongSlot8", ACTION_SONGSLOT8); - dsq->user.control.actionSet.importAction(this, "SongSlot9", ACTION_SONGSLOT9); - dsq->user.control.actionSet.importAction(this, "SongSlot10", ACTION_SONGSLOT10); + 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); - dsq->user.control.actionSet.importAction(this, "Revert", ACTION_REVERT); - dsq->user.control.actionSet.importAction(this, "Look", ACTION_LOOK); - dsq->user.control.actionSet.importAction(this, "Roll", ACTION_ROLL); + 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); + } } // note: z is set to 1.0 when we want the aim to be used as the shot direction @@ -159,8 +165,8 @@ Vector Avatar::getAim() Vector d; if (dsq->inputMode == INPUT_JOYSTICK) { - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + 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; @@ -169,8 +175,8 @@ Vector Avatar::getAim() } if(d.isZero()) - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + 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; @@ -1741,8 +1747,8 @@ void Avatar::updateSingingInterface(float dt) if (dsq->inputMode == INPUT_JOYSTICK) { Vector d; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) { d = j->position; @@ -4190,8 +4196,8 @@ Vector Avatar::getFakeCursorPosition() { float axisInput = 0; Joystick *j = 0; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if( ((j = core->joysticks[i])) ) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if( ((j = core->getJoystick(i))) ) if(j->isEnabled()) { axisInput = j->position.getLength2D(); diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index bd38ed7..91bdb99 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -172,7 +172,6 @@ DSQ::DSQ(const std::string& fileSystem, const std::string& extraDataDir) _canSkipCutscene = false; skippingCutscene = false; - almb = armb = 0; bar_left = bar_right = bar_up = bar_down = barFade_left = barFade_right = 0; difficulty = DIFF_NORMAL; @@ -3741,11 +3740,8 @@ void DSQ::action(int id, int state, int source) void DSQ::bindInput() { clearActions(); - - almb = user.control.actionSet.getActionInputByName("PrimaryAction"); - armb = user.control.actionSet.getActionInputByName("SecondaryAction"); - - user.control.actionSet.importAction(this, "Escape", ACTION_ESC); + almb.clear(); + armb.clear(); addAction(MakeFunctionEvent(DSQ, onSwitchScreenMode), KEY_RETURN, 1); @@ -3758,7 +3754,20 @@ void DSQ::bindInput() } addAction(MakeFunctionEvent(DSQ, debugMenu), KEY_BACKSPACE, 0); //addAction(MakeFunctionEvent(DSQ, takeScreenshotKey ), KEY_P, 0); - user.control.actionSet.importAction(this, "Screenshot", ACTION_SCREENSHOT); + + 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); + } } void DSQ::jiggleCursor() @@ -3857,48 +3866,56 @@ void DSQ::onUpdate(float dt) if (inputMode != INPUT_KEYBOARD && game->isActive()) { - if (almb && (ActionMapper::getKeyState(almb->key[0]) || ActionMapper::getKeyState(almb->key[1]))) - mouse.buttons.left = DOWN; - - if (armb && (ActionMapper::getKeyState(armb->key[0]) || ActionMapper::getKeyState(armb->key[1]))) - mouse.buttons.right = DOWN; + for(size_t i = 0; i < almb.size(); ++i) + if (ActionMapper::getKeyState(almb[i]->key[0]) || ActionMapper::getKeyState(almb[i]->key[1])) + { + mouse.buttons.left = DOWN; + break; + } + for(size_t i = 0; i < armb.size(); ++i) + if (ActionMapper::getKeyState(armb[i]->key[0]) || ActionMapper::getKeyState(armb[i]->key[1])) + { + mouse.buttons.right = DOWN; + break; + } } if (joystickAsMouse) { - if (almb && ActionMapper::getKeyState(almb->joy[0])) - mouse.buttons.left = DOWN; - - if (armb && ActionMapper::getKeyState(armb->joy[0])) - mouse.buttons.right = DOWN; + for(size_t i = 0; i < almb.size(); ++i) + if (ActionMapper::getKeyState(almb[i]->joy[0])) + { + mouse.buttons.left = DOWN; + break; + } + for(size_t i = 0; i < armb.size(); ++i) + if (ActionMapper::getKeyState(armb[i]->joy[0])) + { + mouse.buttons.right = DOWN; + break; + } } if (joystickEnabled) { - + if (dsq->inputMode != INPUT_JOYSTICK) { - if (dsq->inputMode != INPUT_JOYSTICK) + const float thresh = JOY_AXIS_THRESHOLD; + for(size_t i = 0; i < getNumJoysticks(); ++i) + if(Joystick *j = getJoystick(i)) + if(j && j->isEnabled()) + if (j->anyButton() || !j->position.isLength2DIn(thresh) || !j->rightStick.isLength2DIn(thresh)) + { + //debugLog("setting joystick input mode"); + dsq->setInputMode(INPUT_JOYSTICK); + } + } + else if (dsq->inputMode != INPUT_MOUSE) + { + if ((!core->mouse.change.isLength2DIn(5) || (core->getMouseButtonState(0) || core->getMouseButtonState(1))) /*&& !core->joystick.anyButton()*/) { - - const float thresh = 0.6; - for(size_t i = 0; i < joysticks.size(); ++i) - if(Joystick *j = joysticks[i]) - if(j && j->isEnabled()) - if (j->anyButton() || !j->position.isLength2DIn(thresh) || !j->rightStick.isLength2DIn(thresh)) - { - //debugLog("setting joystick input mode"); - dsq->setInputMode(INPUT_JOYSTICK); - } - } - else if (dsq->inputMode != INPUT_MOUSE) - { - - - if ((!core->mouse.change.isLength2DIn(5) || (core->getMouseButtonState(0) || core->getMouseButtonState(1))) /*&& !core->joystick.anyButton()*/) - { - //debugLog("setting mouse input mode"); - dsq->setInputMode(INPUT_MOUSE); - } + //debugLog("setting mouse input mode"); + dsq->setInputMode(INPUT_MOUSE); } } } @@ -3986,10 +4003,10 @@ 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 < joysticks.size(); ++i) - if(Joystick *j = joysticks[i]) + for(size_t i = 0; i < getNumJoysticks(); ++i) + if(Joystick *j = getJoystick(i)) { - os << "J[" << i << "]:["; + os << "J[" << i << "," << (j->isEnabled() ? " on" : "off") << "]:["; for(unsigned ii = 0; ii < MAX_JOYSTICK_BTN; ++ii) if(j->getButton(ii)) os << (ii % 10); diff --git a/Aquaria/DSQ.h b/Aquaria/DSQ.h index 1ab4fa4..7f74756 100644 --- a/Aquaria/DSQ.h +++ b/Aquaria/DSQ.h @@ -499,7 +499,7 @@ protected: bool _canSkipCutscene; bool skippingCutscene; - ActionInput *almb, *armb; + std::vector almb, armb; void recreateBlackBars(); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 6614d18..45b6675 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -3228,55 +3228,58 @@ void Game::bindInput() #ifdef AQUARIA_BUILD_SCENEEDITOR if (dsq->canOpenEditor()) { - addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB); + addAction(ACTION_TOGGLESCENEEDITOR, KEY_TAB, -1); } #endif - dsq->user.control.actionSet.importAction(this, "PrimaryAction", ACTION_PRIMARY); - dsq->user.control.actionSet.importAction(this, "SecondaryAction", ACTION_SECONDARY); - - dsq->user.control.actionSet.importAction(this, "Escape", ACTION_ESC); - - dsq->user.control.actionSet.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP); - - dsq->user.control.actionSet.importAction(this, "ToggleHelp", ACTION_TOGGLEHELPSCREEN); - - // used for scrolling help text - dsq->user.control.actionSet.importAction(this, "SwimUp", ACTION_SWIMUP); - dsq->user.control.actionSet.importAction(this, "SwimDown", ACTION_SWIMDOWN); - dsq->user.control.actionSet.importAction(this, "SwimLeft", ACTION_SWIMLEFT); - dsq->user.control.actionSet.importAction(this, "SwimRight", ACTION_SWIMRIGHT); - - - dsq->user.control.actionSet.importAction(this, "PrevPage", ACTION_PREVPAGE); - dsq->user.control.actionSet.importAction(this, "NextPage", ACTION_NEXTPAGE); - dsq->user.control.actionSet.importAction(this, "CookFood", ACTION_COOKFOOD); - dsq->user.control.actionSet.importAction(this, "FoodLeft", ACTION_FOODLEFT); - dsq->user.control.actionSet.importAction(this, "FoodRight", ACTION_FOODRIGHT); - dsq->user.control.actionSet.importAction(this, "FoodDrop", ACTION_FOODDROP); - if (dsq->canOpenEditor()) { //addAction(MakeFunctionEvent(Game, toggleMiniMapRender), KEY_M, 0); - addAction(ACTION_TOGGLEGRID, KEY_F9); + addAction(ACTION_TOGGLEGRID, KEY_F9, -1); } - // To capture quick song keys via script - dsq->user.control.actionSet.importAction(this, "SongSlot1", ACTION_SONGSLOT1); - dsq->user.control.actionSet.importAction(this, "SongSlot2", ACTION_SONGSLOT2); - dsq->user.control.actionSet.importAction(this, "SongSlot3", ACTION_SONGSLOT3); - dsq->user.control.actionSet.importAction(this, "SongSlot4", ACTION_SONGSLOT4); - dsq->user.control.actionSet.importAction(this, "SongSlot5", ACTION_SONGSLOT5); - dsq->user.control.actionSet.importAction(this, "SongSlot6", ACTION_SONGSLOT6); - dsq->user.control.actionSet.importAction(this, "SongSlot7", ACTION_SONGSLOT7); - dsq->user.control.actionSet.importAction(this, "SongSlot8", ACTION_SONGSLOT8); - dsq->user.control.actionSet.importAction(this, "SongSlot9", ACTION_SONGSLOT9); - dsq->user.control.actionSet.importAction(this, "SongSlot10", ACTION_SONGSLOT10); + for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + { + const ActionSet& as = dsq->user.control.actionSets[i]; + int sourceID = (int)i; - dsq->user.control.actionSet.importAction(this, "Revert", ACTION_REVERT); + as.importAction(this, "PrimaryAction", ACTION_PRIMARY, sourceID); + as.importAction(this, "SecondaryAction", ACTION_SECONDARY, sourceID); - dsq->user.control.actionSet.importAction(this, "Look", ACTION_LOOK); - dsq->user.control.actionSet.importAction(this, "Roll", ACTION_ROLL); + as.importAction(this, "Escape", ACTION_ESC, sourceID); + as.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP, sourceID); + as.importAction(this, "ToggleHelp", ACTION_TOGGLEHELPSCREEN, sourceID); + + // 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); + + 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); + + // 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); + + as.importAction(this, "Revert", ACTION_REVERT, sourceID); + + as.importAction(this, "Look", ACTION_LOOK, sourceID); + as.importAction(this, "Roll", ACTION_ROLL, sourceID); + } if (avatar) avatar->bindInput(); diff --git a/Aquaria/InGameMenu.cpp b/Aquaria/InGameMenu.cpp index 007f945..604b9c6 100644 --- a/Aquaria/InGameMenu.cpp +++ b/Aquaria/InGameMenu.cpp @@ -920,16 +920,22 @@ InGameMenu::~InGameMenu() void InGameMenu::bindInput() { - dsq->user.control.actionSet.importAction(this, "Escape", ACTION_ESC); + for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + { + const ActionSet& as = dsq->user.control.actionSets[i]; + int sourceID = (int)i; - dsq->user.control.actionSet.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP); + as.importAction(this, "Escape", ACTION_ESC, sourceID); - dsq->user.control.actionSet.importAction(this, "PrevPage", ACTION_PREVPAGE); - dsq->user.control.actionSet.importAction(this, "NextPage", ACTION_NEXTPAGE); - dsq->user.control.actionSet.importAction(this, "CookFood", ACTION_COOKFOOD); - dsq->user.control.actionSet.importAction(this, "FoodLeft", ACTION_FOODLEFT); - dsq->user.control.actionSet.importAction(this, "FoodRight", ACTION_FOODRIGHT); - dsq->user.control.actionSet.importAction(this, "FoodDrop", ACTION_FOODDROP); + as.importAction(this, "WorldMap", ACTION_TOGGLEWORLDMAP, 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); + } } void InGameMenu::reset() @@ -3215,7 +3221,7 @@ void InGameMenu::onOptionsCancel() } else { - dsq->user.control.actionSet = dsq->user_bcontrol.control.actionSet; + dsq->user.control.actionSets = dsq->user_bcontrol.control.actionSets; } dsq->user.apply(); diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index 3364e3f..13e0f58 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -574,38 +574,38 @@ void SceneEditor::init() - addAction(ACTION_ZOOMIN, KEY_PGUP); - addAction(ACTION_ZOOMOUT, KEY_PGDN); + addAction(ACTION_ZOOMIN, KEY_PGUP, -1); + addAction(ACTION_ZOOMOUT, KEY_PGDN, -1); - addAction(ACTION_CAMLEFT, KEY_A); - addAction(ACTION_CAMRIGHT, KEY_D); - addAction(ACTION_CAMUP, KEY_W); - addAction(ACTION_CAMDOWN, KEY_S); + 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_BGLAYEREND, KEY_0); + addAction(ACTION_BGLAYEREND, KEY_0, -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_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_BGLAYER10, KEY_B); - addAction(ACTION_BGLAYER11, KEY_N); - addAction(ACTION_BGLAYER12, KEY_M); + addAction(ACTION_BGLAYER10, KEY_B, -1); + addAction(ACTION_BGLAYER11, KEY_N, -1); + addAction(ACTION_BGLAYER12, KEY_M, -1); - addAction(ACTION_BGLAYER13, KEY_J); + addAction(ACTION_BGLAYER13, KEY_J, -1); - addAction(ACTION_BGLAYER14, KEY_COMMA); - addAction(ACTION_BGLAYER15, KEY_PERIOD); - addAction(ACTION_BGLAYER16, KEY_SLASH); - addAction(ACTION_BGLAYER16, KEY_MINUS); // HACK: for german keyboard layout -- FG + addAction(ACTION_BGLAYER14, KEY_COMMA, -1); + addAction(ACTION_BGLAYER15, KEY_PERIOD, -1); + addAction(ACTION_BGLAYER16, KEY_SLASH, -1); + addAction(ACTION_BGLAYER16, KEY_MINUS, -1); // HACK: for german keyboard layout -- FG - addAction(ACTION_MULTISELECT, KEY_LALT); + addAction(ACTION_MULTISELECT, KEY_LALT, -1); placer = new Quad; dsq->game->addRenderObject(placer, LR_HUD); diff --git a/Aquaria/UserSettings.cpp b/Aquaria/UserSettings.cpp index 88f2a47..f871888 100644 --- a/Aquaria/UserSettings.cpp +++ b/Aquaria/UserSettings.cpp @@ -182,30 +182,37 @@ void UserSettings::save() } xml_control->InsertEndChild(xml_flip); - XMLElement *xml_joyAxes = doc.NewElement("JoyAxes"); + for(size_t i = 0; i < control.actionSets.size(); ++i) { - xml_joyAxes->SetAttribute("s1ax", control.s1ax); - xml_joyAxes->SetAttribute("s1ay", control.s1ay); - xml_joyAxes->SetAttribute("s2ax", control.s2ax); - xml_joyAxes->SetAttribute("s2ay", control.s2ay); - xml_joyAxes->SetAttribute("s1dead", double(control.s1dead)); - xml_joyAxes->SetAttribute("s2dead", double(control.s2dead)); - } - xml_control->InsertEndChild(xml_joyAxes); - - XMLElement *xml_actionSet = doc.NewElement("ActionSet"); - { - for (int i = 0; i < control.actionSet.inputSet.size(); i++) + const ActionSet& as = control.actionSets[i]; + XMLElement *xml_actionSet = doc.NewElement("ActionSet"); { - XMLElement *xml_action = doc.NewElement("Action"); - ActionInput *actionInput = &control.actionSet.inputSet[i]; - xml_action->SetAttribute("name", actionInput->name.c_str()); - xml_action->SetAttribute("input", actionInput->toString().c_str()); + xml_actionSet->SetAttribute("enabled", as.enabled); + xml_actionSet->SetAttribute("name", as.name.c_str()); + xml_actionSet->SetAttribute("joystickName", as.joystickName.c_str()); + xml_actionSet->SetAttribute("joystickGUID", as.joystickGUID.c_str()); + XMLElement *xml_joyAxes = doc.NewElement("JoyAxes"); + { + xml_joyAxes->SetAttribute("s1ax", as.joycfg.s1ax); + xml_joyAxes->SetAttribute("s1ay", as.joycfg.s1ay); + xml_joyAxes->SetAttribute("s2ax", as.joycfg.s2ax); + xml_joyAxes->SetAttribute("s2ay", as.joycfg.s2ay); + xml_joyAxes->SetAttribute("s1dead", as.joycfg.s1dead); + xml_joyAxes->SetAttribute("s2dead", as.joycfg.s2dead); + } + xml_actionSet->InsertEndChild(xml_joyAxes); + for (int i = 0; i < as.inputSet.size(); i++) + { + XMLElement *xml_action = doc.NewElement("Action"); + const ActionInput& ai = as.inputSet[i]; + xml_action->SetAttribute("name", ai.name.c_str()); + xml_action->SetAttribute("input", ai.toString().c_str()); - xml_actionSet->InsertEndChild(xml_action); + xml_actionSet->InsertEndChild(xml_action); + } } + xml_control->InsertEndChild(xml_actionSet); } - xml_control->InsertEndChild(xml_actionSet); } doc.InsertEndChild(xml_control); @@ -256,8 +263,30 @@ void UserSettings::save() #elif defined(BBGE_BUILD_WINDOWS) doc.SaveFile(userSettingsFilename.c_str()); #endif +} - +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"); } static void readInt(XMLElement *xml, const char *elem, const char *att, int *toChange) @@ -316,28 +345,6 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) version.settingsVersion = xml_version->IntAttribute("settingsVersion"); } - control.actionSet.clearActions(); - - control.actionSet.addActionInput("PrimaryAction"); - control.actionSet.addActionInput("SecondaryAction"); - control.actionSet.addActionInput("SwimUp"); - control.actionSet.addActionInput("SwimDown"); - control.actionSet.addActionInput("SwimLeft"); - control.actionSet.addActionInput("SwimRight"); - control.actionSet.addActionInput("Roll"); - control.actionSet.addActionInput("Revert"); - control.actionSet.addActionInput("WorldMap"); - control.actionSet.addActionInput("Escape"); - control.actionSet.addActionInput("PrevPage"); - control.actionSet.addActionInput("NextPage"); - control.actionSet.addActionInput("CookFood"); - control.actionSet.addActionInput("FoodLeft"); - control.actionSet.addActionInput("FoodRight"); - control.actionSet.addActionInput("FoodDrop"); - control.actionSet.addActionInput("Look"); - control.actionSet.addActionInput("ToggleHelp"); - control.actionSet.addActionInput("Screenshot"); - XMLElement *xml_system = doc.FirstChildElement("System"); if (xml_system) { @@ -372,9 +379,9 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) XMLElement *xml_volume = xml_audio->FirstChildElement("Volume"); if (xml_volume) { - audio.sfxvol = xml_volume->DoubleAttribute("sfx"); - audio.voxvol = xml_volume->DoubleAttribute("vox"); - audio.musvol = xml_volume->DoubleAttribute("mus"); + audio.sfxvol = xml_volume->FloatAttribute("sfx"); + audio.voxvol = xml_volume->FloatAttribute("vox"); + audio.musvol = xml_volume->FloatAttribute("mus"); audio.subtitles = xml_volume->IntAttribute("subs"); } @@ -438,38 +445,52 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) readInt(xml_control, "AutoAim", "on", &control.autoAim); readInt(xml_control, "Targeting", "on", &control.targeting); readInt(xml_control, "FlipInputButtons", "on", &control.flipInputButtons); + readInt(xml_control, "MinActionSets", "num", &control.minActionSets); + readInt(xml_control, "ToolTipsOn", "on", &control.toolTipsOn); - XMLElement *xml_joyAxes = xml_control->FirstChildElement("JoyAxes"); - if (xml_joyAxes) - { - control.s1ax = xml_joyAxes->IntAttribute("s1ax"); - control.s1ay = xml_joyAxes->IntAttribute("s1ay"); - control.s2ax = xml_joyAxes->IntAttribute("s2ax"); - control.s2ay = xml_joyAxes->IntAttribute("s2ay"); - control.s1dead = xml_joyAxes->DoubleAttribute("s1dead"); - control.s2dead = xml_joyAxes->DoubleAttribute("s2dead"); - } + control.actionSets.clear(); + control.actionSets.reserve(control.minActionSets); - XMLElement *xml_actionSet = xml_control->FirstChildElement("ActionSet"); - if (xml_actionSet) + for(XMLElement *xml_actionSet = xml_control->FirstChildElement("ActionSet"); xml_actionSet; xml_actionSet = xml_actionSet->NextSiblingElement("ActionSet")) { - XMLElement *xml_action = 0; - xml_action = xml_actionSet->FirstChildElement(); - while (xml_action) + control.actionSets.push_back(ActionSet()); + ActionSet& as = control.actionSets.back(); + ensureDefaultActions(as); + + if(const char *s = xml_actionSet->Attribute("name")) + as.name = s; + if(const char *s = xml_actionSet->Attribute("joystickName")) + as.joystickName = s; + if(const char *s = xml_actionSet->Attribute("joystickGUID")) + as.joystickGUID = s; + as.enabled = xml_actionSet->BoolAttribute("enabled"); + + if(XMLElement *xml_joyAxes = xml_actionSet->FirstChildElement("JoyAxes")) + { + as.joycfg.s1ax = xml_joyAxes->IntAttribute("s1ax"); + as.joycfg.s1ay = xml_joyAxes->IntAttribute("s1ay"); + as.joycfg.s2ax = xml_joyAxes->IntAttribute("s2ax"); + as.joycfg.s2ay = xml_joyAxes->IntAttribute("s2ay"); + as.joycfg.s1dead = xml_joyAxes->FloatAttribute("s1dead"); + as.joycfg.s2dead = xml_joyAxes->FloatAttribute("s2dead"); + } + + for(XMLElement *xml_action = xml_actionSet->FirstChildElement(); xml_action; xml_action = xml_action->NextSiblingElement()) { std::string name = xml_action->Attribute("name"); - if (!name.empty()) { - ActionInput *ai = control.actionSet.addActionInput(name); - + ActionInput *ai = as.addActionInput(name); ai->fromString(xml_action->Attribute("input")); } - xml_action = xml_action->NextSiblingElement(); } } - readInt(xml_control, "ToolTipsOn", "on", &control.toolTipsOn); + int nas = (int)control.actionSets.size(); + if(nas < control.minActionSets) + control.actionSets.resize(control.minActionSets); + while(nas < control.actionSets.size()) + ensureDefaultActions(control.actionSets[nas++]); } XMLElement *xml_demo = doc.FirstChildElement("Demo"); @@ -538,15 +559,19 @@ void UserSettings::apply() dsq->loops.updateVolume(); // FIXME: This should be per-joystick - for(size_t i = 0; i < core->joysticks.size(); ++i) + for(size_t i = 0; i < control.actionSets.size(); ++i) { - Joystick *j = core->joysticks[i]; - j->s1ax = control.s1ax; - j->s1ay = control.s1ay; - j->s2ax = control.s2ax; - j->s2ay = control.s2ay; - j->deadZone1 = control.s1dead; - j->deadZone2 = control.s2dead; + 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; + } } core->debugLogActive = system.debugLogOn; diff --git a/Aquaria/UserSettings.h b/Aquaria/UserSettings.h index 7b9dbc7..f22c21e 100644 --- a/Aquaria/UserSettings.h +++ b/Aquaria/UserSettings.h @@ -91,22 +91,16 @@ public: autoAim = 1; targeting = 1; flipInputButtons = 0; - s1ax = 0; - s1ay = 0; - s2ax = 0; - s2ay = 0; - s1dead = 0.3; - s2dead = 0.3; joystickEnabled = 0; + minActionSets = 4; } int joystickEnabled; int autoAim; int targeting; int flipInputButtons; - ActionSet actionSet; - int s1ax, s1ay, s2ax, s2ay; - float s1dead, s2dead; + std::vector actionSets; int toolTipsOn; + int minActionSets; } control; struct Demo diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 2193518..22b0925 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -703,12 +703,7 @@ WorldMapRender::WorldMapRender() : RenderObject(), ActionMapper() } shareAlphaWithChildren = 1; - dsq->user.control.actionSet.importAction(this, "SwimLeft", ACTION_SWIMLEFT); - dsq->user.control.actionSet.importAction(this, "SwimRight", ACTION_SWIMRIGHT); - dsq->user.control.actionSet.importAction(this, "SwimUp", ACTION_SWIMUP); - dsq->user.control.actionSet.importAction(this, "SwimDown", ACTION_SWIMDOWN); - - // where old scale + position set were + bindInput(); tophud = new Quad("gui/worldmap-ui", Vector(400,64)); tophud->followCamera = 1; @@ -799,15 +794,21 @@ void WorldMapRender::bindInput() clearActions(); clearCreatedEvents(); - addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB); + addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB, -1); - dsq->user.control.actionSet.importAction(this, "PrimaryAction", ACTION_PRIMARY); - dsq->user.control.actionSet.importAction(this, "SecondaryAction", ACTION_SECONDARY); + for(size_t i = 0; i < dsq->user.control.actionSets.size(); ++i) + { + const ActionSet& as = dsq->user.control.actionSets[i]; + int sourceID = (int)i; - dsq->user.control.actionSet.importAction(this, "SwimLeft", ACTION_SWIMLEFT); - dsq->user.control.actionSet.importAction(this, "SwimRight", ACTION_SWIMRIGHT); - dsq->user.control.actionSet.importAction(this, "SwimUp", ACTION_SWIMUP); - dsq->user.control.actionSet.importAction(this, "SwimDown", ACTION_SWIMDOWN); + 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); + } } void WorldMapRender::destroy() @@ -1029,8 +1030,8 @@ void WorldMapRender::onUpdate(float dt) if (isActing(ACTION_SECONDARY)) { Vector jpos; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j && j->isEnabled()) if(fabsf(j->position.y) > 0.6f) { @@ -1046,8 +1047,8 @@ void WorldMapRender::onUpdate(float dt) else { Vector jpos; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j && j->isEnabled()) if(!j->position.isZero()) { diff --git a/BBGE/ActionInput.cpp b/BBGE/ActionInput.cpp index 300a09b..de133e4 100644 --- a/BBGE/ActionInput.cpp +++ b/BBGE/ActionInput.cpp @@ -84,15 +84,15 @@ static std::string inputcode2string(int k) return std::string(); } -static const char *jaxisname(int joysickID, int axis) +static const char *jaxisname(int joystickID, int axis) { - Joystick *j = joysickID < core->joysticks.size() ? core->joysticks[joysickID] : NULL; + Joystick *j = core->getJoystick(joystickID); return j ? j->getAxisName(axis) : NULL; } -static const char *jbtnname(int joysickID, int btn) +static const char *jbtnname(int joystickID, int btn) { - Joystick *j = joysickID < core->joysticks.size() ? core->joysticks[joysickID] : NULL; + Joystick *j = core->getJoystick(joystickID); return j ? j->getButtonName(btn) : NULL; } @@ -171,7 +171,7 @@ ActionInput::ActionInput() for (int i = 0; i < INP_JOYSIZE; i++) joy[i] = 0; } -std::string ActionInput::toString() +std::string ActionInput::toString() const { std::ostringstream os; diff --git a/BBGE/ActionInput.h b/BBGE/ActionInput.h index 4383da4..974ec93 100644 --- a/BBGE/ActionInput.h +++ b/BBGE/ActionInput.h @@ -43,7 +43,7 @@ public: int key[INP_KEYSIZE]; int joy[INP_JOYSIZE]; - std::string toString(); + std::string toString() const; void fromString(const std::string &read); }; diff --git a/BBGE/ActionMapper.cpp b/BBGE/ActionMapper.cpp index 704bab4..36d8e22 100644 --- a/BBGE/ActionMapper.cpp +++ b/BBGE/ActionMapper.cpp @@ -56,7 +56,7 @@ bool ActionMapper::isActing(int actionID) return false; } -void ActionMapper::addAction (int actionID, int k) +void ActionMapper::addAction(int actionID, int k, int source) { ActionData *ad = getActionDataByID(actionID); @@ -203,8 +203,8 @@ bool ActionMapper::getKeyState(int k) { int v = k - JOY_BUTTON_0; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) if( ((keyState = j->getButton(v))) ) break; @@ -213,8 +213,8 @@ bool ActionMapper::getKeyState(int k) { int v = k - JOY_AXIS_0_POS; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) { float ax = j->getAxisUncalibrated(v); @@ -227,8 +227,8 @@ bool ActionMapper::getKeyState(int k) { int v = k - JOY_AXIS_END_NEG; - for(size_t i = 0; i < core->joysticks.size(); ++i) - if(Joystick *j = core->joysticks[i]) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) if(j->isEnabled()) { float ax = j->getAxisUncalibrated(v); diff --git a/BBGE/ActionMapper.h b/BBGE/ActionMapper.h index b4702a7..837023c 100644 --- a/BBGE/ActionMapper.h +++ b/BBGE/ActionMapper.h @@ -68,7 +68,7 @@ public: virtual ~ActionMapper(); void addAction(Event *event, int k, int state=-1); - void addAction(int actionID, int k); + void addAction(int actionID, int k, int source); void removeAction(int actionID); void removeAllActions(); diff --git a/BBGE/ActionSet.cpp b/BBGE/ActionSet.cpp index 4d017d6..dd4abf1 100644 --- a/BBGE/ActionSet.cpp +++ b/BBGE/ActionSet.cpp @@ -21,11 +21,71 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ActionSet.h" #include "Core.h" +JoystickConfig::JoystickConfig() +{ + s1ax = 0; + s1ay = 0; + s2ax = 0; + s2ay = 0; + s1dead = 0.3f; + s2dead = 0.3f; +} + +ActionSet::ActionSet() +{ + enabled = true; + joystickID = 0; +} + void ActionSet::clearActions() { inputSet.clear(); } +int ActionSet::assignJoystickByName() +{ + int idx = _whichJoystickForName(); + if(idx >= 0) + assignJoystickIdx(idx); + return idx; +} + +void ActionSet::assignJoystickIdx(int idx) +{ + if(idx < 0) + { + joystickID = -1; + joystickName.clear(); + joystickGUID.clear(); + } + else if(idx < (int)core->getNumJoysticks()) + { + if(Joystick *j = core->getJoystick(idx)) + { + joystickGUID = j->getGUID(); + joystickName = j->getName(); + joystickID = idx; + } + } +} + +int ActionSet::_whichJoystickForName() +{ + if(joystickGUID.length()) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) + if(j->getGUID()[0] && joystickGUID == j->getGUID()) + return int(i); + + if(joystickName.length()) + for(size_t i = 0; i < core->getNumJoysticks(); ++i) + if(Joystick *j = core->getJoystick(i)) + if(joystickName == j->getName()) + return int(i); + + return -1; +} + ActionInput *ActionSet::getActionInputByName(const std::string &name) { for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++) @@ -40,37 +100,39 @@ ActionInput *ActionSet::getActionInputByName(const std::string &name) -void ActionSet::importAction(ActionMapper *mapper, const std::string &name, int actionID) +void ActionSet::importAction(ActionMapper *mapper, const std::string &name, int actionID, int sourceID) const { + if (!enabled) return; if (!mapper) return; for (int i = 0; i < inputSet.size(); i++) { - ActionInput *actionInput = &inputSet[i]; + const ActionInput *actionInput = &inputSet[i]; if (actionInput->name == name) { for (int i = 0; i < INP_MSESIZE; i++) if (actionInput->mse[i]) - mapper->addAction(actionID, actionInput->mse[i]); + mapper->addAction(actionID, actionInput->mse[i], sourceID); for (int i = 0; i < INP_KEYSIZE; i++) if (actionInput->key[i]) - mapper->addAction(actionID, actionInput->key[i]); + mapper->addAction(actionID, actionInput->key[i], sourceID); for (int i = 0; i < INP_JOYSIZE; i++) if (actionInput->joy[i]) - mapper->addAction(actionID, actionInput->joy[i]); + mapper->addAction(actionID, actionInput->joy[i], sourceID); return; } } } -void ActionSet::importAction(ActionMapper *mapper, const std::string &name, Event *event, int state) +void ActionSet::importAction(ActionMapper *mapper, const std::string &name, Event *event, int state) const { + if (!enabled) return; if (!mapper) return; for (int i = 0; i < inputSet.size(); i++) { - ActionInput *actionInput = &inputSet[i]; + const ActionInput *actionInput = &inputSet[i]; if (actionInput->name == name) { for (int i = 0; i < INP_MSESIZE; i++) @@ -91,15 +153,13 @@ void ActionSet::importAction(ActionMapper *mapper, const std::string &name, Even ActionInput *ActionSet::addActionInput(const std::string &name) { ActionInput *a = getActionInputByName(name); - if (!a) - { - ActionInput newa; - newa.name = name; - inputSet.push_back(newa); - a = getActionInputByName(name); - } + if(a) + return a; - return a; + ActionInput newa; + newa.name = name; + inputSet.push_back(newa); + return &inputSet.back(); } /* diff --git a/BBGE/ActionSet.h b/BBGE/ActionSet.h index b64989c..c01425f 100644 --- a/BBGE/ActionSet.h +++ b/BBGE/ActionSet.h @@ -32,22 +32,42 @@ typedef std::vector ActionInputSet; class ActionMapper; class Event; +struct JoystickConfig +{ + JoystickConfig(); + int s1ax, s1ay, s2ax, s2ay; + float s1dead, s2dead; +}; + class ActionSet { public: - void importAction(ActionMapper *mapper, const std::string &name, Event *event, int state); - void importAction(ActionMapper *mapper, const std::string &name, int actionID); + 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; void clearActions(); + int assignJoystickByName(); // -1 if no such joystick found + void assignJoystickIdx(int idx); ActionInput *addActionInput(const std::string &name); - - - ActionInput *getActionInputByName(const std::string &name); + int joystickID; + + // --- Saved in config --- ActionInputSet inputSet; + JoystickConfig joycfg; + std::string joystickName; + std::string joystickGUID; + std::string name; + bool enabled; + // ----------------------- //std::string insertInputIntoString(const std::string &string); +private: + int _whichJoystickForName(); // -1 if no souch joystick found }; #endif diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index f634174..695104c 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -3034,3 +3034,9 @@ void Core::onJoystickRemoved(int instanceID) } // TODO: fixup ActionMapper? } + +Joystick *Core::getJoystick(int idx) +{ + size_t i = idx; + return i < joysticks.size() ? joysticks[i] : NULL; +} diff --git a/BBGE/Core.h b/BBGE/Core.h index 1e2890f..14fa798 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -558,6 +558,10 @@ protected: std::string _extraDataDir; public: + Joystick *getJoystick(int idx); // warning: may return NULL/contain holes + // not the actual number of joysticks! + size_t getNumJoysticks() const { return joysticks.size(); } +private: std::vector joysticks; }; diff --git a/BBGE/Joystick.cpp b/BBGE/Joystick.cpp index cc4c44d..b9d7fb7 100644 --- a/BBGE/Joystick.cpp +++ b/BBGE/Joystick.cpp @@ -55,6 +55,16 @@ Joystick::Joystick() enabled = true; } +const char *Joystick::getName() const +{ + return name.c_str(); +} + +const char *Joystick::getGUID() const +{ + return guid.c_str(); +} + bool Joystick::init(int stick) { stickIndex = stick; @@ -89,7 +99,13 @@ bool Joystick::init(int stick) if (sdl_joy) { #ifdef BBGE_BUILD_SDL2 - debugLog(std::string("Initialized Joystick [") + SDL_JoystickName(sdl_joy) + "]"); + const char *n = SDL_JoystickName(sdl_joy); + name = n ? n : ""; + SDL_JoystickGUID jg = SDL_JoystickGetGUID(sdl_joy); + char guidbuf[40]; + guid = &guidbuf[0]; + SDL_JoystickGetGUIDString(jg, &guidbuf[0], sizeof(guidbuf)); + debugLog(std::string("Initialized Joystick [") + name + "], GUID [" + guid + "]"); if (sdl_controller) { debugLog("Joystick is a Game Controller"); @@ -99,7 +115,9 @@ bool Joystick::init(int stick) debugLog("Joystick has force feedback support"); instanceID = SDL_JoystickInstanceID(sdl_joy); #else - debugLog(std::string("Initialized Joystick [") + SDL_JoystickName(stick)) + std::string("]")); + const char *n = SDL_JoystickName(stick); + name = n ? n : ""; + debugLog(std::string("Initialized Joystick [") + name + "]"); instanceID = SDL_JoystickIndex(sdl_joy); #endif @@ -108,6 +126,9 @@ bool Joystick::init(int stick) if(numJoyAxes > MAX_JOYSTICK_AXIS) numJoyAxes = MAX_JOYSTICK_AXIS; + + + return true; } diff --git a/BBGE/Joystick.h b/BBGE/Joystick.h index 3a8407a..2901619 100644 --- a/BBGE/Joystick.h +++ b/BBGE/Joystick.h @@ -42,6 +42,8 @@ public: const char *getAxisName(int axis) const; const char *getButtonName(int btn) const; + const char *getName() const; + const char *getGUID() const; Vector rightStick; @@ -56,6 +58,8 @@ private: int numJoyAxes; SDL_Joystick *sdl_joy; float axisRaw[MAX_JOYSTICK_AXIS]; + std::string name; + std::string guid; # ifdef BBGE_BUILD_SDL2 SDL_GameController *sdl_controller;