2009-03-23 14:38:06 -04:00
|
|
|
|
2009-04-25 14:25:08 -04:00
|
|
|
#include "graphics/irr_driver.hpp"
|
2009-03-23 14:38:06 -04:00
|
|
|
#include "input/device_manager.hpp"
|
2009-03-29 19:37:21 -04:00
|
|
|
#include "io/file_manager.hpp"
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
2009-05-18 14:38:51 -04:00
|
|
|
#include "user_config.hpp"
|
2009-03-23 14:38:06 -04:00
|
|
|
|
|
|
|
DeviceManager::DeviceManager()
|
|
|
|
{
|
|
|
|
m_keyboard_amount = 0;
|
|
|
|
m_gamepad_amount = 0;
|
|
|
|
}
|
2009-04-25 14:25:08 -04:00
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
bool DeviceManager::initGamePadSupport()
|
|
|
|
{
|
|
|
|
// Prepare a list of connected joysticks.
|
|
|
|
std::cout << "====================\nGamePad/Joystick detection and configuration\n====================\n";
|
|
|
|
|
|
|
|
irr_driver->getDevice()->activateJoysticks(m_irrlicht_gamepads);
|
|
|
|
|
|
|
|
const int numSticks = m_irrlicht_gamepads.size();
|
|
|
|
std::cout << "irrLicht detects " << numSticks << " gamepads" << std::endl;
|
|
|
|
|
|
|
|
bool something_new_to_write = false;
|
|
|
|
|
|
|
|
// check if it's a new gamepad. If so, add it to the file.
|
|
|
|
for (int i = 0; i < numSticks; i++)
|
|
|
|
{
|
|
|
|
std::cout << m_irrlicht_gamepads[i].Name.c_str() << " : "
|
|
|
|
<< m_irrlicht_gamepads[i].Axes << " axes , "
|
|
|
|
<< m_irrlicht_gamepads[i].Buttons << " buttons\n";
|
|
|
|
|
|
|
|
if(checkForGamePad(i)) something_new_to_write = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout << "====================\n";
|
|
|
|
|
|
|
|
return something_new_to_write;
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
2009-05-30 20:40:42 -04:00
|
|
|
GamePadDevice* DeviceManager::getGamePadFromIrrID(const int id)
|
|
|
|
{
|
|
|
|
for(unsigned int i=0; i<m_gamepad_amount; i++)
|
|
|
|
{
|
|
|
|
if(m_gamepads[i].m_index == id)
|
|
|
|
return m_gamepads.get(i);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
2009-04-25 14:25:08 -04:00
|
|
|
/**
|
2009-04-25 15:26:44 -04:00
|
|
|
* Check if we already have a config object for joystick 'irr_id' as reported by irrLicht
|
2009-04-25 14:25:08 -04:00
|
|
|
* If yes, 'open' the gamepad. If no, create one. Returns whether a new gamepad was created.
|
|
|
|
*/
|
|
|
|
bool DeviceManager::checkForGamePad(const int irr_id)
|
|
|
|
{
|
|
|
|
std::string name = m_irrlicht_gamepads[irr_id].Name.c_str();
|
|
|
|
|
|
|
|
std::cout << "trying to find gamepad " << name.c_str() << std::endl;
|
|
|
|
|
|
|
|
for(unsigned int n=0; n<m_gamepad_amount; n++)
|
|
|
|
{
|
|
|
|
std::cout << " (checking...) I remember that gamepad #" << n << " is named " << m_gamepads[n].m_name.c_str() << std::endl;
|
|
|
|
|
|
|
|
// FIXME - don't check only name, but also number of axes and buttons?
|
|
|
|
if(m_gamepads[n].m_name == name)
|
|
|
|
{
|
|
|
|
std::cout << "--> that's the one currently connected\n";
|
2009-05-30 21:27:21 -04:00
|
|
|
m_gamepads[n].open(irr_id, m_gamepads[n].m_name, m_irrlicht_gamepads[irr_id].Axes, m_irrlicht_gamepads[irr_id].Buttons);
|
2009-04-25 14:25:08 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout << "couldn't find this joystick, so creating a new one" << std::endl;
|
2009-05-30 21:27:21 -04:00
|
|
|
add(new GamePadDevice(irr_id, m_irrlicht_gamepads[irr_id].Name.c_str(), m_irrlicht_gamepads[irr_id].Axes, m_irrlicht_gamepads[irr_id].Buttons ));
|
2009-04-25 14:25:08 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
2009-03-23 14:38:06 -04:00
|
|
|
void DeviceManager::add(KeyboardDevice* d)
|
|
|
|
{
|
|
|
|
m_keyboards.push_back(d);
|
|
|
|
m_keyboard_amount = m_keyboards.size();
|
|
|
|
}
|
2009-04-25 14:25:08 -04:00
|
|
|
// -----------------------------------------------------------------------------
|
2009-03-23 14:38:06 -04:00
|
|
|
void DeviceManager::add(GamePadDevice* d)
|
|
|
|
{
|
|
|
|
m_gamepads.push_back(d);
|
|
|
|
m_gamepad_amount = m_gamepads.size();
|
|
|
|
}
|
2009-04-25 14:25:08 -04:00
|
|
|
// -----------------------------------------------------------------------------
|
2009-05-30 14:57:25 -04:00
|
|
|
bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int deviceID, int btnID, int axisDir, int value,
|
2009-03-23 14:38:06 -04:00
|
|
|
int* player /* out */, PlayerAction* action /* out */ )
|
|
|
|
{
|
|
|
|
// TODO - auto-detect player ID from device
|
|
|
|
*player = 0;
|
2009-03-29 20:19:24 -04:00
|
|
|
|
2009-03-23 14:38:06 -04:00
|
|
|
if(type == Input::IT_KEYBOARD)
|
|
|
|
{
|
|
|
|
for(unsigned int n=0; n<m_keyboard_amount; n++)
|
|
|
|
{
|
2009-05-30 14:57:25 -04:00
|
|
|
if( m_keyboards[n].hasBinding(btnID, action) ) return true;
|
2009-03-23 14:38:06 -04:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2009-03-23 14:46:35 -04:00
|
|
|
else if(type == Input::IT_MOUSEBUTTON)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2009-03-31 16:49:51 -04:00
|
|
|
else if(type == Input::IT_STICKBUTTON || type == Input::IT_STICKMOTION)
|
2009-03-23 14:46:35 -04:00
|
|
|
{
|
2009-03-23 15:09:16 -04:00
|
|
|
for(unsigned int n=0; n<m_gamepad_amount; n++)
|
|
|
|
{
|
2009-04-25 20:47:34 -04:00
|
|
|
//std::cout << "checking gamepad #" << n << " out of " << m_gamepad_amount << std::endl;
|
2009-04-25 20:03:46 -04:00
|
|
|
|
2009-05-30 14:57:25 -04:00
|
|
|
if(m_gamepads[n].hasBinding(type, btnID /* axis or button */, value, *player, action /* out */) )
|
2009-04-25 20:03:46 -04:00
|
|
|
{
|
2009-04-25 20:47:34 -04:00
|
|
|
//std::cout << "that's the one.\n";
|
2009-03-29 12:15:17 -04:00
|
|
|
return true;
|
2009-04-25 20:03:46 -04:00
|
|
|
}
|
2009-03-23 15:09:16 -04:00
|
|
|
}
|
2009-03-23 14:46:35 -04:00
|
|
|
return false;
|
|
|
|
}
|
2009-03-23 14:38:06 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2009-03-23 14:46:35 -04:00
|
|
|
|
|
|
|
return false;
|
2009-03-29 19:37:21 -04:00
|
|
|
}
|
2009-04-25 14:25:08 -04:00
|
|
|
// -----------------------------------------------------------------------------
|
2009-03-29 20:19:24 -04:00
|
|
|
bool DeviceManager::deserialize()
|
|
|
|
{
|
|
|
|
static std::string filepath = file_manager->getHomeDir() + "/input.config";
|
|
|
|
|
|
|
|
if(!file_manager->fileExists(filepath)) return false;
|
|
|
|
|
|
|
|
irr::io::IrrXMLReader* xml = irr::io::createIrrXMLReader( filepath.c_str() );
|
|
|
|
|
|
|
|
const int GAMEPAD = 1;
|
|
|
|
const int KEYBOARD = 2;
|
|
|
|
const int NOTHING = 3;
|
|
|
|
|
|
|
|
int reading_now = NOTHING;
|
|
|
|
|
|
|
|
KeyboardDevice* keyboard_device;
|
|
|
|
GamePadDevice* gamepad_device;
|
|
|
|
|
|
|
|
// parse XML file
|
|
|
|
while(xml && xml->read())
|
|
|
|
{
|
|
|
|
switch(xml->getNodeType())
|
|
|
|
{
|
|
|
|
case irr::io::EXN_TEXT:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case irr::io::EXN_ELEMENT:
|
|
|
|
{
|
|
|
|
if (strcmp("keyboard", xml->getNodeName()) == 0)
|
|
|
|
{
|
2009-03-29 20:58:12 -04:00
|
|
|
keyboard_device = new KeyboardDevice(xml);
|
2009-03-29 20:19:24 -04:00
|
|
|
reading_now = KEYBOARD;
|
|
|
|
}
|
|
|
|
else if (strcmp("gamepad", xml->getNodeName()) == 0)
|
|
|
|
{
|
2009-03-29 20:58:12 -04:00
|
|
|
gamepad_device = new GamePadDevice(xml);
|
2009-03-29 20:19:24 -04:00
|
|
|
reading_now = GAMEPAD;
|
|
|
|
}
|
|
|
|
else if (strcmp("action", xml->getNodeName()) == 0)
|
|
|
|
{
|
|
|
|
if(reading_now == KEYBOARD)
|
|
|
|
{
|
|
|
|
if(!keyboard_device->deserializeAction(xml))
|
|
|
|
std::cerr << "Ignoring an ill-formed action in input config\n";
|
|
|
|
}
|
|
|
|
else if(reading_now == GAMEPAD)
|
|
|
|
{
|
2009-03-29 20:58:12 -04:00
|
|
|
if(!gamepad_device->deserializeAction(xml))
|
|
|
|
std::cerr << "Ignoring an ill-formed action in input config\n";
|
2009-03-29 20:19:24 -04:00
|
|
|
}
|
|
|
|
else std::cerr << "Warning: An action is placed in an unexpected area in the input config file\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
// ---- section ending
|
|
|
|
case irr::io::EXN_ELEMENT_END:
|
|
|
|
{
|
|
|
|
if (strcmp("keyboard", xml->getNodeName()) == 0)
|
|
|
|
{
|
|
|
|
add(keyboard_device);
|
|
|
|
reading_now = NOTHING;
|
|
|
|
}
|
|
|
|
else if (strcmp("gamepad", xml->getNodeName()) == 0)
|
|
|
|
{
|
2009-03-29 20:58:12 -04:00
|
|
|
add(gamepad_device);
|
2009-03-29 20:19:24 -04:00
|
|
|
reading_now = GAMEPAD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: break;
|
|
|
|
|
|
|
|
} // end switch
|
|
|
|
} // end while
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2009-04-25 14:25:08 -04:00
|
|
|
// -----------------------------------------------------------------------------
|
2009-03-29 19:37:21 -04:00
|
|
|
void DeviceManager::serialize()
|
|
|
|
{
|
|
|
|
static std::string filepath = file_manager->getHomeDir() + "/input.config";
|
2009-05-18 14:38:51 -04:00
|
|
|
user_config->CheckAndCreateDir();
|
|
|
|
|
2009-03-29 21:42:12 -04:00
|
|
|
std::cout << "writing " << filepath.c_str() << std::endl;
|
2009-03-29 19:37:21 -04:00
|
|
|
|
|
|
|
std::ofstream configfile;
|
|
|
|
configfile.open (filepath.c_str());
|
|
|
|
|
|
|
|
if(!configfile.is_open())
|
|
|
|
{
|
|
|
|
std::cerr << "Failed to open " << filepath.c_str() << " for writing, controls won't be saved\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-03-29 20:19:24 -04:00
|
|
|
|
2009-03-31 11:14:23 -04:00
|
|
|
configfile << "<input>\n\n";
|
|
|
|
|
2009-03-29 19:37:21 -04:00
|
|
|
for(unsigned int n=0; n<m_keyboard_amount; n++)
|
|
|
|
{
|
|
|
|
m_keyboards[n].serialize(configfile);
|
|
|
|
}
|
|
|
|
for(unsigned int n=0; n<m_gamepad_amount; n++)
|
|
|
|
{
|
|
|
|
m_gamepads[n].serialize(configfile);
|
|
|
|
}
|
|
|
|
|
2009-03-31 11:14:23 -04:00
|
|
|
configfile << "</input>\n";
|
|
|
|
|
2009-03-29 19:37:21 -04:00
|
|
|
configfile.close();
|
|
|
|
}
|