From 08b971b7baf9cd4b3632308b3954e673d6d90c8e Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 11 Aug 2020 18:02:19 +0200 Subject: [PATCH] opening debug menu and overlay works again --- Aquaria/Avatar.cpp | 4 +- Aquaria/DSQ.cpp | 4 +- Aquaria/Game.cpp | 4 +- Aquaria/GameEnums.cpp | 47 +++++++++++++++ Aquaria/GameEnums.h | 9 +++ Aquaria/InGameMenu.cpp | 113 ++++++++++++++----------------------- Aquaria/InGameMenu.h | 2 +- Aquaria/UserSettings.cpp | 86 ++++++++++++---------------- Aquaria/WorldMapRender.cpp | 4 +- BBGE/ActionInput.cpp | 8 ++- BBGE/ActionInput.h | 3 +- BBGE/ActionMapper.cpp | 29 ++-------- BBGE/ActionMapper.h | 13 ++--- BBGE/ActionSet.cpp | 96 ++++++++++++++++++++++--------- BBGE/ActionSet.h | 29 +++++++--- BBGE/InputMapper.cpp | 2 +- BBGE/InputMapper.h | 4 +- BBGE/InputMapperRaw.cpp | 2 + CMakeLists.txt | 1 + win/vc90/Aquaria.vcproj | 4 ++ 20 files changed, 261 insertions(+), 203 deletions(-) create mode 100644 Aquaria/GameEnums.cpp diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 522c1c4..8ed4764 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -128,7 +128,7 @@ void Avatar::bindInput() ActionMapper::clearActions(); ActionMapper::clearCreatedEvents(); - const NamedAction actions[] = + /*const NamedAction actions[] = { { "PrimaryAction", ACTION_PRIMARY}, { "SecondaryAction", ACTION_SECONDARY}, @@ -153,7 +153,7 @@ void Avatar::bindInput() { "Look", ACTION_LOOK}, { "Roll", ACTION_ROLL} }; - ImportInput(actions); + importInput(actions);*/ } // note: z is set to 1.0 when we want the aim to be used as the shot direction diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index 0447c80..de0db1c 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -3682,12 +3682,12 @@ void DSQ::bindInput() addAction(MakeFunctionEvent(DSQ, debugMenu), KEY_BACKSPACE, 0); //addAction(MakeFunctionEvent(DSQ, takeScreenshotKey ), KEY_P, 0); - const NamedAction actions[] = + /*const NamedAction actions[] = { { "Escape", ACTION_ESC }, { "Screenshot", ACTION_SCREENSHOT } }; - ImportInput(actions); + importInput(actions);*/ if(game) game->bindInput(); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 47a979f..0051f5b 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -3225,7 +3225,7 @@ void Game::bindInput() addAction(ACTION_TOGGLEGRID, KEY_F9); } - const NamedAction actions[] = + /*const NamedAction actions[] = { { "PrimaryAction", ACTION_PRIMARY}, { "SecondaryAction", ACTION_SECONDARY}, @@ -3264,7 +3264,7 @@ void Game::bindInput() { "Look", ACTION_LOOK}, { "Roll", ACTION_ROLL} }; - ImportInput(actions); + importInput(actions);*/ if (avatar) avatar->bindInput(); diff --git a/Aquaria/GameEnums.cpp b/Aquaria/GameEnums.cpp new file mode 100644 index 0000000..8b53753 --- /dev/null +++ b/Aquaria/GameEnums.cpp @@ -0,0 +1,47 @@ +#include "GameEnums.h" + +// Action names (as seen in usersettings.xml) to action IDs and menu layout +const ActionDef GameActionDefs[] = +{ + // page 1 + { "PrimaryAction", ACTION_PRIMARY, 2107, 0}, + { "SecondaryAction", ACTION_SECONDARY, 2108, 0}, + + { "SwimUp", ACTION_SWIMUP, 2109, 0}, + { "SwimDown", ACTION_SWIMDOWN, 2110, 0}, + { "SwimLeft", ACTION_SWIMLEFT, 2111, 0}, + { "SwimRight", ACTION_SWIMRIGHT, 2112, 0}, + + { "Roll", ACTION_ROLL, 2113, 0}, + { "Revert", ACTION_REVERT, 2114, 0}, + { "WorldMap", ACTION_TOGGLEWORLDMAP, 2115, 0}, + { "Look", ACTION_LOOK, 2127, 0}, + + // page 2 + { "Escape", ACTION_ESC, 2116, 1}, + { "ToggleHelp", ACTION_TOGGLEHELPSCREEN, 2128, 1}, + + { "PrevPage", ACTION_PREVPAGE, 2121, 1}, + { "NextPage", ACTION_NEXTPAGE, 2122, 1}, + { "CookFood", ACTION_COOKFOOD, 2123, 1}, + { "FoodLeft", ACTION_FOODLEFT, 2124, 1}, + { "FoodRight", ACTION_FOODRIGHT, 2125, 1}, + { "FoodDrop", ACTION_FOODDROP, 2126, 1}, + + { "Screenshot", ACTION_SCREENSHOT, 2132, 1}, + + // page 3 + { "SongSlot1", ACTION_SONGSLOT1, 2129, 2}, + { "SongSlot2", ACTION_SONGSLOT2, 2129, 2}, + { "SongSlot3", ACTION_SONGSLOT3, 2129, 2}, + { "SongSlot4", ACTION_SONGSLOT4, 2129, 2}, + { "SongSlot5", ACTION_SONGSLOT5, 2129, 2}, + { "SongSlot6", ACTION_SONGSLOT6, 2129, 2}, + { "SongSlot7", ACTION_SONGSLOT7, 2129, 2}, + { "SongSlot8", ACTION_SONGSLOT8, 2129, 2}, + { "SongSlot9", ACTION_SONGSLOT9, 2129, 2}, + { "SongSlot10", ACTION_SONGSLOT10, 2129, 2}, + + // terminator + { 0, 0, 0, 0 } +}; diff --git a/Aquaria/GameEnums.h b/Aquaria/GameEnums.h index 8a24906..d793069 100644 --- a/Aquaria/GameEnums.h +++ b/Aquaria/GameEnums.h @@ -488,5 +488,14 @@ enum BounceType BOUNCE_REAL = 1 }; +struct ActionDef +{ + const char * const name; + unsigned actionID; + unsigned stringID; // index in stringbank + unsigned page; // page# in key config menu +}; + +extern const ActionDef GameActionDefs[]; #endif diff --git a/Aquaria/InGameMenu.cpp b/Aquaria/InGameMenu.cpp index f7777a8..6f1fe6b 100644 --- a/Aquaria/InGameMenu.cpp +++ b/Aquaria/InGameMenu.cpp @@ -927,7 +927,7 @@ void InGameMenu::bindInput() { addAction(ACTION_ESC, KEY_ESCAPE); - const NamedAction actions[] = + /*const NamedAction actions[] = { { "PrimaryAction", ACTION_PRIMARY}, { "SecondaryAction", ACTION_SECONDARY}, @@ -943,7 +943,7 @@ void InGameMenu::bindInput() { "FoodRight", ACTION_FOODRIGHT}, { "FoodDrop", ACTION_FOODDROP} }; - ImportInput(actions); + importInput(actions);*/ } void InGameMenu::reset() @@ -2127,76 +2127,47 @@ void InGameMenu::create() offy += 2*yi+yi/2; - // PART 1 + for(unsigned page = 0; page < 3; ++page) { RenderObject *kk = createBasicKeyConfig(); - group_keyConfig[0] = kk; - + group_keyConfig[page] = kk; int y = offy; + unsigned entry = 0; - addKeyConfigLine(kk, SB(2107), "PrimaryAction", offx, y+=yi); - addKeyConfigLine(kk, SB(2108), "SecondaryAction", offx, y+=yi); - addKeyConfigLine(kk, SB(2109), "SwimUp", offx, y+=yi, true); - addKeyConfigLine(kk, SB(2110), "SwimDown", offx, y+=yi, true); - addKeyConfigLine(kk, SB(2111), "SwimLeft", offx, y+=yi, true); - addKeyConfigLine(kk, SB(2112), "SwimRight", offx, y+=yi, true); - addKeyConfigLine(kk, SB(2113), "Roll", offx, y+=yi); - addKeyConfigLine(kk, SB(2114), "Revert", offx, y+=yi); - addKeyConfigLine(kk, SB(2115), "WorldMap", offx, y+=yi); - addKeyConfigLine(kk, SB(2127), "Look", offx, y+=yi); + for(const ActionDef *acd = &GameActionDefs[0]; acd->name; ++acd, ++entry) + if(acd->page == page) + { + std::string name = SB(acd->stringID); + if(page == 2) // HACK + { + std::ostringstream os; + os << ' ' << (entry+1); + name += os.str(); + } + addKeyConfigLine(kk, SB(acd->stringID), name, offx, y+=yi); + } - y+=yi+yi/2; - /*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); - - s1x->setDirMove(DIR_LEFT, s1x); - s1x->setDirMove(DIR_RIGHT, s1y); - - s1y->setDirMove(DIR_LEFT, s1x); - s1y->setDirMove(DIR_RIGHT, s2x); - - s2x->setDirMove(DIR_LEFT, s1y); - s2x->setDirMove(DIR_RIGHT, s2y); - - s2y->setDirMove(DIR_LEFT, s2x); - s2y->setDirMove(DIR_RIGHT, s2y);*/ // FIXME controllerfixup - } - - // PART 2 - { - RenderObject *kk = createBasicKeyConfig(); - group_keyConfig[1] = kk; - - int y = offy; - - addKeyConfigLine(kk, SB(2116), "Escape", offx, y+=yi); - addKeyConfigLine(kk, SB(2128), "ToggleHelp", offx, y+=yi); - addKeyConfigLine(kk, SB(2121), "PrevPage", offx, y+=yi); - addKeyConfigLine(kk, SB(2122), "NextPage", offx, y+=yi); - addKeyConfigLine(kk, SB(2123), "CookFood", offx, y+=yi); - addKeyConfigLine(kk, SB(2124), "FoodLeft", offx, y+=yi); - addKeyConfigLine(kk, SB(2125), "FoodRight", offx, y+=yi); - addKeyConfigLine(kk, SB(2126), "FoodDrop", offx, y+=yi); - } - - // PART 2 - { - RenderObject *kk = createBasicKeyConfig(); - group_keyConfig[2] = kk; - - int y = offy; - std::string slotstr = SB(2129); - for(unsigned i = 1; i <= 10; ++i) // SongSlot starts at 1 + if(page == 0) { - std::ostringstream osname; - osname << slotstr << ' ' << i; - std::ostringstream osac; - osac << "SongSlot" << i; - addKeyConfigLine(kk, osname.str(), osac.str(), offx, y+=yi); + y+=yi+yi/2; + + /*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); + + s1x->setDirMove(DIR_LEFT, s1x); + s1x->setDirMove(DIR_RIGHT, s1y); + + s1y->setDirMove(DIR_LEFT, s1x); + s1y->setDirMove(DIR_RIGHT, s2x); + + s2x->setDirMove(DIR_LEFT, s1y); + s2x->setDirMove(DIR_RIGHT, s2y); + + s2y->setDirMove(DIR_LEFT, s2x); + s2y->setDirMove(DIR_RIGHT, s2y);*/ // FIXME controllerfixup } - addKeyConfigLine(kk, SB(2132), "Screenshot", offx, y+=yi); } if(actionSetBox) @@ -3995,7 +3966,7 @@ void InGameMenu::updateKeyConfigMenu(float dt) if(selectedActionSetIdx != curAS) switchToActionSet(curAS); - dsq->user.control.actionSets[selectedActionSetIdx].enabled + dsq->user.control.actionSets[selectedActionSetIdx].cfg.enabled = actionSetCheck->getValue(); } @@ -4202,7 +4173,7 @@ void InGameMenu::switchToActionSet(int idx) if(actionSetBox) { actionSetBox->setSelectedItem(idx); - actionSetCheck->setValue(dsq->user.control.actionSets[idx].enabled); + actionSetCheck->setValue(dsq->user.control.actionSets[idx].cfg.enabled); } for(size_t i = 0; i < keyConfigs.size(); ++i) keyConfigs[i]->setActionSetIndex(idx); @@ -4214,7 +4185,7 @@ void InGameMenu::updateActionSetComboBox() { std::ostringstream os; os << '#' << (i+1); - const std::string& name = dsq->user.control.actionSets[i].name; + const std::string& name = dsq->user.control.actionSets[i].cfg.name; if(name.length()) os << ": " << name; actionSetBox->addItem(os.str()); @@ -4244,7 +4215,7 @@ void InGameMenu::nextJoystick() as.assignJoystickIdx(i, true); if(as.joystickID < 0) - as.joystickName = "NONE"; + as.cfg.joystickName = "NONE"; updateJoystickText(); } @@ -4267,7 +4238,7 @@ void InGameMenu::updateJoystickText() std::string s = "("; s += stringbank.get(2141); s += " "; - s += as.joystickName; + s += as.cfg.joystickName; s += ")"; joystickNameText->setText(s); } @@ -4277,7 +4248,7 @@ void InGameMenu::updateJoystickText() joystickButtonsText->setText(jbt.str()); if(j && as.joystickID >= 0) - joystickGUIDText->setText(as.joystickGUID); + joystickGUIDText->setText(as.cfg.joystickGUID); else joystickGUIDText->setText(""); } diff --git a/Aquaria/InGameMenu.h b/Aquaria/InGameMenu.h index 0529498..bea3fae 100644 --- a/Aquaria/InGameMenu.h +++ b/Aquaria/InGameMenu.h @@ -71,7 +71,7 @@ class InGameMenu : public ActionMapper friend class SongSlot; friend class FoodHolder; friend class KeyConfigMenuReceiver; - enum { NUM_KEY_CONFIG_PAGES = 3 }; + enum { NUM_KEY_CONFIG_PAGES = 3+1 }; public: InGameMenu(); diff --git a/Aquaria/UserSettings.cpp b/Aquaria/UserSettings.cpp index 1434a8a..d5935b3 100644 --- a/Aquaria/UserSettings.cpp +++ b/Aquaria/UserSettings.cpp @@ -200,24 +200,24 @@ void UserSettings::save() { const ActionSet& as = control.actionSets[i]; XMLElement *xml_actionSet = doc.NewElement("ActionSet"); - 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()); + xml_actionSet->SetAttribute("enabled", as.cfg.enabled); + xml_actionSet->SetAttribute("name", as.cfg.name.c_str()); + xml_actionSet->SetAttribute("joystickName", as.cfg.joystickName.c_str()); + xml_actionSet->SetAttribute("joystickGUID", as.cfg.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_joyAxes->SetAttribute("s1ax", as.cfg.joycfg.s1ax); + xml_joyAxes->SetAttribute("s1ay", as.cfg.joycfg.s1ay); + xml_joyAxes->SetAttribute("s2ax", as.cfg.joycfg.s2ax); + xml_joyAxes->SetAttribute("s2ay", as.cfg.joycfg.s2ay); + xml_joyAxes->SetAttribute("s1dead", as.cfg.joycfg.s1dead); + xml_joyAxes->SetAttribute("s2dead", as.cfg.joycfg.s2dead); } xml_actionSet->InsertEndChild(xml_joyAxes); - for (size_t i = 0; i < as.inputSet.size(); i++) + for (size_t i = 0; i < as.cfg.inputSet.size(); i++) { XMLElement *xml_action = doc.NewElement("Action"); - const ActionInput& ai = as.inputSet[i]; + const ActionInput& ai = as.cfg.inputSet[i]; xml_action->SetAttribute("name", ai.getName().c_str()); xml_action->SetAttribute("input", ai.toString().c_str()); @@ -279,32 +279,8 @@ void UserSettings::save() static void ensureDefaultActions(ActionSet& as) { - as.clearActions(); - 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.ensureActionInput(os.str()); - } + for(const ActionDef *acd = &GameActionDefs[0]; acd->name; ++acd) + as.ensureActionInput(acd->name); } static void readInt(XMLElement *xml, const char *elem, const char *att, int *toChange) @@ -474,6 +450,7 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) readInt(xml_control, "ToolTipsOn", "on", &control.toolTipsOn); control.actionSets.clear(); + unsigned playerID = 0; for(XMLElement *xml_actionSet = xml_control->FirstChildElement("ActionSet"); xml_actionSet; xml_actionSet = xml_actionSet->NextSiblingElement("ActionSet")) { @@ -482,21 +459,21 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) ensureDefaultActions(as); if(const char *s = xml_actionSet->Attribute("name")) - as.name = s; + as.cfg.name = s; if(const char *s = xml_actionSet->Attribute("joystickName")) - as.joystickName = s; + as.cfg.joystickName = s; if(const char *s = xml_actionSet->Attribute("joystickGUID")) - as.joystickGUID = s; - as.enabled = xml_actionSet->BoolAttribute("enabled"); + as.cfg.joystickGUID = s; + as.cfg.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"); + as.cfg.joycfg.s1ax = xml_joyAxes->IntAttribute("s1ax"); + as.cfg.joycfg.s1ay = xml_joyAxes->IntAttribute("s1ay"); + as.cfg.joycfg.s2ax = xml_joyAxes->IntAttribute("s2ax"); + as.cfg.joycfg.s2ay = xml_joyAxes->IntAttribute("s2ay"); + as.cfg.joycfg.s1dead = xml_joyAxes->FloatAttribute("s1dead"); + as.cfg.joycfg.s2dead = xml_joyAxes->FloatAttribute("s2dead"); } for(XMLElement *xml_action = xml_actionSet->FirstChildElement(); xml_action; xml_action = xml_action->NextSiblingElement()) @@ -509,11 +486,13 @@ void UserSettings::load(bool doApply, const std::string &overrideFile) ai.fromString(input); } } + + as.initPlayer(playerID++); } } if(control.actionSets.size() == 1) - control.actionSets[0].enabled = true; + control.actionSets[0].cfg.enabled = true; XMLElement *xml_demo = doc.FirstChildElement("Demo"); if (xml_demo) @@ -588,6 +567,15 @@ void UserSettings::apply() core->debugLogActive = system.debugLogOn; + for(size_t i = 0; i < control.actionSets.size(); ++i) + { + ActionSet& as = control.actionSets[i]; + as.initPlayer((unsigned)i); + as.clearBoundActions(); + for(const ActionDef *acd = &GameActionDefs[0]; acd->name; ++acd) + as.bindAction(acd->name, acd->actionID); + } + dsq->bindInput(); core->settings.prebufferSounds = audio.prebuffer; diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 6c75291..1b26b9d 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -796,7 +796,7 @@ void WorldMapRender::bindInput() addAction(ACTION_TOGGLEWORLDMAPEDITOR, KEY_TAB); - const NamedAction actions[] = + /*const NamedAction actions[] = { { "PrimaryAction", ACTION_PRIMARY }, { "SecondaryAction", ACTION_SECONDARY }, @@ -806,7 +806,7 @@ void WorldMapRender::bindInput() { "SwimUp", ACTION_SWIMUP }, { "SwimDown", ACTION_SWIMDOWN } }; - ImportInput(actions); + importInput(actions);*/ } void WorldMapRender::destroy() diff --git a/BBGE/ActionInput.cpp b/BBGE/ActionInput.cpp index 8648ab8..8c77f89 100644 --- a/BBGE/ActionInput.cpp +++ b/BBGE/ActionInput.cpp @@ -385,6 +385,10 @@ unsigned ActionInput::GetField(InputDeviceType dev, unsigned slot) return base + slot; } +InputDeviceType ActionInput::GetDevice(unsigned field) +{ + return getTypeAndSlot(field).type; +} std::string ActionInput::prettyPrintField(unsigned field, int joystickID /* = -1 */) const { @@ -468,11 +472,12 @@ bool ActionInput::Import(const RawInput& inp, unsigned slot) return false; } -bool ActionInput::Export(RawInput& inp, unsigned field) const +bool ActionInput::Export(RawInput& inp, unsigned field, unsigned deviceID) const { TypeAndSlot ts = getTypeAndSlot(field); inp.src.deviceType = ts.type; inp.src.ctrlType = INP_CTRL_BUTTON; + inp.src.deviceID = deviceID; inp.u.pressed = 1; switch(ts.type) @@ -492,6 +497,7 @@ bool ActionInput::Export(RawInput& inp, unsigned field) const if(!k) return false; inp.src.ctrlID = k; + return true; } case INP_DEV_JOYSTICK: { diff --git a/BBGE/ActionInput.h b/BBGE/ActionInput.h index 6a05383..8c984d1 100644 --- a/BBGE/ActionInput.h +++ b/BBGE/ActionInput.h @@ -61,10 +61,11 @@ public: // field: absolute, [0 ..INP_NUMFIELDS) static unsigned GetField(InputDeviceType dev, unsigned slot); + static InputDeviceType GetDevice(unsigned field); 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 + bool Export(RawInput& inp, unsigned field, unsigned deviceID) const; // returns false if no mapping present // for checking whether a key/button/etc is configured bool hasEntry(unsigned field) const; diff --git a/BBGE/ActionMapper.cpp b/BBGE/ActionMapper.cpp index d864ca1..93980d0 100644 --- a/BBGE/ActionMapper.cpp +++ b/BBGE/ActionMapper.cpp @@ -35,12 +35,6 @@ struct LegacyActionData 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; @@ -154,8 +148,11 @@ void ActionMapper::updateActions() { const ActionUpdate& am = _actionChanges[i]; if(am.id >= _activeActions.size()) - _activeActions.resize(am.id); - _activeActions[am.id] = am.state; + _activeActions.resize(am.id + 1); + if(am.state) + _activeActions[am.id] |= (1 << am.playerID); + else + _activeActions[am.id] &= ~(1 << am.playerID); action(am.id, am.state, am.playerID, am.device); } } @@ -239,19 +236,3 @@ void ActionMapper::recvDirectInput(unsigned k, bool keyState) _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 4cafbb9..652d240 100644 --- a/BBGE/ActionMapper.h +++ b/BBGE/ActionMapper.h @@ -35,11 +35,6 @@ struct LegacyActionData; class ActionMapper { public: - struct NamedAction // for importing - { - const char * const name; - unsigned actionID; - }; // funcs ActionMapper(); @@ -79,11 +74,11 @@ public: void recvDirectInput(unsigned k, bool state); protected: - template static void ImportInput(const NamedAction (&a)[N]) + /*template void importInput(const NamedAction (&a)[N]) { - ImportInput(&a[0], N); + importInput(&a[0], N); } - static void ImportInput(const NamedAction *actions, size_t N); + void importInput(const NamedAction *actions, size_t N);*/ std::vector createdEvents; @@ -107,7 +102,7 @@ private: std::vector _inputChanges; // >0: pressed, <0: released bool inUpdate; - std::vector _activeActions; + std::vector _activeActions; }; #endif diff --git a/BBGE/ActionSet.cpp b/BBGE/ActionSet.cpp index 97a99c2..82b3650 100644 --- a/BBGE/ActionSet.cpp +++ b/BBGE/ActionSet.cpp @@ -32,14 +32,32 @@ JoystickConfig::JoystickConfig() } ActionSet::ActionSet() +: joystickID(ACTIONSET_REASSIGN_JOYSTICK), _inputmapper(NULL) { - enabled = true; - joystickID = ACTIONSET_REASSIGN_JOYSTICK; + cfg.enabled = true; } -void ActionSet::clearActions() +ActionSet::ActionSet(const ActionSet& o) +: cfg(o.cfg), _inputmapper(NULL) { - inputSet.clear(); +} + +ActionSet::~ActionSet() +{ + delete _inputmapper; +} + +void ActionSet::initPlayer(unsigned playerID) +{ + assert(!_inputmapper || _inputmapper->playerID == playerID); + if(!_inputmapper) + _inputmapper = new InputMapper(playerID); +} + +void ActionSet::clearBoundActions() +{ + if(_inputmapper) + _inputmapper->clearMapping(); } int ActionSet::assignJoystickByName(bool force) @@ -56,8 +74,8 @@ void ActionSet::assignJoystickIdx(int idx, bool updateValues) { if(updateValues && idx != ACTIONSET_REASSIGN_JOYSTICK) { - joystickName.clear(); - joystickGUID.clear(); + cfg.joystickName.clear(); + cfg.joystickGUID.clear(); } } else if(idx < (int)core->getNumJoysticks()) @@ -66,8 +84,8 @@ void ActionSet::assignJoystickIdx(int idx, bool updateValues) { if(updateValues) { - joystickGUID = j->getGUID(); - joystickName = j->getName(); + cfg.joystickGUID = j->getGUID(); + cfg.joystickName = j->getName(); } } else @@ -78,29 +96,29 @@ void ActionSet::assignJoystickIdx(int idx, bool updateValues) int ActionSet::_whichJoystickForName() { - if(joystickName == "NONE") + if(cfg.joystickName == "NONE") return -1; - if(joystickGUID.length() && joystickName.length()) + if(cfg.joystickGUID.length() && cfg.joystickName.length()) for(size_t i = 0; i < core->getNumJoysticks(); ++i) if(Joystick *j = core->getJoystick(i)) - if(j->getGUID()[0] && joystickGUID == j->getGUID() && joystickName == j->getName()) + if(j->getGUID()[0] && cfg.joystickGUID == j->getGUID() && cfg.joystickName == j->getName()) return int(i); - if(joystickGUID.length()) + if(cfg.joystickGUID.length()) for(size_t i = 0; i < core->getNumJoysticks(); ++i) if(Joystick *j = core->getJoystick(i)) - if(j->getGUID()[0] && joystickGUID == j->getGUID()) + if(j->getGUID()[0] && cfg.joystickGUID == j->getGUID()) return int(i); - if(joystickName.length()) + if(cfg.joystickName.length()) for(size_t i = 0; i < core->getNumJoysticks(); ++i) if(Joystick *j = core->getJoystick(i)) - if(joystickName == j->getName()) + if(cfg.joystickName == j->getName()) return int(i); // first attached - if(!joystickGUID.length() && !joystickName.length()) + if(!cfg.joystickGUID.length() && !cfg.joystickName.length()) for(size_t i = 0; i < core->getNumJoysticks(); ++i) if(Joystick *j = core->getJoystick(i)) return i; @@ -127,13 +145,36 @@ void ActionSet::updateJoystick() // joystick but disabled, so we can't just do // j->setEnabled(enabled) here. Joystick *j = core->getJoystick(joystickID); - if(j && enabled) + if(j && cfg.enabled) j->setEnabled(true); } +// true when device exists +bool ActionSet::getDeviceID(unsigned field, unsigned& deviceID) const +{ + switch(ActionInput::GetDevice(field)) + { + case INP_DEV_MOUSE: + case INP_DEV_KEYBOARD: + deviceID = 0; // SDL only supports 1 mouse and keyboard + return true; + case INP_DEV_JOYSTICK: + if(joystickID >= 0) + { + Joystick *j = core->getJoystick(joystickID); + if(j) + deviceID = j->getInstanceID(); + return !!j; + } + return false; + } + assert(false); + return false; +} + const ActionInput *ActionSet::getActionInputByName(const std::string &name) const { - for (ActionInputSet::const_iterator i = inputSet.begin(); i != inputSet.end(); i++) + for (ActionInputSet::const_iterator i = cfg.inputSet.begin(); i != cfg.inputSet.end(); i++) { if (nocasecmp(i->getName(), name) == 0) { @@ -143,34 +184,35 @@ const ActionInput *ActionSet::getActionInputByName(const std::string &name) cons return 0; } -void ActionSet::importAction(InputMapper *mapper, const std::string &name, unsigned actionID) const +void ActionSet::bindAction(const std::string& name, unsigned action) { - if (!enabled) return; - if (!mapper) return; + assert(_inputmapper); + if (!cfg.enabled) return; const ActionInput *ac = getActionInputByName(name); if(!ac) { - errorLog("ActionSet::importAction: Undefined action name: " + name); + errorLog("ActionSet::importAction: Requested action but it's not in config: " + name); return; } RawInput raw; + unsigned deviceID; for(unsigned i = 0; i < INP_NUMFIELDS; ++i) - if(ac->Export(raw, i)) - if(!mapper->addMapping(InputMapper::TO_BUTTON, raw, actionID)) + if(getDeviceID(i, deviceID) && ac->Export(raw, i, deviceID)) // returns false if no key assigned + if(!_inputmapper->addMapping(InputMapper::TO_BUTTON, raw, action)) errorLog("Failed to map action: " + name); } ActionInput& ActionSet::ensureActionInput(const std::string &name) { - for (ActionInputSet::iterator i = inputSet.begin(); i != inputSet.end(); i++) + for (ActionInputSet::iterator i = cfg.inputSet.begin(); i != cfg.inputSet.end(); i++) if (nocasecmp(i->getName(), name) == 0) return *i; ActionInput newa(name); - inputSet.push_back(newa); - return inputSet.back(); + cfg.inputSet.push_back(newa); + return cfg.inputSet.back(); } /* diff --git a/BBGE/ActionSet.h b/BBGE/ActionSet.h index 7707138..9e18aae 100644 --- a/BBGE/ActionSet.h +++ b/BBGE/ActionSet.h @@ -46,13 +46,19 @@ class ActionSet public: ActionSet(); + ActionSet(const ActionSet& o); + ~ActionSet(); + void initPlayer(unsigned playerID); // call after finishing up + + // runtime binds + void bindAction(const std::string& name, unsigned action); + void clearBoundActions(); - // 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); + bool getDeviceID(unsigned field, unsigned& deviceID) const; + // note: this only ENABLES joysticks if they are needed, but never disables any void updateJoystick(); @@ -62,17 +68,22 @@ public: int joystickID; // >= 0: use that, -1 = no joystick, or ACTIONSET_REASSIGN_JOYSTICK // --- Saved in config --- - ActionInputSet inputSet; - JoystickConfig joycfg; - std::string joystickName; - std::string joystickGUID; - std::string name; - bool enabled; + struct Config + { + ActionInputSet inputSet; + JoystickConfig joycfg; + std::string joystickName; + std::string joystickGUID; + std::string name; + bool enabled; + } cfg; // ----------------------- //std::string insertInputIntoString(const std::string &string); private: int _whichJoystickForName(); // -1 if no such joystick found + + InputMapper *_inputmapper; }; #endif diff --git a/BBGE/InputMapper.cpp b/BBGE/InputMapper.cpp index a550fc9..7dc56e2 100644 --- a/BBGE/InputMapper.cpp +++ b/BBGE/InputMapper.cpp @@ -249,7 +249,7 @@ bool InputMapper::CleanupForMapping(InputControlType c, InputMapper::MapType mt, bool InputMapper::addMapping(MapType mt, const RawInput& inp, unsigned targetID) { Mapping m; - m.buttonOrAxis = 1 + (mt == TO_BUTTON ? int(targetID) : -int(targetID)); + m.buttonOrAxis = (mt == TO_BUTTON ? int(targetID)+1 : -int(targetID)-1); m.raw = inp; m.val = inp.u; diff --git a/BBGE/InputMapper.h b/BBGE/InputMapper.h index 489be6d..7048dfe 100644 --- a/BBGE/InputMapper.h +++ b/BBGE/InputMapper.h @@ -52,6 +52,7 @@ public: bool acceptMouse; int acceptMouseID; // -1: accept all, otherwise: that id + const int playerID; // raw data go in virtual void input(const RawInput *inp); @@ -71,11 +72,10 @@ private: struct Mapping { RawInput raw; // last input that came in, also contains src to check for - int buttonOrAxis; + int buttonOrAxis; // >0: button+1, <0: (-axis-1), never 0 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; diff --git a/BBGE/InputMapperRaw.cpp b/BBGE/InputMapperRaw.cpp index 53b64a7..d78e1dd 100644 --- a/BBGE/InputMapperRaw.cpp +++ b/BBGE/InputMapperRaw.cpp @@ -34,6 +34,8 @@ void InputMapperRaw::input(const RawInput *inp) unsigned char ch = !!inp->u.pressed; keyChanged[idx] |= (keyState[idx] != ch) << 1; // bit 1 becomes bit 0 in next frame keyState[idx] = ch; + + ForwardDirectInput(idx, ch); } void InputMapperRaw::update() diff --git a/CMakeLists.txt b/CMakeLists.txt index ca0d740..29eff39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -429,6 +429,7 @@ SET(AQUARIA_SRCS ${SRCDIR}/Entity.cpp ${SRCDIR}/FlockEntity.cpp ${SRCDIR}/Game.cpp + ${SRCDIR}/GameEnums.cpp ${SRCDIR}/GameStructs.cpp ${SRCDIR}/GameplayVariables.cpp ${SRCDIR}/GasCloud.cpp diff --git a/win/vc90/Aquaria.vcproj b/win/vc90/Aquaria.vcproj index 3ff4361..0a4ab1e 100644 --- a/win/vc90/Aquaria.vcproj +++ b/win/vc90/Aquaria.vcproj @@ -467,6 +467,10 @@ RelativePath="..\..\Aquaria\Game.h" > + +