Moved the wiimote update loop in a separate thread

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10543 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
funto66 2012-01-02 00:06:11 +00:00
parent dde596e0fc
commit 9dc03ff36d
2 changed files with 126 additions and 63 deletions

View File

@ -36,6 +36,11 @@ WiimoteManager::WiimoteManager()
m_wiimotes = NULL;
m_nb_wiimotes = 0;
m_initial_nb_gamepads = 0;
resetEvent(&m_irr_events[0], -1);
resetEvent(&m_irr_events[1], -1);
m_shut = false;
m_write_id = 0;
}
// -----------------------------------------------------------------------------
@ -109,12 +114,107 @@ void WiimoteManager::launchDetection(int timeout)
gamepadConfig );
device_manager->addGamepad(gamepadDevice);
} // end for
// ---------------------------------------------------
// Create the update thread
if(m_nb_wiimotes > 0)
{
m_write_id = 0;
m_shut = false;
resetEvent(&m_irr_events[0], getGamepadId(0));
resetEvent(&m_irr_events[1], getGamepadId(0));
pthread_mutex_init(&m_mutex, NULL);
pthread_create(&m_thread, NULL, &threadFuncWrapper, this);
}
}
// -----------------------------------------------------------------------------
void WiimoteManager::cleanup()
{
if(m_nb_wiimotes > 0)
{
m_shut = true;
pthread_join(m_thread, NULL);
pthread_mutex_destroy(&m_mutex);
wiiuse_cleanup(m_wiimotes, MAX_WIIMOTES);
m_wiimotes = NULL;
m_nb_wiimotes = 0;
}
}
// -----------------------------------------------------------------------------
void WiimoteManager::update()
{
if(m_nb_wiimotes > 0)
{
pthread_mutex_lock(&m_mutex);
int read_id = !m_write_id;
irr::SEvent event = m_irr_events[read_id];
pthread_mutex_unlock(&m_mutex);
input_manager->input(event);
}
}
// -----------------------------------------------------------------------------
void WiimoteManager::translateEvent(wiimote_t *wm, int gamepad_id, irr::SEvent* event)
{
// Simulate an Irrlicht joystick event;
resetEvent(event, gamepad_id);
// Send button states
if(IS_PRESSED(wm, WIIMOTE_BUTTON_A))
{
printf("DEBUG: A\n");
event->JoystickEvent.ButtonStates |= (1<<1);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_B))
{
printf("DEBUG: B\n");
event->JoystickEvent.ButtonStates |= (1<<2);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS))
{
printf("DEBUG: +\n");
event->JoystickEvent.ButtonStates |= (1<<3);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS))
{
printf("DEBUG: -\n");
event->JoystickEvent.ButtonStates |= (1<<4);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_ONE))
{
printf("DEBUG: 1\n");
event->JoystickEvent.ButtonStates |= (1<<5);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_TWO))
{
printf("DEBUG: 2\n");
event->JoystickEvent.ButtonStates |= (1<<6);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_HOME))
{
printf("DEBUG: Home\n");
event->JoystickEvent.ButtonStates |= (1<<7);
}
}
void WiimoteManager::resetEvent(irr::SEvent* event, int gamepad_id)
{
event->EventType = irr::EET_JOYSTICK_INPUT_EVENT;
for(int i=0 ; i < SEvent::SJoystickEvent::NUMBER_OF_AXES ; i++)
event->JoystickEvent.Axis[i] = 0;
event->JoystickEvent.Joystick = (u8)(gamepad_id);
event->JoystickEvent.POV = 65535;
event->JoystickEvent.ButtonStates = 0;
}
void WiimoteManager::threadFunc()
{
while(!m_shut)
{
if(wiiuse_poll(m_wiimotes, MAX_WIIMOTES))
{
@ -125,7 +225,7 @@ void WiimoteManager::update()
switch (m_wiimotes[i]->event)
{
case WIIUSE_EVENT:
handleEvent(m_wiimotes[i], gamepad_id);
translateEvent(m_wiimotes[i], gamepad_id, &m_irr_events[m_write_id]);
//printf("DEBUG: wiimote event\n");
break;
@ -163,71 +263,21 @@ void WiimoteManager::update()
break;
}
}
pthread_mutex_lock(&m_mutex);
m_write_id = !m_write_id; // swap buffers (no need to swap them if wiiuse_poll()
// did not find anything)
pthread_mutex_unlock(&m_mutex);
}
}
irr_driver->getDevice()->sleep(1); // 'cause come on, the whole CPU is not ours :)
} // end while
}
// -----------------------------------------------------------------------------
void WiimoteManager::cleanup()
void* WiimoteManager::threadFuncWrapper(void *data)
{
if(m_nb_wiimotes > 0)
{
wiiuse_cleanup(m_wiimotes, MAX_WIIMOTES);
m_wiimotes = NULL;
m_nb_wiimotes = 0;
}
}
// -----------------------------------------------------------------------------
void WiimoteManager::handleEvent(wiimote_t *wm, int gamepad_id)
{
// Simulate an Irrlicht joystick event
irr::SEvent event;
event.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
for(int i=0 ; i < SEvent::SJoystickEvent::NUMBER_OF_AXES ; i++)
event.JoystickEvent.Axis[i] = 0;
event.JoystickEvent.Joystick = gamepad_id;
event.JoystickEvent.POV = 65535;
event.JoystickEvent.ButtonStates = 0;
// Send button states
if(IS_PRESSED(wm, WIIMOTE_BUTTON_A))
{
printf("DEBUG: A\n");
event.JoystickEvent.ButtonStates |= (1<<1);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_B))
{
printf("DEBUG: B\n");
event.JoystickEvent.ButtonStates |= (1<<2);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS))
{
printf("DEBUG: +\n");
event.JoystickEvent.ButtonStates |= (1<<3);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS))
{
printf("DEBUG: -\n");
event.JoystickEvent.ButtonStates |= (1<<4);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_ONE))
{
printf("DEBUG: 1\n");
event.JoystickEvent.ButtonStates |= (1<<5);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_TWO))
{
printf("DEBUG: 2\n");
event.JoystickEvent.ButtonStates |= (1<<6);
}
if(IS_PRESSED(wm, WIIMOTE_BUTTON_HOME))
{
printf("DEBUG: Home\n");
event.JoystickEvent.ButtonStates |= (1<<7);
}
input_manager->input(event);
((WiimoteManager*)data)->threadFunc();
return NULL;
}
#endif // ENABLE_WIIUSE

View File

@ -21,6 +21,9 @@
#ifdef ENABLE_WIIUSE
#include <pthread.h>
#include "IEventReceiver.h"
extern const int MAX_WIIMOTES;
extern const int WIIMOTE_AXES;
extern const int WIIMOTE_BUTTONS;
@ -35,6 +38,12 @@ private:
int m_initial_nb_gamepads; // Wiimotes are attributed the IDs following
// the "normal" gamepads - that's a bit of a hack...
pthread_t m_thread;
pthread_mutex_t m_mutex;
int m_write_id;
irr::SEvent m_irr_events[2];
bool m_shut;
public:
WiimoteManager();
@ -47,8 +56,12 @@ public:
int getNbWiimotes() const {return m_nb_wiimotes;}
private:
void handleEvent(wiimote_t* wm, int gamepad_id);
void translateEvent(wiimote_t* wm, int gamepad_id, irr::SEvent* event);
int getGamepadId(int wiimote_id) const {return wiimote_id + m_initial_nb_gamepads;}
void resetEvent(irr::SEvent* event, int gamepad_id);
void threadFunc();
static void* threadFuncWrapper(void* data);
};
extern WiimoteManager* wiimote_manager;