gamepad axes work again
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3423 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -398,14 +398,7 @@ void IrrDriver::setAmbientLight(const video::SColor &light)
|
||||
*/
|
||||
void IrrDriver::update(float dt)
|
||||
{
|
||||
// FIXME: the run() call interferes with the SDL event handling
|
||||
// currently implemented in STK (since run() converts all SDL events
|
||||
// into irrlicht events). To avoid re-writing the STK event handling,
|
||||
// instead of calling run(), we only update the irrlicht timer (which is
|
||||
// necessary to get animations to work) - that's the only other operation
|
||||
// happening in run.
|
||||
if(!m_device->run()) return;
|
||||
//m_device->getTimer()->tick();
|
||||
m_device->getVideoDriver()->beginScene(true, true, video::SColor(255,100,101,140));
|
||||
m_scene_manager->drawAll();
|
||||
|
||||
|
||||
@@ -40,7 +40,9 @@ namespace GUIEngine
|
||||
}
|
||||
bool OnEvent (const SEvent &event)
|
||||
{
|
||||
if(event.EventType == EET_GUI_EVENT || !StateManager::isGameState())
|
||||
if(event.EventType == EET_GUI_EVENT ||
|
||||
(!StateManager::isGameState() && event.EventType != EET_KEY_INPUT_EVENT && event.EventType != EET_JOYSTICK_INPUT_EVENT)
|
||||
)
|
||||
{
|
||||
if(g_current_screen == NULL) return false;
|
||||
g_current_screen->OnEvent(event);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "gui/widget.hpp"
|
||||
#include "gui/state_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "input/input.hpp"
|
||||
|
||||
using namespace irr;
|
||||
|
||||
@@ -349,11 +350,136 @@ Widget* Screen::getLastWidget(ptr_vector<Widget>* within_vector)
|
||||
#pragma mark irrLicht events
|
||||
#endif
|
||||
|
||||
#define MAX_VALUE 32768
|
||||
|
||||
void Screen::processAction(const int action, const unsigned int value)
|
||||
{
|
||||
const bool pressedDown = value > MAX_VALUE*2/3;
|
||||
|
||||
if(!pressedDown) return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case PA_LEFT:
|
||||
{
|
||||
IGUIElement *el = GUIEngine::getGUIEnv()->getFocus();
|
||||
if(el == NULL) break;
|
||||
Widget* w = getWidget( el->getID() );
|
||||
if(w == NULL) break;
|
||||
|
||||
Widget* widget_to_call = w;
|
||||
|
||||
/* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall
|
||||
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
|
||||
notified of clicks onto themselves so they can toggle their state. ) */
|
||||
while(widget_to_call->m_event_handler != NULL && widget_to_call->m_event_handler != widget_to_call)
|
||||
widget_to_call = widget_to_call->m_event_handler;
|
||||
|
||||
if(widget_to_call->leftPressed())
|
||||
transmitEvent(w, w->m_properties[PROP_ID]);
|
||||
}
|
||||
break;
|
||||
|
||||
case PA_RIGHT:
|
||||
|
||||
{
|
||||
IGUIElement *el = GUIEngine::getGUIEnv()->getFocus();
|
||||
if(el == NULL) break;
|
||||
Widget* w = getWidget( el->getID() );
|
||||
if(w == NULL) break;
|
||||
|
||||
Widget* widget_to_call = w;
|
||||
/* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall
|
||||
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
|
||||
notified of clicks onto themselves so they can toggle their state. ) */
|
||||
while(widget_to_call->m_event_handler != NULL && widget_to_call->m_event_handler != widget_to_call)
|
||||
widget_to_call = widget_to_call->m_event_handler;
|
||||
|
||||
if(widget_to_call->rightPressed())
|
||||
transmitEvent(widget_to_call, w->m_properties[PROP_ID]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PA_ACCEL:
|
||||
{
|
||||
IGUIElement *el, *first=NULL, *closest=NULL;
|
||||
el = GUIEngine::getGUIEnv()->getFocus();
|
||||
|
||||
Widget* w = (el == NULL) ? NULL : getWidget( el->getID() );
|
||||
|
||||
// list widgets are a bit special, because up/down keys are also used
|
||||
// to navigate between various list items, not only to navigate between
|
||||
// components
|
||||
if(w != NULL && w->m_type == WTYPE_LIST)
|
||||
{
|
||||
IGUIListBox* list = dynamic_cast<IGUIListBox*>(w->m_element);
|
||||
assert(list != NULL);
|
||||
if(list->getSelected()>0) break;
|
||||
}
|
||||
|
||||
if(el != NULL && el->getTabGroup() != NULL &&
|
||||
el->getTabGroup()->getNextElement(el->getTabOrder(), true, false, first, closest))
|
||||
{
|
||||
GUIEngine::getGUIEnv()->setFocus(closest);
|
||||
}
|
||||
else
|
||||
{
|
||||
// select the first widget
|
||||
Widget* w = getLastWidget();
|
||||
|
||||
if(w != NULL) GUIEngine::getGUIEnv()->setFocus( w->m_element );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PA_BRAKE:
|
||||
{
|
||||
IGUIElement *el, *first = NULL, *closest = NULL;
|
||||
el = GUIEngine::getGUIEnv()->getFocus();
|
||||
|
||||
Widget* w = (el == NULL) ? NULL : getWidget( el->getID() );
|
||||
|
||||
// list widgets are a bit special, because up/down keys are also used
|
||||
// to navigate between various list items, not only to navigate between
|
||||
// components
|
||||
if(w != NULL && w->m_type == WTYPE_LIST)
|
||||
{
|
||||
IGUIListBox* list = dynamic_cast<IGUIListBox*>(w->m_element);
|
||||
assert(list != NULL);
|
||||
if(list->getSelected() < (int)list->getItemCount()-1) break;
|
||||
}
|
||||
|
||||
if(el != NULL && el->getTabGroup() != NULL &&
|
||||
el->getTabGroup()->getNextElement(el->getTabOrder(), false, false, first, closest))
|
||||
{
|
||||
GUIEngine::getGUIEnv()->setFocus(closest);
|
||||
}
|
||||
else
|
||||
{
|
||||
// select the first widget
|
||||
Widget* w = getFirstWidget();
|
||||
if(w != NULL) GUIEngine::getGUIEnv()->setFocus( w->m_element );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PA_RESCUE:
|
||||
StateManager::escapePressed();
|
||||
break;
|
||||
|
||||
case PA_FIRE:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool Screen::OnEvent(const SEvent& event)
|
||||
{
|
||||
assert(transmitEvent != NULL);
|
||||
//if (event.EventType != EET_GUI_EVENT) return false;
|
||||
|
||||
|
||||
if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
|
||||
{
|
||||
const int key = event.KeyInput.Key;
|
||||
@@ -361,111 +487,21 @@ bool Screen::OnEvent(const SEvent& event)
|
||||
switch(key)
|
||||
{
|
||||
case KEY_ESCAPE :
|
||||
StateManager::escapePressed();
|
||||
break;
|
||||
|
||||
case KEY_SPACE :
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
{
|
||||
IGUIElement *el = GUIEngine::getGUIEnv()->getFocus();
|
||||
if(el == NULL) break;
|
||||
Widget* w = getWidget( el->getID() );
|
||||
if(w == NULL) break;
|
||||
|
||||
Widget* widget_to_call = w;
|
||||
|
||||
/* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall
|
||||
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
|
||||
notified of clicks onto themselves so they can toggle their state. ) */
|
||||
while(widget_to_call->m_event_handler != NULL && widget_to_call->m_event_handler != widget_to_call)
|
||||
widget_to_call = widget_to_call->m_event_handler;
|
||||
|
||||
if(widget_to_call->leftPressed())
|
||||
transmitEvent(w, w->m_properties[PROP_ID]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case KEY_RIGHT:
|
||||
{
|
||||
IGUIElement *el = GUIEngine::getGUIEnv()->getFocus();
|
||||
if(el == NULL) break;
|
||||
Widget* w = getWidget( el->getID() );
|
||||
if(w == NULL) break;
|
||||
|
||||
Widget* widget_to_call = w;
|
||||
/* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall
|
||||
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
|
||||
notified of clicks onto themselves so they can toggle their state. ) */
|
||||
while(widget_to_call->m_event_handler != NULL && widget_to_call->m_event_handler != widget_to_call)
|
||||
widget_to_call = widget_to_call->m_event_handler;
|
||||
|
||||
if(widget_to_call->rightPressed())
|
||||
transmitEvent(widget_to_call, w->m_properties[PROP_ID]);
|
||||
break;
|
||||
}
|
||||
case KEY_UP:
|
||||
{
|
||||
IGUIElement *el, *first=NULL, *closest=NULL;
|
||||
el = GUIEngine::getGUIEnv()->getFocus();
|
||||
|
||||
Widget* w = (el == NULL) ? NULL : getWidget( el->getID() );
|
||||
|
||||
// list widgets are a bit special, because up/down keys are also used
|
||||
// to navigate between various list items, not only to navigate between
|
||||
// components
|
||||
if(w != NULL && w->m_type == WTYPE_LIST)
|
||||
{
|
||||
IGUIListBox* list = dynamic_cast<IGUIListBox*>(w->m_element);
|
||||
assert(list != NULL);
|
||||
if(list->getSelected()>0) break;
|
||||
}
|
||||
|
||||
if(el != NULL && el->getTabGroup() != NULL &&
|
||||
el->getTabGroup()->getNextElement(el->getTabOrder(), true, false, first, closest))
|
||||
{
|
||||
GUIEngine::getGUIEnv()->setFocus(closest);
|
||||
}
|
||||
else
|
||||
{
|
||||
// select the first widget
|
||||
Widget* w = getLastWidget();
|
||||
|
||||
if(w != NULL) GUIEngine::getGUIEnv()->setFocus( w->m_element );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
{
|
||||
IGUIElement *el, *first = NULL, *closest = NULL;
|
||||
el = GUIEngine::getGUIEnv()->getFocus();
|
||||
|
||||
Widget* w = (el == NULL) ? NULL : getWidget( el->getID() );
|
||||
|
||||
// list widgets are a bit special, because up/down keys are also used
|
||||
// to navigate between various list items, not only to navigate between
|
||||
// components
|
||||
if(w != NULL && w->m_type == WTYPE_LIST)
|
||||
{
|
||||
IGUIListBox* list = dynamic_cast<IGUIListBox*>(w->m_element);
|
||||
assert(list != NULL);
|
||||
if(list->getSelected() < (int)list->getItemCount()-1) break;
|
||||
}
|
||||
|
||||
if(el != NULL && el->getTabGroup() != NULL &&
|
||||
el->getTabGroup()->getNextElement(el->getTabOrder(), false, false, first, closest))
|
||||
{
|
||||
GUIEngine::getGUIEnv()->setFocus(closest);
|
||||
}
|
||||
else
|
||||
{
|
||||
// select the first widget
|
||||
Widget* w = getFirstWidget();
|
||||
if(w != NULL) GUIEngine::getGUIEnv()->setFocus( w->m_element );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//std::cout << "key!" << std::endl;
|
||||
|
||||
@@ -52,6 +52,8 @@ namespace GUIEngine
|
||||
void elementsWereDeleted(ptr_vector<Widget>* within_vector = NULL);
|
||||
|
||||
virtual bool OnEvent(const SEvent& event);
|
||||
void processAction(const int action, const unsigned int value);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ bool DeviceManager::initGamePadSupport()
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
/**
|
||||
* Check if we already have a config object for joystick 'sdl_id' as reported by SDL
|
||||
* Check if we already have a config object for joystick 'irr_id' as reported by irrLicht
|
||||
* If yes, 'open' the gamepad. If no, create one. Returns whether a new gamepad was created.
|
||||
*/
|
||||
bool DeviceManager::checkForGamePad(const int irr_id)
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "karts/kart.hpp"
|
||||
#include "history.hpp"
|
||||
#include "gui/race_gui.hpp"
|
||||
#include "gui/screen.hpp"
|
||||
#include "sdl_manager.hpp"
|
||||
|
||||
InputManager *input_manager;
|
||||
@@ -186,7 +187,7 @@ InputManager::~InputManager()
|
||||
|
||||
|
||||
#define MAX_VALUE 32768
|
||||
|
||||
/*
|
||||
void InputManager::postIrrLichtMouseEvent(irr::EMOUSE_INPUT_EVENT type, const int x, const int y)
|
||||
{
|
||||
irr::SEvent::SMouseInput evt;
|
||||
@@ -201,7 +202,7 @@ void InputManager::postIrrLichtMouseEvent(irr::EMOUSE_INPUT_EVENT type, const in
|
||||
|
||||
GUIEngine::getDevice()->postEventFromUser(wrapper);
|
||||
}
|
||||
|
||||
*/
|
||||
// TODO - make this do something
|
||||
void InputManager::handleStaticAction(int key, int value)
|
||||
{
|
||||
@@ -291,7 +292,7 @@ void InputManager::input(Input::InputType type, int id0, int id1, int id2,
|
||||
|
||||
const bool action_found = m_device_manager->mapInputToPlayerAndAction( type, id0, id1, id2, value, &player, &action );
|
||||
|
||||
std::cout << "Input code=" << id0 << " found=" << action_found << std::endl;
|
||||
// std::cout << "Input code=" << id0 << " found=" << action_found << std::endl;
|
||||
|
||||
//GameAction ga = m_action_map->getEntry(type, id0, id1, id2);
|
||||
#if 0 // TODO - input sensing
|
||||
@@ -341,7 +342,28 @@ void InputManager::input(Input::InputType type, int id0, int id1, int id2,
|
||||
#endif
|
||||
if (action_found)
|
||||
{
|
||||
RaceManager::getWorld()->getLocalPlayerKart(player)->action(action, abs(value));
|
||||
if(StateManager::isGameState())
|
||||
RaceManager::getWorld()->getLocalPlayerKart(player)->action(action, abs(value));
|
||||
else
|
||||
{
|
||||
// reset timer when released
|
||||
if( abs(value) == 0 )
|
||||
{
|
||||
m_timer_in_use = false;
|
||||
m_timer = 0;
|
||||
}
|
||||
|
||||
// menu input
|
||||
if(!m_timer_in_use)
|
||||
{
|
||||
if(abs(value) > MAX_VALUE*2/3)
|
||||
{
|
||||
m_timer_in_use = true;
|
||||
m_timer = 0.25;
|
||||
}
|
||||
GUIEngine::getCurrentScreen()->processAction(action, abs(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == Input::IT_KEYBOARD)
|
||||
{
|
||||
@@ -351,17 +373,10 @@ void InputManager::input(Input::InputType type, int id0, int id1, int id2,
|
||||
} // input
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Reads the SDL event loop, does some tricks with certain values and calls
|
||||
* input() if appropriate.
|
||||
*
|
||||
* Digital inputs get the value of 32768 when pressed (key/button press,
|
||||
* digital axis) because this is what SDL provides. Relative mouse inputs
|
||||
* which do not fit into this scheme are converted to match. This is done to
|
||||
* relieve the KartAction implementor from the need to think about different
|
||||
* input devices and how SDL treats them. The same input gets the value of 0
|
||||
* when released.
|
||||
*
|
||||
* Analog axes can have any value from [0, 32768].
|
||||
/**
|
||||
* Called on keyboard events [indirectly] by irrLicht
|
||||
*
|
||||
* Analog axes can have any value from [-32768, 32767].
|
||||
*
|
||||
* There are no negative values. Instead this is reported as an axis with a
|
||||
* negative direction. This simplifies input configuration and allows greater
|
||||
@@ -370,16 +385,67 @@ void InputManager::input(Input::InputType type, int id0, int id1, int id2,
|
||||
*/
|
||||
void InputManager::input(const SEvent& event)
|
||||
{
|
||||
std::cout << "input event\n";
|
||||
|
||||
|
||||
if(event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
||||
{
|
||||
/*
|
||||
std::cout << "x=" << event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_X]
|
||||
<< " y=" << event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Y]
|
||||
<< " 1=" << event.JoystickEvent.IsButtonPressed(0)
|
||||
<< " 2=" << event.JoystickEvent.IsButtonPressed(1)
|
||||
<< " 3=" << event.JoystickEvent.IsButtonPressed(2)
|
||||
<< " 4=" << event.JoystickEvent.IsButtonPressed(3) << std::endl;
|
||||
*/
|
||||
// Axes - FIXME, instead of checking all of them, ask the bindings which to poll
|
||||
for(int axis_id=0; axis_id<SEvent::SJoystickEvent::NUMBER_OF_AXES ; axis_id++)
|
||||
{
|
||||
int value = event.JoystickEvent.Axis[axis_id];
|
||||
|
||||
// work around irrLicht bug. FIXME - get it fixed and remove this
|
||||
if(value == -32768) continue; // ignore bogus values given by irrlicht
|
||||
|
||||
if(user_config->m_gamepad_debug)
|
||||
{
|
||||
printf("axis motion: gamepad_id=%d axis=%d value=%d\n",
|
||||
event.JoystickEvent.Joystick, axis_id, value);
|
||||
}
|
||||
|
||||
// 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);
|
||||
else
|
||||
input(Input::IT_STICKMOTION, event.JoystickEvent.Joystick, axis_id, Input::AD_POSITIVE, value);
|
||||
}
|
||||
|
||||
/*
|
||||
case SDL_JOYAXISMOTION:
|
||||
{
|
||||
const int value = ev.jaxis.value;
|
||||
|
||||
if(user_config->m_gamepad_debug)
|
||||
{
|
||||
printf("axis motion: which=%d axis=%d value=%d\n",
|
||||
ev.jaxis.which, ev.jaxis.axis, value);
|
||||
}
|
||||
|
||||
// FIXME - AD_NEGATIVE/AD_POSITIVE are probably useless since value contains that info too
|
||||
if(value < 0)
|
||||
input(Input::IT_STICKMOTION, ev.jaxis.which, ev.jaxis.axis, Input::AD_NEGATIVE, value);
|
||||
else
|
||||
input(Input::IT_STICKMOTION, ev.jaxis.which, ev.jaxis.axis, Input::AD_POSITIVE, value);
|
||||
}
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
// See the SDL_JOYAXISMOTION case label because of !m_mode thingie.
|
||||
input(Input::IT_STICKBUTTON, ev.jbutton.which,
|
||||
ev.jbutton.button, 0, 0);
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
// See the SDL_JOYAXISMOTION case label because of !m_mode thingie.
|
||||
input(Input::IT_STICKBUTTON, ev.jbutton.which, ev.jbutton.button, 0, 32768);
|
||||
break;
|
||||
*/
|
||||
|
||||
}
|
||||
else if(event.EventType == EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ private:
|
||||
int m_mouse_val_x, m_mouse_val_y;
|
||||
|
||||
void input(Input::InputType, int, int, int, int);
|
||||
void postIrrLichtMouseEvent(irr::EMOUSE_INPUT_EVENT type, const int x, const int y);
|
||||
//void postIrrLichtMouseEvent(irr::EMOUSE_INPUT_EVENT type, const int x, const int y);
|
||||
void handleStaticAction(int id0, int value);
|
||||
void handlePlayerAction(PlayerAction pa, const int playerNo, int value);
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user