Improved assignment of mouse to which player (a few known glitches when game master uses a gamepad, but getting better overall)
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@4193 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -30,11 +30,13 @@ InputDevice* ActivePlayer::getDevice() const
|
||||
|
||||
void ActivePlayer::setDevice(InputDevice* device)
|
||||
{
|
||||
// unset player from previous device he was assigned to, if any
|
||||
if (m_device != NULL) m_device->setPlayer(NULL);
|
||||
|
||||
m_device = device;
|
||||
|
||||
if(device != NULL) device->setPlayer(this);
|
||||
// inform the devce of its new owner
|
||||
if (device != NULL) device->setPlayer(this);
|
||||
}
|
||||
|
||||
PlayerKart* ActivePlayer::getKart()
|
||||
|
||||
@@ -69,7 +69,7 @@ class ActivePlayer
|
||||
PlayerProfile* m_player;
|
||||
InputDevice* m_device;
|
||||
public:
|
||||
// ID of this player within the lsit of active players
|
||||
/** ID of this player within the list of active players */
|
||||
int m_id;
|
||||
|
||||
ActivePlayer(PlayerProfile* player, InputDevice* device);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace GUIEngine
|
||||
IVideoDriver* g_driver;
|
||||
Screen* g_current_screen = NULL;
|
||||
AbstractStateManager* g_state_manager = NULL;
|
||||
Widget* g_focus_for_player[MAX_PLAYER_COUNT]; // unused for player 0, player 0's focus is tracked by irrlicht
|
||||
Widget* g_focus_for_player[MAX_PLAYER_COUNT];
|
||||
}
|
||||
using namespace Private;
|
||||
|
||||
|
||||
@@ -97,16 +97,20 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event)
|
||||
{
|
||||
RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(w->m_event_handler);
|
||||
if (ribbon == NULL) break;
|
||||
const int playerID = 0; // FIXME : don't hardcode player 0
|
||||
if (ribbon->mouseHovered(w) == EVENT_LET) transmitEvent(ribbon, ribbon->m_properties[PROP_ID], playerID);
|
||||
if (ribbon->m_event_handler != NULL) ribbon->m_event_handler->mouseHovered(w);
|
||||
const int playerID = input_manager->getPlayerKeyboardID();
|
||||
if (playerID == -1) break;
|
||||
if (ribbon->mouseHovered(w, playerID) == EVENT_LET) transmitEvent(ribbon, ribbon->m_properties[PROP_ID], playerID);
|
||||
if (ribbon->m_event_handler != NULL) ribbon->m_event_handler->mouseHovered(w, playerID);
|
||||
ribbon->setFocusForPlayer(playerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// focus on hover for other widgets
|
||||
const int playerID = 0; // FIXME: don't hardcode player 0 ?
|
||||
w->setFocusForPlayer(playerID);
|
||||
const int playerID = input_manager->getPlayerKeyboardID();
|
||||
if (playerID != -1)
|
||||
{
|
||||
w->setFocusForPlayer(playerID);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -597,11 +597,11 @@ void Skin::drawRibbon(const core::rect< s32 > &rect, Widget* widget, const bool
|
||||
|
||||
void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused)
|
||||
{
|
||||
bool mark_selected = widget->isSelected();
|
||||
bool always_show_selection = false;
|
||||
|
||||
const int playerID = 0; // FIXME : don't hardcode player 0 ?
|
||||
|
||||
|
||||
bool mark_selected = widget->isSelected(playerID);
|
||||
bool always_show_selection = false;
|
||||
|
||||
IGUIElement* focusedElem = NULL;
|
||||
if (GUIEngine::getFocusForPlayer(playerID) != NULL)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@ Widget::Widget(bool reserve_id)
|
||||
id = -1;
|
||||
m_element = NULL;
|
||||
m_type = WTYPE_NONE;
|
||||
m_selected = false;
|
||||
|
||||
m_event_handler = NULL;
|
||||
m_show_bounding_box = false;
|
||||
m_parent = NULL;
|
||||
@@ -75,6 +75,7 @@ Widget::Widget(bool reserve_id)
|
||||
for (int n=0; n<MAX_PLAYER_COUNT; n++)
|
||||
{
|
||||
m_player_focus[n] = false;
|
||||
m_selected[n] = false;
|
||||
}
|
||||
|
||||
m_reserved_id = -1;
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace GUIEngine
|
||||
* - in widgets where it makes sense (e.g. ribbon children) and where the
|
||||
* irrLicht widget can not directly contain this state
|
||||
*/
|
||||
bool m_selected;
|
||||
bool m_selected[MAX_PLAYER_COUNT];
|
||||
|
||||
/**
|
||||
* called when left/right keys pressed and focus is on widget.
|
||||
@@ -119,7 +119,7 @@ namespace GUIEngine
|
||||
/** used when you set eventSupervisors - see m_event_handler explainations below
|
||||
called when one of a widget's children is hovered.
|
||||
Returns 'true' if main event handler should be notified of a change. */
|
||||
virtual EventPropagation mouseHovered(Widget* child) { return EVENT_BLOCK; }
|
||||
virtual EventPropagation mouseHovered(Widget* child, const int playerID) { return EVENT_BLOCK; }
|
||||
|
||||
/** override in children if you need to know when the widget is focused. return whether to block event */
|
||||
virtual EventPropagation focused(const int playerID) { setWithinATextBox(false); return EVENT_LET; }
|
||||
@@ -272,7 +272,7 @@ namespace GUIEngine
|
||||
virtual void move(const int x, const int y, const int w, const int h);
|
||||
|
||||
|
||||
bool isSelected() const { return m_selected; }
|
||||
bool isSelected(const int playerID) const { return m_selected[playerID]; }
|
||||
|
||||
bool isSameIrrlichtWidgetAs(const Widget* ref) const { return m_element == ref->m_element; }
|
||||
|
||||
|
||||
@@ -397,14 +397,13 @@ EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& orig
|
||||
return EVENT_LET;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child)
|
||||
EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child, const int playerID)
|
||||
{
|
||||
std::cout << "DynamicRibbonWidget::mouseHovered " << playerID << std::endl;
|
||||
|
||||
updateLabel();
|
||||
propagateSelection();
|
||||
|
||||
// FIXME: don't hardcode player 0
|
||||
const int playerID = 0;
|
||||
|
||||
if (getSelectedRibbon(playerID) != NULL)
|
||||
{
|
||||
const int listenerAmount = m_hover_listeners.size();
|
||||
|
||||
@@ -133,10 +133,10 @@ namespace GUIEngine
|
||||
int m_selected_item[MAX_PLAYER_COUNT];
|
||||
|
||||
/** Callbacks */
|
||||
void onRowChange(RibbonWidget* row, const int playerID);
|
||||
void add();
|
||||
EventPropagation mouseHovered(Widget* child);
|
||||
EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID);
|
||||
virtual void onRowChange(RibbonWidget* row, const int playerID);
|
||||
virtual void add();
|
||||
virtual EventPropagation mouseHovered(Widget* child, const int playerID);
|
||||
virtual EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
using namespace GUIEngine;
|
||||
using namespace irr::core;
|
||||
@@ -206,7 +207,7 @@ void RibbonWidget::add()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void RibbonWidget::select(std::string item, const int playerID)
|
||||
void RibbonWidget::select(std::string item, const int mousePlayerID)
|
||||
{
|
||||
const int subbuttons_amount = m_children.size();
|
||||
|
||||
@@ -214,7 +215,7 @@ void RibbonWidget::select(std::string item, const int playerID)
|
||||
{
|
||||
if (m_children[i].m_properties[PROP_ID] == item)
|
||||
{
|
||||
m_selection[playerID] = i;
|
||||
m_selection[mousePlayerID] = i;
|
||||
updateSelection();
|
||||
return;
|
||||
}
|
||||
@@ -236,8 +237,14 @@ EventPropagation RibbonWidget::rightPressed(const int playerID)
|
||||
}
|
||||
updateSelection();
|
||||
|
||||
// FIXME: don't hardcode player ID 0
|
||||
if (playerID == 0) m_mouse_focus = m_children.get(m_selection[playerID]);
|
||||
if (m_ribbon_type == RIBBON_COMBO)
|
||||
{
|
||||
const int mousePlayerID = input_manager->getPlayerKeyboardID();
|
||||
if (playerID == mousePlayerID)
|
||||
{
|
||||
m_mouse_focus = m_children.get(m_selection[mousePlayerID]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ribbon_type != RIBBON_TOOLBAR)
|
||||
{
|
||||
@@ -264,8 +271,14 @@ EventPropagation RibbonWidget::leftPressed(const int playerID)
|
||||
}
|
||||
updateSelection();
|
||||
|
||||
// FIXME: don't hardcode player ID
|
||||
if (playerID == 0) m_mouse_focus = m_children.get(m_selection[playerID]);
|
||||
if (m_ribbon_type == RIBBON_COMBO)
|
||||
{
|
||||
const int mousePlayerID = input_manager->getPlayerKeyboardID();
|
||||
if (playerID == mousePlayerID)
|
||||
{
|
||||
m_mouse_focus = m_children.get(m_selection[mousePlayerID]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ribbon_type != RIBBON_TOOLBAR)
|
||||
{
|
||||
@@ -284,10 +297,13 @@ EventPropagation RibbonWidget::focused(const int playerID)
|
||||
|
||||
if (m_children.size() < 1) return EVENT_LET; // empty ribbon
|
||||
|
||||
// FIXME: don't hardcode player ID 0
|
||||
if (m_mouse_focus == NULL && m_selection[playerID] != -1 && playerID == 0)
|
||||
if (m_ribbon_type == RIBBON_COMBO)
|
||||
{
|
||||
m_mouse_focus = m_children.get(m_selection[playerID]);
|
||||
const int mousePlayerID = input_manager->getPlayerKeyboardID();
|
||||
if (m_mouse_focus == NULL && m_selection[playerID] != -1 && playerID == mousePlayerID)
|
||||
{
|
||||
m_mouse_focus = m_children.get(m_selection[playerID]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_event_handler != NULL)
|
||||
@@ -301,22 +317,31 @@ EventPropagation RibbonWidget::focused(const int playerID)
|
||||
return EVENT_LET;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
EventPropagation RibbonWidget::mouseHovered(Widget* child)
|
||||
EventPropagation RibbonWidget::mouseHovered(Widget* child, const int mousePlayerID)
|
||||
{
|
||||
std::cout << "RibbonWidget::mouseHovered " << mousePlayerID << std::endl;
|
||||
const int subbuttons_amount = m_children.size();
|
||||
|
||||
m_mouse_focus = child;
|
||||
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
if (m_ribbon_type == RIBBON_COMBO)
|
||||
{
|
||||
if (m_children.get(i) == child)
|
||||
std::cout << "SETTING m_mouse_focus\n";
|
||||
m_mouse_focus = child;
|
||||
}
|
||||
|
||||
// In toolbar ribbons, hovering selects
|
||||
if (m_ribbon_type == RIBBON_TOOLBAR)
|
||||
{
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
{
|
||||
// FIXME: don't hardcode player 0 there?
|
||||
if (m_selection[0] == i) return EVENT_BLOCK; // was already selected, don't send another event
|
||||
if (m_ribbon_type == RIBBON_TOOLBAR) m_selection[0] = i; // don't change selection on hover for others
|
||||
break;
|
||||
if (m_children.get(i) == child)
|
||||
{
|
||||
if (m_selection[mousePlayerID] == i) return EVENT_BLOCK; // was already selected, don't send another event
|
||||
m_selection[mousePlayerID] = i; // don't change selection on hover for others
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSelection();
|
||||
return EVENT_BLOCK;
|
||||
}
|
||||
@@ -334,14 +359,37 @@ void RibbonWidget::updateSelection()
|
||||
{
|
||||
const int subbuttons_amount = m_children.size();
|
||||
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
// FIXME: m_selection, m_selected, m_mouse_focus... what a mess...
|
||||
|
||||
//std::cout << "----\n";
|
||||
// Update selection flags for mouse player
|
||||
for (int p=0; p<MAX_PLAYER_COUNT; p++)
|
||||
{
|
||||
// Player 0 selection
|
||||
m_children[i].m_selected = (i == m_selection[0]);
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
{
|
||||
m_children[i].m_selected[p] = (i == m_selection[p]);
|
||||
|
||||
/*
|
||||
if (m_children[i].m_selected[p])
|
||||
std::cout << "m_children[" << i << "].m_selected[" << p << "] = " << m_children[i].m_selected[p] << std::endl;
|
||||
if (p == 0 && m_children.get(i) == m_mouse_focus)
|
||||
std::cout << "m_children[" << i << "] is mouse focus" << std::endl;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: don't hardcode player 0
|
||||
if (subbuttons_amount > 0 && m_ribbon_type == RIBBON_TOOLBAR) m_mouse_focus = m_children.get(m_selection[0]);
|
||||
// Update the 'mouse focus' if necessary
|
||||
/*
|
||||
if (subbuttons_amount > 0 && m_ribbon_type == RIBBON_COMBO)
|
||||
{
|
||||
const int mousePlayerID = input_manager->getPlayerKeyboardID();
|
||||
if (mousePlayerID != -1 && m_selection[mousePlayerID] != -1)
|
||||
{
|
||||
m_mouse_focus = m_children.get(m_selection[mousePlayerID]);
|
||||
std::cout << "RESET mouse focus\n";
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
EventPropagation RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
|
||||
|
||||
@@ -53,18 +53,18 @@ namespace GUIEngine
|
||||
void updateSelection();
|
||||
|
||||
/** Callbacks */
|
||||
EventPropagation rightPressed(const int playerID=0);
|
||||
EventPropagation leftPressed(const int playerID=0);
|
||||
EventPropagation mouseHovered(Widget* child);
|
||||
EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID=0);
|
||||
EventPropagation focused(const int playerID);
|
||||
virtual EventPropagation rightPressed(const int playerID=0);
|
||||
virtual EventPropagation leftPressed(const int playerID=0);
|
||||
virtual EventPropagation mouseHovered(Widget* child, const int playerID);
|
||||
virtual EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID=0);
|
||||
virtual EventPropagation focused(const int playerID);
|
||||
|
||||
ptr_vector<irr::gui::IGUIStaticText, REF> m_labels;
|
||||
|
||||
public:
|
||||
|
||||
/** Contains which element within the ribbon is currently focused (used by the skin to
|
||||
show mouse hovers over items that are not selected) */
|
||||
/** Contains which element within the ribbon is currently focused by player 0 (used by the skin to
|
||||
show mouse hovers over items that are not selected). Only used for COMBO ribbons. */
|
||||
Widget* m_mouse_focus;
|
||||
|
||||
RibbonWidget(const RibbonType type=RIBBON_COMBO);
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
GamePadDevice* getGamePad(const int i) { return m_gamepads.get(i); }
|
||||
GamepadConfig* getGamepadConfig(const int i) { return m_gamepad_configs.get(i); }
|
||||
PlayerAssignMode playerAssignMode() const { return m_assign_mode; }
|
||||
KeyboardDevice* getKeyboard(const int i) { return m_keyboard; }
|
||||
KeyboardDevice* getKeyboard() { return m_keyboard; }
|
||||
PlayerAssignMode getAssignMode() { return m_assign_mode; }
|
||||
GamePadDevice* getGamePadFromIrrID(const int i);
|
||||
InputDevice* getLatestUsedDevice();
|
||||
|
||||
@@ -22,6 +22,11 @@ void InputDevice::setPlayer(ActivePlayer* owner)
|
||||
m_player = owner;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark Keyboard
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
KeyboardDevice::KeyboardDevice(KeyboardConfig *configuration)
|
||||
{
|
||||
@@ -48,7 +53,7 @@ bool KeyboardDevice::hasBinding(const int id, PlayerAction* action)
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark gamepad
|
||||
#pragma mark Gamepad
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -221,7 +221,22 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
|
||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int InputManager::getPlayerKeyboardID() const
|
||||
{
|
||||
// In no-assign mode, just return the GUI player ID (devices not assigned yet)
|
||||
if (m_device_manager->playerAssignMode() == NO_ASSIGN) return GUI_PLAYER_ID;
|
||||
|
||||
// Otherwise, after devices are assigned, we can check the ID
|
||||
if (m_device_manager->getKeyboard() != NULL)
|
||||
{
|
||||
if (m_device_manager->getKeyboard()->getPlayer() != NULL)
|
||||
{
|
||||
return m_device_manager->getKeyboard()->getPlayer()->m_id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Handles the conversion from some input to a GameAction and its distribution
|
||||
* to the currently active menu.
|
||||
@@ -302,9 +317,13 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID, int btnID,
|
||||
{
|
||||
InputDevice *device = NULL;
|
||||
if (type == Input::IT_KEYBOARD)
|
||||
device = m_device_manager->getKeyboard(0);
|
||||
{
|
||||
device = m_device_manager->getKeyboard();
|
||||
}
|
||||
else if (type == Input::IT_STICKBUTTON || type == Input::IT_STICKMOTION)
|
||||
{
|
||||
device = m_device_manager->getGamePadFromIrrID(deviceID);
|
||||
}
|
||||
|
||||
if (device != NULL)
|
||||
{
|
||||
|
||||
@@ -60,8 +60,7 @@ private:
|
||||
* axis which was pushed the furthest when sensing input. */
|
||||
int m_max_sensed_input;
|
||||
Input::InputType m_max_sensed_type;
|
||||
//ActionMap *m_action_map;
|
||||
//GamePadDevice **m_stick_infos;
|
||||
|
||||
InputDriverMode m_mode;
|
||||
|
||||
/* Helper values to store and track the relative mouse movements. If these
|
||||
@@ -89,7 +88,8 @@ public:
|
||||
|
||||
void update(float dt);
|
||||
|
||||
//Input &getSensedInput();
|
||||
/** Returns the ID of the player that plays with the keyboard, or -1 if none */
|
||||
int getPlayerKeyboardID() const;
|
||||
};
|
||||
|
||||
extern InputManager *input_manager;
|
||||
|
||||
@@ -633,7 +633,7 @@ int main(int argc, char *argv[] )
|
||||
InputDevice *device;
|
||||
|
||||
// Use keyboard by default in --no-start-screen
|
||||
device = input_manager->getDeviceList()->getKeyboard(0);
|
||||
device = input_manager->getDeviceList()->getKeyboard();
|
||||
|
||||
// Create player and associate player with keyboard
|
||||
StateManager::get()->createActivePlayer( UserConfigParams::m_all_players.get(0), device );
|
||||
|
||||
@@ -161,7 +161,7 @@ void OptionsScreenInput::gotSensedInput(Input* sensedInput)
|
||||
{
|
||||
std::cout << "% Binding " << KartActionStrings[binding_to_set] << " : setting to keyboard key " << sensedInput->btnID << " \n\n";
|
||||
|
||||
KeyboardDevice* keyboard = input_manager->getDeviceList()->getKeyboard(0);
|
||||
KeyboardDevice* keyboard = input_manager->getDeviceList()->getKeyboard();
|
||||
keyboard->getConfiguration()->setBinding(binding_to_set, Input::IT_KEYBOARD, sensedInput->btnID, Input::AD_NEUTRAL);
|
||||
|
||||
// refresh display
|
||||
@@ -273,7 +273,7 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
}
|
||||
else if(selection == "keyboard")
|
||||
{
|
||||
updateInputButtons( input_manager->getDeviceList()->getKeyboard(0)->getConfiguration() );
|
||||
updateInputButtons( input_manager->getDeviceList()->getKeyboard()->getConfiguration() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user