diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index ead19534a..025331579 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -92,19 +92,12 @@ bool DeviceManager::deserialize() { if (strcmp("keyboard", xml->getNodeName()) == 0) { - keyboard_device = new KeyboardDevice(); - - // TODO - read name and owner attributes - + keyboard_device = new KeyboardDevice(xml); reading_now = KEYBOARD; } else if (strcmp("gamepad", xml->getNodeName()) == 0) { - // TODO - //gamepad_device = new GamePadDevice(); - - // TODO - read name and owner attributes - + gamepad_device = new GamePadDevice(xml); reading_now = GAMEPAD; } else if (strcmp("action", xml->getNodeName()) == 0) @@ -116,9 +109,8 @@ bool DeviceManager::deserialize() } else if(reading_now == GAMEPAD) { - // TODO - //if(!gamepad_device->deserializeAction(xml)) - // std::cerr << "Ignoring an ill-formed action in input config\n"; + if(!gamepad_device->deserializeAction(xml)) + std::cerr << "Ignoring an ill-formed action in input config\n"; } else std::cerr << "Warning: An action is placed in an unexpected area in the input config file\n"; } @@ -134,8 +126,7 @@ bool DeviceManager::deserialize() } else if (strcmp("gamepad", xml->getNodeName()) == 0) { - // TODO - // add(gamepad_device); + add(gamepad_device); reading_now = GAMEPAD; } } @@ -149,6 +140,27 @@ bool DeviceManager::deserialize() return true; } +/** + * Check if we already have a config object for joystick 'sdl_id' as reported by SDL + * If yes, 'open' the gamepad instance. If no, create one. + */ +void DeviceManager::checkForGamePad(const int sdl_id) +{ + std::string name = SDL_JoystickName(sdl_id); + + for(unsigned int n=0; ngetHomeDir() + "/input.config"; diff --git a/src/input/device_manager.hpp b/src/input/device_manager.hpp index 5ec4870ff..ac2d93c80 100644 --- a/src/input/device_manager.hpp +++ b/src/input/device_manager.hpp @@ -25,6 +25,8 @@ public: void serialize(); bool deserialize(); + + void checkForGamePad(const int sdl_id); }; diff --git a/src/input/input_device.cpp b/src/input/input_device.cpp index b781826a6..20b8e616e 100644 --- a/src/input/input_device.cpp +++ b/src/input/input_device.cpp @@ -90,6 +90,15 @@ KeyboardDevice::KeyboardDevice() m_type = DT_KEYBOARD; } // ----------------------------------------------------------------------------- +KeyboardDevice::KeyboardDevice(irr::io::IrrXMLReader* xml) +{ + m_type = DT_KEYBOARD; + + const char* owner_string = xml->getAttributeValue("owner"); + if(owner_string == NULL) m_player = "default"; + else m_player = owner_string; +} +// ----------------------------------------------------------------------------- void KeyboardDevice::loadDefaults() { m_bindings[PA_NITRO].id = SDLK_SPACE; @@ -127,35 +136,60 @@ bool KeyboardDevice::hasBinding(const int key_id, PlayerAction* action /* out */ return false; } - // ----------------------------------------------------------------------------- -/** Constructor for GamePadDevice. - * \param sdlIndex Index of stick. +/** + * Creates a GamePade device from a config file. Note that this device will not yet be ready to be used, + * it must first be detected to be connected by SDL (hence m_sdlJoystick is NULL) */ -GamePadDevice::GamePadDevice(int sdlIndex, const char* name) +GamePadDevice::GamePadDevice(irr::io::IrrXMLReader* xml) { m_type = DT_GAMEPAD; - m_sdlJoystick = SDL_JoystickOpen(sdlIndex); - m_name = name; - m_id = SDL_JoystickName(sdlIndex); + m_sdlJoystick = NULL; + m_prevAxisDirections = NULL; + m_deadzone = DEADZONE_JOYSTICK; + + const char* owner_string = xml->getAttributeValue("owner"); + if(owner_string == NULL) m_player = "default"; + else m_player = owner_string; + + const char* name_string = xml->getAttributeValue("name"); + if(name_string == NULL) + { + std::cerr << "Warning, joystick without name in config file, making it undetectable\n"; + } + else m_name = name_string; +} +// ----------------------------------------------------------------------------- +/** Constructor for GamePadDevice from a connected gamepad for which no configuration existed +* (defaults will be used) + * \param sdlIndex Index of stick. + */ +GamePadDevice::GamePadDevice(int sdlIndex) +{ + m_type = DT_GAMEPAD; + m_name = SDL_JoystickName(sdlIndex); + m_deadzone = DEADZONE_JOYSTICK; + + open(sdlIndex); + + loadDefaults(); +} // GamePadDevice +// ----------------------------------------------------------------------------- +void GamePadDevice::open(const int sdl_id) +{ + m_sdlJoystick = SDL_JoystickOpen(sdl_id); const int count = SDL_JoystickNumAxes(m_sdlJoystick); m_prevAxisDirections = new Input::AxisDirection[count]; for (int i = 0; i < count; i++) m_prevAxisDirections[i] = Input::AD_NEUTRAL; - - m_deadzone = DEADZONE_JOYSTICK; - - //m_index = -1; - - loadDefaults(); -} // GamePadDevice +} // ----------------------------------------------------------------------------- void GamePadDevice::loadDefaults() { /* - TODO - joystic buttons + TODO - default bindings for joystic buttons m_bindings[PA_NITRO] m_bindings[PA_DRIFT] m_bindings[PA_RESCUE] diff --git a/src/input/input_device.hpp b/src/input/input_device.hpp index c455b3bd9..e59c29a3d 100644 --- a/src/input/input_device.hpp +++ b/src/input/input_device.hpp @@ -47,6 +47,7 @@ class KeyboardDevice : public InputDevice { public: KeyboardDevice(); + KeyboardDevice(irr::io::IrrXMLReader* xml); /** checks if this key belongs to this belongs. if yes, sets action and returns true; otherwise returns false */ bool hasBinding(const int key_id, PlayerAction* action /* out */) const; @@ -59,17 +60,22 @@ class GamePadDevice : public InputDevice void resetAxisDirection(const int axis, Input::AxisDirection direction, const int player); public: SDL_Joystick *m_sdlJoystick; - std::string m_id; + std::string m_name; int m_deadzone; int m_index; Input::AxisDirection *m_prevAxisDirections; - /** checks if this key belongs to this belongs. if yes, sets action and returns true; otherwise returns false */ + /** checks if this key belongs to this belongs. if yes, sets action and returns true; otherwise returns false. + The 'player' id passed is simply to know where to send 'axis reset's when necessary*/ bool hasBinding(const int axis, const int value, const int player, PlayerAction* action /* out */); + void open(const int sdl_id); + void loadDefaults(); - GamePadDevice(int sdlIndex, const char* name); + GamePadDevice(int sdlIndex); + GamePadDevice(irr::io::IrrXMLReader* xml); + ~GamePadDevice(); }; diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index 97b9389c0..d6b293ccf 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -67,7 +67,18 @@ m_mode(BOOTSTRAP), m_mouse_val_x(0), m_mouse_val_y(0) m_device_manager->serialize(); } - initGamePadDevices(); + // Prepare a list of connected joysticks. + const int numSticks = SDL_NumJoysticks(); + + std::cout << "SDL detects " << numSticks << " gamepads" << std::endl; + + // TODO - detect if device is currently known and has an entry in the config + // the constructor below should only be used if not + for (int i = 0; i < numSticks; i++) + { + m_device_manager->checkForGamePad(i); + } + } // ----------------------------------------------------------------------------- @@ -75,16 +86,7 @@ m_mode(BOOTSTRAP), m_mouse_val_x(0), m_mouse_val_y(0) */ void InputManager::initGamePadDevices() { - // Prepare a list of connected joysticks. - const int numSticks = SDL_NumJoysticks(); - - std::cout << "SDL detects " << numSticks << " gamepads" << std::endl; - - // TODO - detect if device is currently known and has an entry in the config - for (int i = 0; i < numSticks; i++) - m_device_manager->add(new GamePadDevice(i, SDL_JoystickName(i))); - - // TODO - init gamepad devices from config file + /* m_stick_infos = new GamePadDevice *[numSticks]; std::vector *si = new std::vector;