From a7abbf4c821a2cbf776e917bfce54dfb5ff2d113 Mon Sep 17 00:00:00 2001 From: auria Date: Sat, 4 Jul 2009 20:00:18 +0000 Subject: [PATCH] More work towards multiplayer (player 1 is now assigned an input device when pressing 'new game'). Cleanup when restarting game not implemented git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3701 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/config/player.hpp | 13 ++++-- src/gui/kart_selection.cpp | 46 +++++++++++++++---- src/gui/kart_selection.hpp | 2 + src/gui/modaldialog.cpp | 79 ++++++++++++++++++++------------ src/gui/modaldialog.hpp | 1 + src/gui/screen.cpp | 36 +++++++-------- src/gui/state_manager.cpp | 35 +++++++++++---- src/gui/state_manager.hpp | 5 +++ src/gui/widget.cpp | 2 + src/input/device_manager.cpp | 87 ++++++++++++++++++++++++++++++++---- src/input/device_manager.hpp | 14 +++++- src/input/input_device.cpp | 22 +++++++-- src/input/input_device.hpp | 8 +++- src/input/input_manager.cpp | 25 ++++++----- src/input/input_manager.hpp | 2 +- src/utils/ptr_vector.hpp | 9 ++++ 16 files changed, 292 insertions(+), 94 deletions(-) diff --git a/src/config/player.hpp b/src/config/player.hpp index 58aeccbe3..faf51e175 100644 --- a/src/config/player.hpp +++ b/src/config/player.hpp @@ -22,11 +22,14 @@ #include #include "config/user_config.hpp" +#include "input/input_device.hpp" class InputDevice; /** - * class for managing player name and control configuration + * class for managing player name and control configuration. + * A list of all possible players is stored in the user config. + * A list of currently playing players will be stored somewhere else (FIXME : complete comment) */ class Player { @@ -50,8 +53,12 @@ public: m_device = NULL; } - InputDevice* getDevice() { return m_device; } - void setDevice(InputDevice* device) { m_device = device; } + InputDevice* getDevice() const { return m_device; } + void setDevice(InputDevice* device) + { + m_device = device; + device->setPlayer(this); + } void setName(const std::string &name_){m_name = name_;} diff --git a/src/gui/kart_selection.cpp b/src/gui/kart_selection.cpp index 1d8baddb7..2d1ab507e 100644 --- a/src/gui/kart_selection.cpp +++ b/src/gui/kart_selection.cpp @@ -24,6 +24,9 @@ #include "gui/engine.hpp" #include "gui/screen.hpp" #include "gui/state_manager.hpp" +#include "input/input.hpp" +#include "input/input_manager.hpp" +#include "input/device_manager.hpp" #include "input/input_device.hpp" #include "karts/kart.hpp" #include "karts/kart_properties_manager.hpp" @@ -84,9 +87,7 @@ namespace StateManager const int modelMaxHeight = area->h - 25 - 65; const int modelMaxWidth = area->w; const int bestSize = std::min(modelMaxWidth, modelMaxHeight); - - std::cout << "bestSize=" << bestSize << std::endl; - + modelView->x = area->x + area->w/2 - bestSize*1.2/2; modelView->y = modelY + modelMaxHeight/2 - bestSize/2; modelView->w = bestSize*1.2; // FIXME : for some reason, it looks better this way, though full square should be ok @@ -117,8 +118,8 @@ namespace StateManager }; - // TODO : have one per player - PlayerKart* playerKart1 = NULL; + // ref only since we're adding them to a Screen, and the Screen will take ownership of these widgets + ptr_vector g_player_karts; class KartHoverListener : public RibbonGridHoverListener { @@ -129,7 +130,8 @@ class KartHoverListener : public RibbonGridHoverListener if(selectionID.size() == 0) return; - ModelViewWidget* w3 = playerKart1->modelView; + // TODO : support players other than player 0 (i.e. multiplayer) + ModelViewWidget* w3 = g_player_karts[0].modelView; assert( w3 != NULL ); const KartProperties* kart = kart_properties_manager->getKart(selectionID); @@ -144,11 +146,38 @@ class KartHoverListener : public RibbonGridHoverListener w3->addModel( kartModel->getWheelModel(3), kartModel->getWheelGraphicsPosition(3) ); w3->update(0); - playerKart1->kartName->setText( kart->getName().c_str() ); + // TODO : support players other than player 0 (i.e. multiplayer) + g_player_karts[0].kartName->setText( kart->getName().c_str() ); } }; KartHoverListener* karthoverListener = NULL; +void setPlayer0Device(InputDevice* device) +{ + if(device == NULL) + { + std::cout << "I don't know which device to assign to player 0 :'(\n"; + return; + } + + if(device->getType() == DT_KEYBOARD) + { + std::cout << "Player 0 is using a keyboard\n"; + } + if(device->getType() == DT_GAMEPAD) + { + std::cout << "Player 0 is using a gamepad\n"; + } + + // TODO : support moer than 1 player + StateManager::addActivePlayer( UserConfigParams::m_player.get(0) ); + UserConfigParams::m_player[0].setDevice(device); + + // TODO : fall back in no-assign mode when aborting a game and going back to the menu + input_manager->getDeviceList()->setNoAssignMode(false); + +} + /** * Callback handling events from the kart selection menu */ @@ -171,9 +200,10 @@ void menuEventKarts(Widget* widget, std::string& name) Widget* area = getCurrentScreen()->getWidget("playerskarts"); - playerKart1 = new PlayerKart(area); + PlayerKart* playerKart1 = new PlayerKart(area); getCurrentScreen()->manualAddWidget(playerKart1); playerKart1->add(); + g_player_karts.push_back(playerKart1); // Build kart list const int kart_amount = kart_properties_manager->getNumberOfKarts(); diff --git a/src/gui/kart_selection.hpp b/src/gui/kart_selection.hpp index 21e4a4896..2e76d0c42 100644 --- a/src/gui/kart_selection.hpp +++ b/src/gui/kart_selection.hpp @@ -23,8 +23,10 @@ namespace GUIEngine { class Widget; } +class InputDevice; namespace StateManager { + void setPlayer0Device(InputDevice* device); void menuEventKarts(GUIEngine::Widget* widget, std::string& name); } diff --git a/src/gui/modaldialog.cpp b/src/gui/modaldialog.cpp index 1da5a6d89..5dbb7f2d5 100644 --- a/src/gui/modaldialog.cpp +++ b/src/gui/modaldialog.cpp @@ -89,7 +89,6 @@ void ModalDialog::dismiss() void ModalDialog::onEnterPressed() { - std::cout << "onEnterPressed()\n"; if(modalWindow != NULL) modalWindow->onEnterPressedInternal(); } @@ -263,51 +262,69 @@ void EnterPlayerNameDialog::onEnterPressedInternal() TrackInfoDialog::TrackInfoDialog(const char* trackName, ITexture* screenshot, const float w, const float h) : ModalDialog(w, h) { - const int y1 = m_area.getHeight()/3; - const int y2 = m_area.getHeight() - 50; + const int y1 = m_area.getHeight()/7; + const int y2 = m_area.getHeight()*5/7; + const int y3 = m_area.getHeight()*6/7; + + SpinnerWidget* spinner = new SpinnerWidget(); + spinner->x = m_area.getWidth()/2 - 200; + spinner->y = y2; + spinner->w = 400; + spinner->h = y3 - y2 - 15; + spinner->setParent(m_irrlicht_window); + + spinner->m_properties[PROP_MIN_VALUE] = "1"; + spinner->m_properties[PROP_MAX_VALUE] = "99"; + spinner->m_properties[PROP_TEXT] = "%i laps"; + + m_children.push_back(spinner); + spinner->add(); + spinner->setValue(3); + spinner->m_element->setTabStop(true); + spinner->m_element->setTabGroup(false); + + ButtonWidget* okBtn = new ButtonWidget(); + okBtn->m_properties[PROP_ID] = "start"; + okBtn->m_properties[PROP_TEXT] = _("Start Race"); + okBtn->x = m_area.getWidth()/2 - 200; + okBtn->y = y3; + okBtn->w = 400; + okBtn->h = m_area.getHeight() - y3 - 15; + okBtn->setParent(m_irrlicht_window); + m_children.push_back(okBtn); + okBtn->add(); + okBtn->m_element->setTabStop(true); + okBtn->m_element->setTabGroup(false); + + GUIEngine::getGUIEnv()->setFocus( okBtn->m_element ); + core::rect< s32 > area_top(0, 0, m_area.getWidth(), y1); IGUIStaticText* a = GUIEngine::getGUIEnv()->addStaticText( stringw(trackName).c_str(), - area_top, false /* border */, true /* word wrap */, + area_top, false, true, // border, word warp m_irrlicht_window); - + a->setTabStop(false); + core::rect< s32 > area_left(0, y1, m_area.getWidth()/2, y2); IGUIStaticText* b = GUIEngine::getGUIEnv()->addStaticText( stringw(_("High Scores & Track Info")).c_str(), - area_left, false /* border */, true /* word wrap */, + area_left, false , true , // border, word warp m_irrlicht_window); - + b->setTabStop(false); + // TODO : preserve aspect ratio - core::rect< s32 > area_right(m_area.getWidth()/2, y1, m_area.getWidth(), y2); + core::rect< s32 > area_right(m_area.getWidth()/2, y1, m_area.getWidth(), y2-10); IGUIImage* screenshotWidget = GUIEngine::getGUIEnv()->addImage( area_right, m_irrlicht_window ); screenshotWidget->setImage(screenshot); screenshotWidget->setScaleImage(true); + screenshotWidget->setTabStop(false); - - SpinnerWidget* widget = new SpinnerWidget(); - widget->x = 0; - widget->y = y2; - widget->w = m_area.getWidth(); - widget->h = m_area.getHeight() - y2; - widget->setParent(m_irrlicht_window); - - widget->m_properties[PROP_MIN_VALUE] = "1"; - widget->m_properties[PROP_MAX_VALUE] = "99"; - widget->m_properties[PROP_TEXT] = "%i laps"; - - m_children.push_back(widget); - widget->add(); - widget->setValue(3); - - //IGUIStaticText* d = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Number of laps")).c_str(), - // area_bottom, false /* border */, true /* word wrap */, - // m_irrlicht_window); a->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); b->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); - //d->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); + } // ------------------------------------------------------------------------------------------------------ @@ -343,7 +360,11 @@ void TrackInfoDialog::onEnterPressedInternal() { startGame(); } - + +void TrackInfoDialog::processEvent(std::string& eventSource) +{ + if (eventSource == "start" ) startGame(); +} // ------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------ diff --git a/src/gui/modaldialog.hpp b/src/gui/modaldialog.hpp index d7897c880..b954faca3 100644 --- a/src/gui/modaldialog.hpp +++ b/src/gui/modaldialog.hpp @@ -92,6 +92,7 @@ public: */ TrackInfoDialog(const char* trackName, irr::video::ITexture* screenshot, const float percentWidth, const float percentHeight); void onEnterPressedInternal(); + void processEvent(std::string& eventSource); }; class PlayerInfoDialog : public ModalDialog diff --git a/src/gui/screen.cpp b/src/gui/screen.cpp index c8d218deb..1dc211870 100644 --- a/src/gui/screen.cpp +++ b/src/gui/screen.cpp @@ -443,17 +443,19 @@ void Screen::processAction(const int action, const unsigned int value, Input::In switch(action) { case PA_LEFT: + /* if(type == Input::IT_STICKMOTION) { // simulate a key press irr::SEvent::SKeyInput evt; evt.PressedDown = pressedDown; - evt.Key = KEY_LEFT; + evt.Key = KEY_LEFT; // FIXME : what if keyboard bindings are not set to use this key? irr::SEvent wrapper; wrapper.KeyInput = evt; wrapper.EventType = EET_KEY_INPUT_EVENT; GUIEngine::getDevice()->postEventFromUser(wrapper); } + */ { IGUIElement *el = GUIEngine::getGUIEnv()->getFocus(); if(el == NULL) break; @@ -475,17 +477,18 @@ void Screen::processAction(const int action, const unsigned int value, Input::In break; case PA_RIGHT: + /* if(type == Input::IT_STICKMOTION) { // simulate a key press irr::SEvent::SKeyInput evt; evt.PressedDown = pressedDown; - evt.Key = KEY_RIGHT; + evt.Key = KEY_RIGHT; // FIXME : what if keyboard bindings are not set to use this key? irr::SEvent wrapper; wrapper.KeyInput = evt; wrapper.EventType = EET_KEY_INPUT_EVENT; GUIEngine::getDevice()->postEventFromUser(wrapper); - } + }*/ { IGUIElement *el = GUIEngine::getGUIEnv()->getFocus(); if(el == NULL) break; @@ -537,9 +540,10 @@ void Screen::processAction(const int action, const unsigned int value, Input::In if(stay_within_list) break; else list->setSelected(-1); } - + + // find closest widget if(el != NULL && el->getTabGroup() != NULL && - el->getTabGroup()->getNextElement(el->getTabOrder(), true, false, first, closest)) + el->getTabGroup()->getNextElement(el->getTabOrder(), true /* reverse */, false /* group */, first, closest)) { GUIEngine::getGUIEnv()->setFocus(closest); @@ -558,6 +562,8 @@ void Screen::processAction(const int action, const unsigned int value, Input::In } else { + std::cout << "Could not find any!\n"; + // select the first widget Widget* w = getLastWidget(); @@ -622,28 +628,16 @@ void Screen::processAction(const int action, const unsigned int value, Input::In case PA_FIRE: if(type == Input::IT_STICKBUTTON) { - // simulate a 'enter' key press. doesn't seem to work + // simulate a 'enter' key press irr::SEvent::SKeyInput evt; evt.PressedDown = pressedDown; - evt.Key = KEY_SPACE; // KEY_RETURN + evt.Key = KEY_SPACE; // FIXME : what if keyboard bindings are not set to use this key? + evt.Char = 666; // My magic code to know it's a fake event (FIXME : ugly, but irrlicht doesn't seem to offer better) irr::SEvent wrapper; wrapper.KeyInput = evt; + wrapper.EventType = EET_KEY_INPUT_EVENT; GUIEngine::getDevice()->postEventFromUser(wrapper); - - /* - irr::SEvent::SGUIEvent evt; - evt.EventType = EGET_BUTTON_CLICKED; - evt.Element = GUIEngine::getGUIEnv()->getFocus(); - evt.Caller = GUIEngine::getGUIEnv()->getFocus(); - irr::SEvent wrapper; - wrapper.GUIEvent = evt; - wrapper.EventType = EET_GUI_EVENT; - // GUIEngine::getDevice()->postEventFromUser(wrapper); - this->OnEvent(wrapper); - // std::cout << "posting event to simulate 'enter'\n"; - */ - } break; default: diff --git a/src/gui/state_manager.cpp b/src/gui/state_manager.cpp index ffc0dde63..80141fbda 100644 --- a/src/gui/state_manager.cpp +++ b/src/gui/state_manager.cpp @@ -41,20 +41,35 @@ using namespace GUIEngine; -/** - * This stack will contain menu names (e.g. main.stkgui), and/or 'race'. - */ -std::vector g_menu_stack; -static bool g_game_mode = false; +namespace StateManager +{ + static bool g_game_mode = false; + + /** + * This stack will contain menu names (e.g. main.stkgui), and/or 'race'. + */ + std::vector g_menu_stack; + + /** + * A list of all currently playing players. (only storing references since + * the original is in UserConfig) + */ + ptr_vector g_active_players; + + const ptr_vector& getActivePlayers() + { + return g_active_players; + } + void addActivePlayer(Player* p) + { + g_active_players.push_back(p); + } #if 0 #pragma mark Callbacks #endif -namespace StateManager -{ - // ------------------------------------------------------------------------- /** * Callback handling events from the main menu @@ -68,6 +83,8 @@ namespace StateManager if(selection == "new") { + InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice(); + StateManager::setPlayer0Device(device); StateManager::pushMenu("karts.stkgui"); } else if(selection == "options") @@ -239,7 +256,7 @@ namespace StateManager ITexture* screenshot = GUIEngine::getDriver()->getTexture( (file_manager->getDataDir() + "/gui/track1.png").c_str() ); - new TrackInfoDialog( w2->getSelectionText().c_str(), screenshot, 0.75f, 0.6f); + new TrackInfoDialog( w2->getSelectionText().c_str(), screenshot, 0.8f, 0.7f); } } else if(name == "gps") diff --git a/src/gui/state_manager.hpp b/src/gui/state_manager.hpp index 4534254cb..7655e72a7 100644 --- a/src/gui/state_manager.hpp +++ b/src/gui/state_manager.hpp @@ -20,8 +20,10 @@ #define STATE_MANAGER_HPP #include +#include "utils/ptr_vector.hpp" struct Input; +class Player; namespace StateManager { @@ -35,6 +37,9 @@ namespace StateManager bool isGameState(); void reshowTopMostMenu(); + const ptr_vector& getActivePlayers(); + void addActivePlayer(Player* p); + void escapePressed(); } diff --git a/src/gui/widget.cpp b/src/gui/widget.cpp index d1adf5fce..60d1e5147 100644 --- a/src/gui/widget.cpp +++ b/src/gui/widget.cpp @@ -768,6 +768,8 @@ void SpinnerWidget::add() rect widget_size = rect(x, y, x + w, y + h); IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, ++id_counter, L""); m_element = btn; + + m_element->setTabOrder( m_element->getID() ); // left arrow rect subsize_left_arrow = rect(0 ,0, h, h); diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index d0b61d4cf..d8b491e5c 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -3,14 +3,18 @@ #include #include +#include "config/player.hpp" #include "config/user_config.hpp" #include "graphics/irr_driver.hpp" +#include "gui/state_manager.hpp" #include "io/file_manager.hpp" DeviceManager::DeviceManager() { m_keyboard_amount = 0; m_gamepad_amount = 0; + m_latest_used_device = NULL; + m_no_assign_mode = true; } // ----------------------------------------------------------------------------- bool DeviceManager::initGamePadSupport() @@ -40,6 +44,11 @@ bool DeviceManager::initGamePadSupport() return something_new_to_write; } // ----------------------------------------------------------------------------- +void DeviceManager::setNoAssignMode(const bool noAssignMode) +{ + m_no_assign_mode = noAssignMode; +} +// ----------------------------------------------------------------------------- GamePadDevice* DeviceManager::getGamePadFromIrrID(const int id) { for(unsigned int i=0; i& players = StateManager::getActivePlayers(); + const int playerAmount = players.size(); + for(int n=0; nhasBinding(type, btnID /* axis or button */, value, *player, action /* out */) ) { - //std::cout << "that's the one.\n"; return true; } } + else + { + if(gamepad->m_player_id != -1) + *player = gamepad->m_player_id; + else + return false; // no player mapped to this device + + if(gamepad->hasBinding(type, btnID /* axis or button */, value, *player, action /* out */) ) + { + return true; + } + } + return false; } else @@ -130,6 +193,14 @@ bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int device return false; } // ----------------------------------------------------------------------------- +InputDevice* DeviceManager::getLatestUsedDevice() +{ + // If none, probably the user clicked or used enter; give keyboard by default + if (m_latest_used_device == NULL ) return m_keyboards.get(0); + + return m_latest_used_device; +} +// ----------------------------------------------------------------------------- bool DeviceManager::deserialize() { static std::string filepath = file_manager->getHomeDir() + "/input.config"; diff --git a/src/input/device_manager.hpp b/src/input/device_manager.hpp index 602aae763..94763d54c 100644 --- a/src/input/device_manager.hpp +++ b/src/input/device_manager.hpp @@ -14,6 +14,10 @@ class DeviceManager unsigned int m_keyboard_amount; unsigned int m_gamepad_amount; + InputDevice* m_latest_used_device; + + bool m_no_assign_mode; + public: DeviceManager(); @@ -23,13 +27,21 @@ public: int getGamePadAmount() const { return m_gamepad_amount; } GamePadDevice* getGamePad(const int i) { return m_gamepads.get(i); } GamePadDevice* getGamePadFromIrrID(const int i); + InputDevice* getLatestUsedDevice(); + + /** + * The device manager starts in "no-assign" mode, which means no input configuration is associated + * to any player. So all devices will react. This is used in menus before player set-up is done. + */ + bool noAssignMode() const { return m_no_assign_mode; } + void setNoAssignMode(const bool noAssignMode); int getKeyboardAmount() const { return m_keyboard_amount; } KeyboardDevice* getKeyboard(const int i) { return m_keyboards.get(i); } /** Given some input, finds to which device it belongs and, using the corresponding device object, maps this input to the corresponding player and game action. returns false if player/action could not be set */ - bool mapInputToPlayerAndAction( Input::InputType type, int id0, int id1, int id2, int value, + bool mapInputToPlayerAndAction( Input::InputType type, int id0, int id1, int id2, int value, const bool programaticallyGenerated, int* player /* out */, PlayerAction* action /* out */ ); void serialize(); diff --git a/src/input/input_device.cpp b/src/input/input_device.cpp index bc7057906..6264d1e9b 100644 --- a/src/input/input_device.cpp +++ b/src/input/input_device.cpp @@ -11,8 +11,24 @@ InputDevice::InputDevice() { m_default_bindings[n].id = -1; m_default_bindings[n].type = Input::IT_NONE; - m_default_bindings[n].dir = Input::AD_NEGATIVE; + m_default_bindings[n].dir = Input::AD_NEUTRAL; } + m_player_id = -1; +} +// ----------------------------------------------------------------------------- +void InputDevice::setPlayer(Player* owner) +{ + const ptr_vector& players = StateManager::getActivePlayers(); + const int playerAmount = players.size(); + for(int n=0; n= m_axis_count) return false; // this gamepad doesn't even have that many axes @@ -305,7 +322,6 @@ bool GamePadDevice::hasBinding(Input::InputType type, const int id, const int va { // set positive id to 0 resetAxisDirection(id, Input::AD_POSITIVE, player); - } // going to positive from negative else if (value > 0 && m_prevAxisDirections[id] == Input::AD_NEGATIVE) diff --git a/src/input/input_device.hpp b/src/input/input_device.hpp index 7e73aa231..69076c0a3 100644 --- a/src/input/input_device.hpp +++ b/src/input/input_device.hpp @@ -7,6 +7,8 @@ #include #include "io/xml_node.hpp" +class Player; + enum DeviceType { DT_KEYBOARD, @@ -25,11 +27,13 @@ struct KeyBinding class InputDevice { + friend class DeviceManager; protected: DeviceType m_type; KeyBinding m_default_bindings[PA_COUNT]; - + int m_player_id; + public: std::string m_name; // if device has a name; unused for keyboards since AFAIK we can't tell keyboards apart @@ -37,6 +41,8 @@ public: DeviceType getType() const { return m_type; }; + void setPlayer(Player* owner); + /** * returns a human-readable string for the key binded with the given action */ diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index 39ff0ed13..c64cdf01c 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -251,16 +251,18 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID, * Note: It is the obligation of the called menu to switch of the sense mode. * */ -void InputManager::input(Input::InputType type, int deviceID, int btnID, int axisDirection, int value) +void InputManager::input(Input::InputType type, int deviceID, int btnID, int axisDirection, int value, + const bool programaticallyGenerated) { int player; PlayerAction action; - bool action_found = m_device_manager->mapInputToPlayerAndAction( type, deviceID, btnID, axisDirection, value, &player, &action ); + bool action_found = m_device_manager->mapInputToPlayerAndAction( type, deviceID, btnID, axisDirection, + value, programaticallyGenerated, &player, &action ); - - // in menus, some keyboard keys are standard - if(!StateManager::isGameState() && type == Input::IT_KEYBOARD && m_mode == MENU) + // in menus, some keyboard keys are standard (before each player selected his device) + // FIXME: should enter always work to accept for a player using keyboard? + if(!StateManager::isGameState() && type == Input::IT_KEYBOARD && m_mode == MENU && m_device_manager->noAssignMode()) { action = PA_FIRST; @@ -339,6 +341,9 @@ void InputManager::input(Input::InputType type, int deviceID, int btnID, int axi bool InputManager::input(const SEvent& event) { + //const bool programaticallyGenerated = (event.UserEvent.UserData1 == 666 && event.UserEvent.UserData1 == 999); + const bool programaticallyGenerated = event.EventType == EET_KEY_INPUT_EVENT && (event.KeyInput.Char == 666); + if(event.EventType == EET_JOYSTICK_INPUT_EVENT) { // Axes - FIXME, instead of checking all of them, ask the bindings which ones to poll @@ -359,9 +364,9 @@ bool InputManager::input(const SEvent& event) // FIXME - AD_NEGATIVE/AD_POSITIVE are probably useless since value contains that info too if(value < 0) - input(Input::IT_STICKMOTION, event.JoystickEvent.Joystick , axis_id, Input::AD_NEGATIVE, value); + input(Input::IT_STICKMOTION, event.JoystickEvent.Joystick , axis_id, Input::AD_NEGATIVE, value, programaticallyGenerated); else - input(Input::IT_STICKMOTION, event.JoystickEvent.Joystick, axis_id, Input::AD_POSITIVE, value); + input(Input::IT_STICKMOTION, event.JoystickEvent.Joystick, axis_id, Input::AD_POSITIVE, value, programaticallyGenerated); } GamePadDevice* gp = getDeviceList()->getGamePadFromIrrID(event.JoystickEvent.Joystick); @@ -371,7 +376,7 @@ bool InputManager::input(const SEvent& event) const bool isButtonPressed = event.JoystickEvent.IsButtonPressed(i); if(gp->isButtonPressed(i) || isButtonPressed) - input(Input::IT_STICKBUTTON, event.JoystickEvent.Joystick, i, 0, isButtonPressed ? MAX_VALUE : 0); + input(Input::IT_STICKBUTTON, event.JoystickEvent.Joystick, i, 0, isButtonPressed ? MAX_VALUE : 0, programaticallyGenerated); gp->setButtonPressed(i, isButtonPressed); } @@ -413,12 +418,12 @@ bool InputManager::input(const SEvent& event) #else ev.key.keysym.unicode, #endif - MAX_VALUE); + MAX_VALUE, programaticallyGenerated); } else { - input(Input::IT_KEYBOARD, 0, key, 0, 0); + input(Input::IT_KEYBOARD, 0, key, 0, 0, programaticallyGenerated); } } #if 0 // in case we ever use mouse in-game... diff --git a/src/input/input_manager.hpp b/src/input/input_manager.hpp index a054444e6..1970b9f74 100644 --- a/src/input/input_manager.hpp +++ b/src/input/input_manager.hpp @@ -67,7 +67,7 @@ private: */ int m_mouse_val_x, m_mouse_val_y; - void input(Input::InputType, int, int, int, int); + void input(Input::InputType, int, int, int, int, const bool programaticallyGenerated); void handleStaticAction(int id0, int value); void handlePlayerAction(PlayerAction pa, const int playerNo, int value); void inputSensing(Input::InputType type, int deviceID, int btnID, int axisDirection, int value); diff --git a/src/utils/ptr_vector.hpp b/src/utils/ptr_vector.hpp index 068633699..0f425196f 100644 --- a/src/utils/ptr_vector.hpp +++ b/src/utils/ptr_vector.hpp @@ -128,6 +128,15 @@ TYPE* get(const int ID) return contentsVector[ID]; } +const TYPE* getConst(const int ID) const +{ + + assert(ID > -1); + assert((unsigned int)ID < contentsVector.size()); + + return contentsVector[ID]; +} + int size() const { return contentsVector.size();