Added support for multitouch steering.
It will be used for steering on Android. There are some limitations: - currently it works only in single player mode (but I don't see any reason to make it working for multiplayer) - speedometer is not available in race GUI because there is no place for it TODO: - add DPI support (race GUI should have probably different proportions on smaller devices for comfortable playing) - make nice button images - make nitro button that changes its look depending on collected nitro (a kind of nitro bar) Touch input events must be handled in android device to make use of it. It can be simulated for debugging on non-android devices using standard mouse.
This commit is contained in:
parent
78c1c5e14a
commit
4bb0405a32
@ -34,8 +34,8 @@ namespace irr
|
|||||||
IrrlichtDevice::postEventFromUser. They take the same path as mouse events. */
|
IrrlichtDevice::postEventFromUser. They take the same path as mouse events. */
|
||||||
EET_KEY_INPUT_EVENT,
|
EET_KEY_INPUT_EVENT,
|
||||||
|
|
||||||
//! A multi touch event.
|
//! A touch input event.
|
||||||
EET_MULTI_TOUCH_EVENT,
|
EET_TOUCH_INPUT_EVENT,
|
||||||
|
|
||||||
//! A accelerometer event.
|
//! A accelerometer event.
|
||||||
EET_ACCELEROMETER_EVENT,
|
EET_ACCELEROMETER_EVENT,
|
||||||
@ -177,22 +177,19 @@ namespace irr
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Enumeration for all touch input events
|
//! Enumeration for all touch input events
|
||||||
enum EMULTI_TOUCH_INPUT_EVENT
|
enum ETOUCH_INPUT_EVENT
|
||||||
{
|
{
|
||||||
//! Max multi touch count
|
|
||||||
NUMBER_OF_MULTI_TOUCHES = 10,
|
|
||||||
|
|
||||||
//! Touch was pressed down.
|
//! Touch was pressed down.
|
||||||
EMTIE_PRESSED_DOWN = 0,
|
ETIE_PRESSED_DOWN = 0,
|
||||||
|
|
||||||
//! Touch was left up.
|
//! Touch was left up.
|
||||||
EMTIE_LEFT_UP,
|
ETIE_LEFT_UP,
|
||||||
|
|
||||||
//! The touch changed its position.
|
//! The touch changed its position.
|
||||||
EMTIE_MOVED,
|
ETIE_MOVED,
|
||||||
|
|
||||||
//! No real event. Just for convenience to get number of events
|
//! No real event. Just for convenience to get number of events
|
||||||
EMTIE_COUNT
|
ETIE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace gui
|
namespace gui
|
||||||
@ -384,55 +381,23 @@ struct SEvent
|
|||||||
bool Control:1;
|
bool Control:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Any kind of multi touch event.
|
//! Any kind of touch event.
|
||||||
struct SMultiTouchInput
|
struct STouchInput
|
||||||
{
|
{
|
||||||
//! A helper function to check if a button is pressed.
|
// Touch ID.
|
||||||
u32 touchedCount() const
|
size_t ID;
|
||||||
{
|
|
||||||
u32 count = 0;
|
|
||||||
|
|
||||||
for (u16 i = 0; i < NUMBER_OF_MULTI_TOUCHES; ++i)
|
|
||||||
{
|
|
||||||
if (Touched[i])
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Reset variables.
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
for (u16 i = 0; i < NUMBER_OF_MULTI_TOUCHES; ++i)
|
|
||||||
{
|
|
||||||
Touched[i] = 0;
|
|
||||||
X[i] = 0;
|
|
||||||
Y[i] = 0;
|
|
||||||
PrevX[i] = 0;
|
|
||||||
PrevY[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status of simple touch.
|
|
||||||
u8 Touched[NUMBER_OF_MULTI_TOUCHES];
|
|
||||||
|
|
||||||
// X position of simple touch.
|
// X position of simple touch.
|
||||||
s32 X[NUMBER_OF_MULTI_TOUCHES];
|
s32 X;
|
||||||
|
|
||||||
// Y position of simple touch.
|
// Y position of simple touch.
|
||||||
s32 Y[NUMBER_OF_MULTI_TOUCHES];
|
s32 Y;
|
||||||
|
|
||||||
// Previous X position of simple touch.
|
//! Type of touch event.
|
||||||
s32 PrevX[NUMBER_OF_MULTI_TOUCHES];
|
ETOUCH_INPUT_EVENT Event;
|
||||||
|
|
||||||
// Previous Y position of simple touch.
|
|
||||||
s32 PrevY[NUMBER_OF_MULTI_TOUCHES];
|
|
||||||
|
|
||||||
//! Type of multi touch event
|
|
||||||
EMULTI_TOUCH_INPUT_EVENT Event;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! Any kind of accelerometer event.
|
//! Any kind of accelerometer event.
|
||||||
struct SAccelerometerEvent
|
struct SAccelerometerEvent
|
||||||
{
|
{
|
||||||
@ -575,7 +540,7 @@ struct SEvent
|
|||||||
struct SGUIEvent GUIEvent;
|
struct SGUIEvent GUIEvent;
|
||||||
struct SMouseInput MouseInput;
|
struct SMouseInput MouseInput;
|
||||||
struct SKeyInput KeyInput;
|
struct SKeyInput KeyInput;
|
||||||
struct SMultiTouchInput MultiTouchInput;
|
struct STouchInput TouchInput;
|
||||||
struct SAccelerometerEvent AccelerometerEvent;
|
struct SAccelerometerEvent AccelerometerEvent;
|
||||||
struct SGyroscopeEvent GyroscopeEvent;
|
struct SGyroscopeEvent GyroscopeEvent;
|
||||||
struct SDeviceMotionEvent DeviceMotionEvent;
|
struct SDeviceMotionEvent DeviceMotionEvent;
|
||||||
|
@ -389,6 +389,28 @@ namespace UserConfigParams
|
|||||||
&m_wiimote_group,
|
&m_wiimote_group,
|
||||||
"A weight applied to the sin component of mapping wiimote angle to steering angle"));
|
"A weight applied to the sin component of mapping wiimote angle to steering angle"));
|
||||||
|
|
||||||
|
// ---- Multitouch device
|
||||||
|
PARAM_PREFIX GroupUserConfigParam m_multitouch_group
|
||||||
|
PARAM_DEFAULT( GroupUserConfigParam("Multitouch",
|
||||||
|
"Settings for the multitouch device") );
|
||||||
|
|
||||||
|
PARAM_PREFIX BoolUserConfigParam m_multitouch_enabled
|
||||||
|
PARAM_DEFAULT( BoolUserConfigParam(false, "multitouch_enabled",
|
||||||
|
&m_multitouch_group,
|
||||||
|
"Enable multitouch support.") );
|
||||||
|
|
||||||
|
PARAM_PREFIX FloatUserConfigParam m_multitouch_deadzone_center
|
||||||
|
PARAM_DEFAULT( FloatUserConfigParam(0.15f, "multitouch_deadzone_center",
|
||||||
|
&m_multitouch_group,
|
||||||
|
"A parameter in range [0, 0.5] that determines the zone that is "
|
||||||
|
"considered as centered in steering button."));
|
||||||
|
|
||||||
|
PARAM_PREFIX FloatUserConfigParam m_multitouch_deadzone_edge
|
||||||
|
PARAM_DEFAULT( FloatUserConfigParam(0.15f, "multitouch_deadzone_edge",
|
||||||
|
&m_multitouch_group,
|
||||||
|
"A parameter in range [0, 0.5] that determines the zone that is "
|
||||||
|
"considered as max value in steering button."));
|
||||||
|
|
||||||
// ---- GP start order
|
// ---- GP start order
|
||||||
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
|
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
|
||||||
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
|
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
|
||||||
|
@ -144,6 +144,35 @@ bool EventHandler::OnEvent (const SEvent &event)
|
|||||||
DemoWorld::resetIdleTime();
|
DemoWorld::resetIdleTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simulate mouse event for first finger on multitouch device.
|
||||||
|
// This allows to click on GUI elements.
|
||||||
|
if (event.EventType == EET_TOUCH_INPUT_EVENT)
|
||||||
|
{
|
||||||
|
if (event.TouchInput.ID == 0)
|
||||||
|
{
|
||||||
|
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
|
||||||
|
{
|
||||||
|
SEvent irrevent;
|
||||||
|
irrevent.EventType = EET_MOUSE_INPUT_EVENT;
|
||||||
|
irrevent.MouseInput.X = event.TouchInput.X;
|
||||||
|
irrevent.MouseInput.Y = event.TouchInput.Y;
|
||||||
|
irrevent.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN;
|
||||||
|
|
||||||
|
irr_driver->getDevice()->postEventFromUser(irrevent);
|
||||||
|
}
|
||||||
|
else if (event.TouchInput.Event == ETIE_LEFT_UP)
|
||||||
|
{
|
||||||
|
SEvent irrevent;
|
||||||
|
irrevent.EventType = EET_MOUSE_INPUT_EVENT;
|
||||||
|
irrevent.MouseInput.X = event.TouchInput.X;
|
||||||
|
irrevent.MouseInput.Y = event.TouchInput.Y;
|
||||||
|
irrevent.MouseInput.Event = EMIE_LMOUSE_LEFT_UP;
|
||||||
|
|
||||||
|
irr_driver->getDevice()->postEventFromUser(irrevent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (event.EventType == EET_GUI_EVENT)
|
if (event.EventType == EET_GUI_EVENT)
|
||||||
{
|
{
|
||||||
return onGUIEvent(event) == EVENT_BLOCK;
|
return onGUIEvent(event) == EVENT_BLOCK;
|
||||||
@ -155,6 +184,7 @@ bool EventHandler::OnEvent (const SEvent &event)
|
|||||||
return false; // EVENT_LET
|
return false; // EVENT_LET
|
||||||
}
|
}
|
||||||
else if (event.EventType == EET_MOUSE_INPUT_EVENT ||
|
else if (event.EventType == EET_MOUSE_INPUT_EVENT ||
|
||||||
|
event.EventType == EET_TOUCH_INPUT_EVENT ||
|
||||||
event.EventType == EET_KEY_INPUT_EVENT ||
|
event.EventType == EET_KEY_INPUT_EVENT ||
|
||||||
event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "input/gamepad_device.hpp"
|
#include "input/gamepad_device.hpp"
|
||||||
#include "input/keyboard_device.hpp"
|
#include "input/keyboard_device.hpp"
|
||||||
|
#include "input/multitouch_device.hpp"
|
||||||
#include "input/wiimote_manager.hpp"
|
#include "input/wiimote_manager.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "states_screens/kart_selection.hpp"
|
#include "states_screens/kart_selection.hpp"
|
||||||
@ -43,6 +44,7 @@ DeviceManager::DeviceManager()
|
|||||||
m_latest_used_device = NULL;
|
m_latest_used_device = NULL;
|
||||||
m_assign_mode = NO_ASSIGN;
|
m_assign_mode = NO_ASSIGN;
|
||||||
m_single_player = NULL;
|
m_single_player = NULL;
|
||||||
|
m_multitouch_device = NULL;
|
||||||
} // DeviceManager
|
} // DeviceManager
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -138,6 +140,11 @@ bool DeviceManager::initialize()
|
|||||||
addGamepad(gamepadDevice);
|
addGamepad(gamepadDevice);
|
||||||
} // end for
|
} // end for
|
||||||
|
|
||||||
|
if (UserConfigParams::m_multitouch_enabled)
|
||||||
|
{
|
||||||
|
m_multitouch_device = new MultitouchDevice();
|
||||||
|
}
|
||||||
|
|
||||||
if (created) save();
|
if (created) save();
|
||||||
|
|
||||||
return created;
|
return created;
|
||||||
@ -154,6 +161,12 @@ void DeviceManager::clearGamepads()
|
|||||||
{
|
{
|
||||||
m_gamepads.clearAndDeleteAll();
|
m_gamepads.clearAndDeleteAll();
|
||||||
} // clearGamepads
|
} // clearGamepads
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
void DeviceManager::clearMultitouchDevices()
|
||||||
|
{
|
||||||
|
delete m_multitouch_device;
|
||||||
|
m_multitouch_device = NULL;
|
||||||
|
} // clearMultitouchDevices
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
void DeviceManager::setAssignMode(const PlayerAssignMode assignMode)
|
void DeviceManager::setAssignMode(const PlayerAssignMode assignMode)
|
||||||
@ -177,6 +190,9 @@ void DeviceManager::setAssignMode(const PlayerAssignMode assignMode)
|
|||||||
{
|
{
|
||||||
m_keyboards[i].setPlayer(NULL);
|
m_keyboards[i].setPlayer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_multitouch_device != NULL)
|
||||||
|
m_multitouch_device->setPlayer(NULL);
|
||||||
}
|
}
|
||||||
} // setAssignMode
|
} // setAssignMode
|
||||||
|
|
||||||
@ -391,6 +407,25 @@ InputDevice *DeviceManager::mapGamepadInput(Input::InputType type,
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DeviceManager::updateMultitouchDevice()
|
||||||
|
{
|
||||||
|
if (m_multitouch_device == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_single_player != NULL)
|
||||||
|
{
|
||||||
|
// in single-player mode, assign the gamepad as needed
|
||||||
|
if (m_multitouch_device->getPlayer() != m_single_player)
|
||||||
|
m_multitouch_device->setPlayer(m_single_player);
|
||||||
|
}
|
||||||
|
else if (m_assign_mode == NO_ASSIGN) // Don't set the player in NO_ASSIGN mode
|
||||||
|
{
|
||||||
|
m_multitouch_device->setPlayer(NULL);
|
||||||
|
}
|
||||||
|
} // updateMultitouchDevice
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool DeviceManager::translateInput( Input::InputType type,
|
bool DeviceManager::translateInput( Input::InputType type,
|
||||||
int device_id,
|
int device_id,
|
||||||
int button_id,
|
int button_id,
|
||||||
@ -604,5 +639,7 @@ void DeviceManager::shutdown()
|
|||||||
m_keyboards.clearAndDeleteAll();
|
m_keyboards.clearAndDeleteAll();
|
||||||
m_gamepad_configs.clearAndDeleteAll();
|
m_gamepad_configs.clearAndDeleteAll();
|
||||||
m_keyboard_configs.clearAndDeleteAll();
|
m_keyboard_configs.clearAndDeleteAll();
|
||||||
|
delete m_multitouch_device;
|
||||||
|
m_multitouch_device = NULL;
|
||||||
m_latest_used_device = NULL;
|
m_latest_used_device = NULL;
|
||||||
} // shutdown
|
} // shutdown
|
||||||
|
@ -34,6 +34,7 @@ class DeviceConfig;
|
|||||||
class InputDevice;
|
class InputDevice;
|
||||||
class GamePadDevice;
|
class GamePadDevice;
|
||||||
class KeyboardDevice;
|
class KeyboardDevice;
|
||||||
|
class MultitouchDevice;
|
||||||
|
|
||||||
|
|
||||||
enum PlayerAssignMode
|
enum PlayerAssignMode
|
||||||
@ -66,6 +67,7 @@ private:
|
|||||||
PtrVector<GamePadDevice, HOLD> m_gamepads;
|
PtrVector<GamePadDevice, HOLD> m_gamepads;
|
||||||
PtrVector<KeyboardConfig, HOLD> m_keyboard_configs;
|
PtrVector<KeyboardConfig, HOLD> m_keyboard_configs;
|
||||||
PtrVector<GamepadConfig, HOLD> m_gamepad_configs;
|
PtrVector<GamepadConfig, HOLD> m_gamepad_configs;
|
||||||
|
MultitouchDevice* m_multitouch_device;
|
||||||
|
|
||||||
/** The list of all joysticks that were found and activated. */
|
/** The list of all joysticks that were found and activated. */
|
||||||
core::array<SJoystickInfo> m_irrlicht_gamepads;
|
core::array<SJoystickInfo> m_irrlicht_gamepads;
|
||||||
@ -129,6 +131,11 @@ public:
|
|||||||
KeyboardConfig* getKeyboardConfig(const int i) { return m_keyboard_configs.get(i); }
|
KeyboardConfig* getKeyboardConfig(const int i) { return m_keyboard_configs.get(i); }
|
||||||
KeyboardDevice* getKeyboardFromBtnID(const int btnID);
|
KeyboardDevice* getKeyboardFromBtnID(const int btnID);
|
||||||
|
|
||||||
|
// ---- Multitouch device ----
|
||||||
|
MultitouchDevice* getMultitouchDevice() { return m_multitouch_device; }
|
||||||
|
void clearMultitouchDevices();
|
||||||
|
void updateMultitouchDevice();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Delete the given config and removes DeviceManager references to it.
|
* \brief Delete the given config and removes DeviceManager references to it.
|
||||||
|
@ -36,7 +36,8 @@ class DeviceConfig;
|
|||||||
enum DeviceType
|
enum DeviceType
|
||||||
{
|
{
|
||||||
DT_KEYBOARD,
|
DT_KEYBOARD,
|
||||||
DT_GAMEPAD
|
DT_GAMEPAD,
|
||||||
|
DT_MULTITOUCH
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "input/device_manager.hpp"
|
#include "input/device_manager.hpp"
|
||||||
#include "input/gamepad_device.hpp"
|
#include "input/gamepad_device.hpp"
|
||||||
#include "input/keyboard_device.hpp"
|
#include "input/keyboard_device.hpp"
|
||||||
|
#include "input/multitouch_device.hpp"
|
||||||
#include "input/input.hpp"
|
#include "input/input.hpp"
|
||||||
#include "karts/controller/controller.hpp"
|
#include "karts/controller/controller.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
@ -1014,6 +1015,30 @@ EventPropagation InputManager::input(const SEvent& event)
|
|||||||
return EVENT_BLOCK; // Don't propagate key up events
|
return EVENT_BLOCK; // Don't propagate key up events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event.EventType == EET_TOUCH_INPUT_EVENT)
|
||||||
|
{
|
||||||
|
MultitouchDevice* device = m_device_manager->getMultitouchDevice();
|
||||||
|
unsigned int id = event.TouchInput.ID;
|
||||||
|
|
||||||
|
if (device != NULL && id < device->m_events.size())
|
||||||
|
{
|
||||||
|
device->m_events[id].id = id;
|
||||||
|
device->m_events[id].x = event.TouchInput.X;
|
||||||
|
device->m_events[id].y = event.TouchInput.Y;
|
||||||
|
|
||||||
|
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
|
||||||
|
{
|
||||||
|
device->m_events[id].touched = true;
|
||||||
|
}
|
||||||
|
else if (event.TouchInput.Event == ETIE_LEFT_UP)
|
||||||
|
{
|
||||||
|
device->m_events[id].touched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_device_manager->updateMultitouchDevice();
|
||||||
|
device->updateDeviceState(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Use the mouse to change the looking direction when first person view is activated
|
// Use the mouse to change the looking direction when first person view is activated
|
||||||
else if (event.EventType == EET_MOUSE_INPUT_EVENT)
|
else if (event.EventType == EET_MOUSE_INPUT_EVENT)
|
||||||
{
|
{
|
||||||
@ -1096,6 +1121,35 @@ EventPropagation InputManager::input(const SEvent& event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simulate touch event on non-android devices
|
||||||
|
#if !defined(ANDROID)
|
||||||
|
if (UserConfigParams::m_multitouch_enabled == true &&
|
||||||
|
(type == EMIE_LMOUSE_PRESSED_DOWN || type == EMIE_LMOUSE_LEFT_UP ||
|
||||||
|
type == EMIE_MOUSE_MOVED))
|
||||||
|
{
|
||||||
|
MultitouchDevice* device = m_device_manager->getMultitouchDevice();
|
||||||
|
|
||||||
|
if (device != NULL)
|
||||||
|
{
|
||||||
|
device->m_events[0].id = 0;
|
||||||
|
device->m_events[0].x = event.MouseInput.X;
|
||||||
|
device->m_events[0].y = event.MouseInput.Y;
|
||||||
|
|
||||||
|
if (type == EMIE_LMOUSE_PRESSED_DOWN)
|
||||||
|
{
|
||||||
|
device->m_events[0].touched = true;
|
||||||
|
}
|
||||||
|
else if (type == EMIE_LMOUSE_LEFT_UP)
|
||||||
|
{
|
||||||
|
device->m_events[0].touched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_device_manager->updateMultitouchDevice();
|
||||||
|
device->updateDeviceState(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
EMIE_LMOUSE_PRESSED_DOWN Left mouse button was pressed down.
|
EMIE_LMOUSE_PRESSED_DOWN Left mouse button was pressed down.
|
||||||
EMIE_RMOUSE_PRESSED_DOWN Right mouse button was pressed down.
|
EMIE_RMOUSE_PRESSED_DOWN Right mouse button was pressed down.
|
||||||
|
306
src/input/multitouch_device.cpp
Normal file
306
src/input/multitouch_device.cpp
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2013-2015 SuperTuxKart-Team
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License: or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "config/user_config.hpp"
|
||||||
|
#include "input/multitouch_device.hpp"
|
||||||
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "karts/controller/controller.hpp"
|
||||||
|
#include "graphics/irr_driver.hpp"
|
||||||
|
#include "guiengine/modaldialog.hpp"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** The multitouch device constructor
|
||||||
|
*/
|
||||||
|
MultitouchDevice::MultitouchDevice()
|
||||||
|
{
|
||||||
|
m_configuration = NULL;
|
||||||
|
m_type = DT_MULTITOUCH;
|
||||||
|
m_name = "Multitouch";
|
||||||
|
m_player = NULL;
|
||||||
|
|
||||||
|
for (MultitouchEvent& event : m_events)
|
||||||
|
{
|
||||||
|
event.id = 0;
|
||||||
|
event.touched = false;
|
||||||
|
event.x = 0;
|
||||||
|
event.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_deadzone_center = UserConfigParams::m_multitouch_deadzone_center;
|
||||||
|
m_deadzone_center = std::min(std::max(m_deadzone_center, 0.0f), 0.5f);
|
||||||
|
|
||||||
|
m_deadzone_edge = UserConfigParams::m_multitouch_deadzone_edge;
|
||||||
|
m_deadzone_edge = std::min(std::max(m_deadzone_edge, 0.0f), 0.5f);
|
||||||
|
} // MultitouchDevice
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** The multitouch device destructor
|
||||||
|
*/
|
||||||
|
MultitouchDevice::~MultitouchDevice()
|
||||||
|
{
|
||||||
|
clearButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Returns a number of fingers that are currently in use
|
||||||
|
*/
|
||||||
|
unsigned int MultitouchDevice::getActiveTouchesCount()
|
||||||
|
{
|
||||||
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
for (MultitouchEvent event : m_events)
|
||||||
|
{
|
||||||
|
if (event.touched)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
} // getActiveTouchesCount
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Creates a button of specified type and position. The button is then updated
|
||||||
|
* when touch event occurs and proper action is sent to player controller.
|
||||||
|
* Note that it just determines the screen area that is considered as button
|
||||||
|
* and it doesn't draw the GUI element on a screen.
|
||||||
|
* \param type The button type that determines its behaviour.
|
||||||
|
* \param x Vertical position of the button.
|
||||||
|
* \param y Horizontal position of the button.
|
||||||
|
* \param width Width of the button.
|
||||||
|
* \param height Height of the button.
|
||||||
|
*/
|
||||||
|
void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
assert(width > 0 && height > 0);
|
||||||
|
|
||||||
|
MultitouchButton* button = new MultitouchButton();
|
||||||
|
button->type = type;
|
||||||
|
button->event_id = 0;
|
||||||
|
button->pressed = false;
|
||||||
|
button->x = x;
|
||||||
|
button->y = y;
|
||||||
|
button->width = width;
|
||||||
|
button->height = height;
|
||||||
|
button->axis_x = 0.0f;
|
||||||
|
button->axis_y = 0.0f;
|
||||||
|
|
||||||
|
switch (button->type)
|
||||||
|
{
|
||||||
|
case MultitouchButtonType::BUTTON_FIRE:
|
||||||
|
button->action = PA_FIRE;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_NITRO:
|
||||||
|
button->action = PA_NITRO;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_SKIDDING:
|
||||||
|
button->action = PA_DRIFT;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_LOOK_BACKWARDS:
|
||||||
|
button->action = PA_LOOK_BACK;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_RESCUE:
|
||||||
|
button->action = PA_RESCUE;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_ESCAPE:
|
||||||
|
button->action = PA_PAUSE_RACE;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_UP:
|
||||||
|
button->action = PA_ACCEL;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_DOWN:
|
||||||
|
button->action = PA_BRAKE;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_LEFT:
|
||||||
|
button->action = PA_STEER_LEFT;
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_RIGHT:
|
||||||
|
button->action = PA_STEER_RIGHT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
button->action = PA_BEFORE_FIRST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buttons.push_back(button);
|
||||||
|
} // addButton
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Deletes all previously created buttons
|
||||||
|
*/
|
||||||
|
void MultitouchDevice::clearButtons()
|
||||||
|
{
|
||||||
|
for (MultitouchButton* button : m_buttons)
|
||||||
|
{
|
||||||
|
delete button;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buttons.clear();
|
||||||
|
} // clearButtons
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** The function that is executed when touch event occurs. It updates the
|
||||||
|
* buttons state when it's needed.
|
||||||
|
* \param event_id The id of touch event that should be processed.
|
||||||
|
*/
|
||||||
|
void MultitouchDevice::updateDeviceState(unsigned int event_id)
|
||||||
|
{
|
||||||
|
assert(event_id < m_events.size());
|
||||||
|
|
||||||
|
MultitouchEvent event = m_events[event_id];
|
||||||
|
|
||||||
|
for (MultitouchButton* button : m_buttons)
|
||||||
|
{
|
||||||
|
bool update_controls = false;
|
||||||
|
bool prev_button_state = button->pressed;
|
||||||
|
float prev_axis_x = button->axis_x;
|
||||||
|
float prev_axis_y = button->axis_y;
|
||||||
|
|
||||||
|
if (event.x < button->x || event.x > button->x + button->width ||
|
||||||
|
event.y < button->y || event.y > button->y + button->height)
|
||||||
|
{
|
||||||
|
if (button->event_id == event_id)
|
||||||
|
{
|
||||||
|
button->pressed = false;
|
||||||
|
button->event_id = 0;
|
||||||
|
button->axis_x = 0.0f;
|
||||||
|
button->axis_y = 0.0f;
|
||||||
|
update_controls = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button->pressed = event.touched;
|
||||||
|
button->event_id = event_id;
|
||||||
|
|
||||||
|
if (button->type == MultitouchButtonType::BUTTON_STEERING)
|
||||||
|
{
|
||||||
|
if (button->pressed == true)
|
||||||
|
{
|
||||||
|
button->axis_x = (float)(event.x - button->x) /
|
||||||
|
(button->width/2) - 1;
|
||||||
|
button->axis_y = (float)(event.y - button->y) /
|
||||||
|
(button->height/2) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button->axis_x = 0.0f;
|
||||||
|
button->axis_y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_axis_x != button->axis_x ||
|
||||||
|
prev_axis_y != button->axis_y)
|
||||||
|
{
|
||||||
|
update_controls = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (prev_button_state != button->pressed)
|
||||||
|
{
|
||||||
|
update_controls = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_controls)
|
||||||
|
{
|
||||||
|
handleControls(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // updateDeviceState
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Sends proper action for player controller depending on the button type
|
||||||
|
* and state.
|
||||||
|
* \param button The button that should be handled.
|
||||||
|
*/
|
||||||
|
void MultitouchDevice::handleControls(MultitouchButton* button)
|
||||||
|
{
|
||||||
|
if (m_player == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Handle multitouch events only when race is running. It avoids to process
|
||||||
|
// it when pause dialog is active during the race. And there is no reason
|
||||||
|
// to use it for GUI navigation.
|
||||||
|
if (StateManager::get()->getGameState() != GUIEngine::GAME ||
|
||||||
|
GUIEngine::ModalDialog::isADialogActive() ||
|
||||||
|
race_manager->isWatchingReplay())
|
||||||
|
return;
|
||||||
|
|
||||||
|
AbstractKart* pk = m_player->getKart();
|
||||||
|
|
||||||
|
if (pk == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Controller* controller = pk->getController();
|
||||||
|
|
||||||
|
if (controller == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (button->type == MultitouchButtonType::BUTTON_STEERING)
|
||||||
|
{
|
||||||
|
assert(m_deadzone_edge != 1.0f);
|
||||||
|
|
||||||
|
if (button->axis_y < -m_deadzone_center)
|
||||||
|
{
|
||||||
|
float factor = std::min(std::abs(button->axis_y) / (1 -
|
||||||
|
m_deadzone_edge), 1.0f);
|
||||||
|
controller->action(PA_ACCEL, factor * Input::MAX_VALUE);
|
||||||
|
}
|
||||||
|
else if (button->axis_y > m_deadzone_center)
|
||||||
|
{
|
||||||
|
float factor = std::min(std::abs(button->axis_y) / (1 -
|
||||||
|
m_deadzone_edge), 1.0f);
|
||||||
|
controller->action(PA_BRAKE, factor * Input::MAX_VALUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controller->action(PA_BRAKE, 0);
|
||||||
|
controller->action(PA_ACCEL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button->axis_x < -m_deadzone_center)
|
||||||
|
{
|
||||||
|
float factor = std::min(std::abs(button->axis_x) / (1 -
|
||||||
|
m_deadzone_edge), 1.0f);
|
||||||
|
controller->action(PA_STEER_LEFT, factor * Input::MAX_VALUE);
|
||||||
|
}
|
||||||
|
else if (button->axis_x > m_deadzone_center)
|
||||||
|
{
|
||||||
|
float factor = std::min(std::abs(button->axis_x) / (1 -
|
||||||
|
m_deadzone_edge), 1.0f);
|
||||||
|
controller->action(PA_STEER_RIGHT, factor * Input::MAX_VALUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controller->action(PA_STEER_LEFT, 0);
|
||||||
|
controller->action(PA_STEER_RIGHT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (button->action != PA_BEFORE_FIRST)
|
||||||
|
{
|
||||||
|
int value = button->pressed ? Input::MAX_VALUE : 0;
|
||||||
|
controller->action(button->action, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // handleControls
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
111
src/input/multitouch_device.hpp
Normal file
111
src/input/multitouch_device.hpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2013-2015 SuperTuxKart-Team
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef HEADER_MULTITOUCH_DEVICE_HPP
|
||||||
|
#define HEADER_MULTITOUCH_DEVICE_HPP
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "input/input_device.hpp"
|
||||||
|
#include "IEventReceiver.h"
|
||||||
|
|
||||||
|
#define NUMBER_OF_MULTI_TOUCHES 10
|
||||||
|
|
||||||
|
enum MultitouchButtonType
|
||||||
|
{
|
||||||
|
BUTTON_STEERING,
|
||||||
|
BUTTON_FIRE,
|
||||||
|
BUTTON_NITRO,
|
||||||
|
BUTTON_SKIDDING,
|
||||||
|
BUTTON_LOOK_BACKWARDS,
|
||||||
|
BUTTON_RESCUE,
|
||||||
|
BUTTON_ESCAPE,
|
||||||
|
BUTTON_UP,
|
||||||
|
BUTTON_DOWN,
|
||||||
|
BUTTON_LEFT,
|
||||||
|
BUTTON_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MultitouchEvent
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
bool touched;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MultitouchButton
|
||||||
|
{
|
||||||
|
MultitouchButtonType type;
|
||||||
|
PlayerAction action;
|
||||||
|
bool pressed;
|
||||||
|
unsigned int event_id;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
float axis_x;
|
||||||
|
float axis_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MultitouchDevice : public InputDevice
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/** The list of pointers to all created buttons */
|
||||||
|
std::vector<MultitouchButton*> m_buttons;
|
||||||
|
|
||||||
|
/** The parameter that is used for steering button and determines dead area
|
||||||
|
* in a center of button */
|
||||||
|
float m_deadzone_center;
|
||||||
|
|
||||||
|
/** The parameter that is used for steering button and determines dead area
|
||||||
|
* at the edge of button */
|
||||||
|
float m_deadzone_edge;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** The array that contains data for all multitouch input events */
|
||||||
|
std::array<MultitouchEvent, NUMBER_OF_MULTI_TOUCHES> m_events;
|
||||||
|
|
||||||
|
MultitouchDevice();
|
||||||
|
virtual ~MultitouchDevice();
|
||||||
|
|
||||||
|
/** Unused function */
|
||||||
|
bool processAndMapInput(Input::InputType type, const int id,
|
||||||
|
InputManager::InputDriverMode mode,
|
||||||
|
PlayerAction *action, int* value = NULL)
|
||||||
|
{return true;}
|
||||||
|
|
||||||
|
unsigned int getActiveTouchesCount();
|
||||||
|
|
||||||
|
void addButton(MultitouchButtonType type, int x, int y, int width,
|
||||||
|
int height);
|
||||||
|
void clearButtons();
|
||||||
|
|
||||||
|
/** Returns the number of created buttons */
|
||||||
|
unsigned int getButtonsCount() {return m_buttons.size();}
|
||||||
|
|
||||||
|
/** Returns pointer to the selected button */
|
||||||
|
MultitouchButton* getButton(unsigned int i) {return m_buttons.at(i);}
|
||||||
|
|
||||||
|
void updateDeviceState(unsigned int event_id);
|
||||||
|
void handleControls(MultitouchButton* button);
|
||||||
|
|
||||||
|
}; // MultitouchDevice
|
||||||
|
|
||||||
|
#endif
|
@ -35,10 +35,13 @@ using namespace irr;
|
|||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "input/input.hpp"
|
#include "input/input.hpp"
|
||||||
#include "input/input_manager.hpp"
|
#include "input/input_manager.hpp"
|
||||||
|
#include "input/device_manager.hpp"
|
||||||
|
#include "input/multitouch_device.hpp"
|
||||||
#include "items/attachment.hpp"
|
#include "items/attachment.hpp"
|
||||||
#include "items/attachment_manager.hpp"
|
#include "items/attachment_manager.hpp"
|
||||||
#include "items/powerup_manager.hpp"
|
#include "items/powerup_manager.hpp"
|
||||||
#include "karts/abstract_kart.hpp"
|
#include "karts/abstract_kart.hpp"
|
||||||
|
#include "karts/controller/controller.hpp"
|
||||||
#include "karts/controller/spare_tire_ai.hpp"
|
#include "karts/controller/spare_tire_ai.hpp"
|
||||||
#include "karts/kart_properties.hpp"
|
#include "karts/kart_properties.hpp"
|
||||||
#include "karts/kart_properties_manager.hpp"
|
#include "karts/kart_properties_manager.hpp"
|
||||||
@ -83,6 +86,11 @@ RaceGUI::RaceGUI()
|
|||||||
{
|
{
|
||||||
m_map_left = irr_driver->getActualScreenSize().Width - m_map_width;
|
m_map_left = irr_driver->getActualScreenSize().Width - m_map_width;
|
||||||
}
|
}
|
||||||
|
else if (UserConfigParams::m_multitouch_enabled)
|
||||||
|
{
|
||||||
|
m_map_left = irr_driver->getActualScreenSize().Width - m_map_width;
|
||||||
|
m_map_bottom = irr_driver->getActualScreenSize().Height * 0.55f;
|
||||||
|
}
|
||||||
|
|
||||||
m_is_tutorial = (race_manager->getTrackName() == "tutorial");
|
m_is_tutorial = (race_manager->getTrackName() == "tutorial");
|
||||||
|
|
||||||
@ -104,11 +112,22 @@ RaceGUI::RaceGUI()
|
|||||||
else
|
else
|
||||||
m_lap_width = font->getDimension(L"9/9").Width;
|
m_lap_width = font->getDimension(L"9/9").Width;
|
||||||
|
|
||||||
|
if (UserConfigParams::m_multitouch_enabled)
|
||||||
|
{
|
||||||
|
initMultitouchSteering();
|
||||||
|
}
|
||||||
} // RaceGUI
|
} // RaceGUI
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
RaceGUI::~RaceGUI()
|
RaceGUI::~RaceGUI()
|
||||||
{
|
{
|
||||||
|
MultitouchDevice* device = input_manager->getDeviceManager()->
|
||||||
|
getMultitouchDevice();
|
||||||
|
|
||||||
|
if (device != NULL)
|
||||||
|
{
|
||||||
|
device->clearButtons();
|
||||||
|
}
|
||||||
} // ~Racegui
|
} // ~Racegui
|
||||||
|
|
||||||
|
|
||||||
@ -216,10 +235,19 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
|
|||||||
scaling *= viewport.getWidth()/800.0f; // scale race GUI along screen size
|
scaling *= viewport.getWidth()/800.0f; // scale race GUI along screen size
|
||||||
drawAllMessages(kart, viewport, scaling);
|
drawAllMessages(kart, viewport, scaling);
|
||||||
|
|
||||||
|
if (UserConfigParams::m_multitouch_enabled)
|
||||||
|
{
|
||||||
|
drawMultitouchSteering(kart, viewport, scaling);
|
||||||
|
}
|
||||||
|
|
||||||
if(!World::getWorld()->isRacePhase()) return;
|
if(!World::getWorld()->isRacePhase()) return;
|
||||||
|
|
||||||
drawPowerupIcons (kart, viewport, scaling);
|
drawPowerupIcons(kart, viewport, scaling);
|
||||||
drawSpeedEnergyRank(kart, viewport, scaling, dt);
|
|
||||||
|
if (!UserConfigParams::m_multitouch_enabled)
|
||||||
|
{
|
||||||
|
drawSpeedEnergyRank(kart, viewport, scaling, dt);
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_is_tutorial)
|
if (!m_is_tutorial)
|
||||||
drawLap(kart, viewport, scaling);
|
drawLap(kart, viewport, scaling);
|
||||||
@ -878,3 +906,157 @@ void RaceGUI::drawLap(const AbstractKart* kart,
|
|||||||
font->setScale(1.0f);
|
font->setScale(1.0f);
|
||||||
|
|
||||||
} // drawLap
|
} // drawLap
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Makes some initializations and determines the look of multitouch steering
|
||||||
|
* interface
|
||||||
|
*/
|
||||||
|
void RaceGUI::initMultitouchSteering()
|
||||||
|
{
|
||||||
|
MultitouchDevice* device = input_manager->getDeviceManager()->
|
||||||
|
getMultitouchDevice();
|
||||||
|
|
||||||
|
if (device == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int w = irr_driver->getActualScreenSize().Width;
|
||||||
|
const int h = irr_driver->getActualScreenSize().Height;
|
||||||
|
const float btn_size = 0.1f * h;
|
||||||
|
const float btn2_size = 0.35f * h;
|
||||||
|
const float margin = 0.1f * h;
|
||||||
|
const float top_margin = 0.3f * h;
|
||||||
|
const float col_size = btn_size + margin;
|
||||||
|
const float small_ratio = 0.6f;
|
||||||
|
|
||||||
|
device->addButton(BUTTON_STEERING,
|
||||||
|
0.5f * margin, h - 0.5f * margin - btn2_size,
|
||||||
|
btn2_size, btn2_size);
|
||||||
|
device->addButton(BUTTON_ESCAPE,
|
||||||
|
top_margin, small_ratio * margin,
|
||||||
|
small_ratio * btn_size, small_ratio * btn_size);
|
||||||
|
device->addButton(BUTTON_RESCUE,
|
||||||
|
top_margin + small_ratio * col_size, small_ratio * margin,
|
||||||
|
small_ratio * btn_size, small_ratio * btn_size);
|
||||||
|
device->addButton(BUTTON_NITRO,
|
||||||
|
w - 1 * col_size, h - 2 * col_size,
|
||||||
|
btn_size, btn_size);
|
||||||
|
device->addButton(BUTTON_SKIDDING,
|
||||||
|
w - 1 * col_size, h - 1 * col_size,
|
||||||
|
btn_size, btn_size);
|
||||||
|
device->addButton(BUTTON_FIRE,
|
||||||
|
w - 2 * col_size, h - 2 * col_size,
|
||||||
|
btn_size, btn_size);
|
||||||
|
device->addButton(BUTTON_LOOK_BACKWARDS,
|
||||||
|
w - 2 * col_size, h - 1 * col_size,
|
||||||
|
btn_size, btn_size);
|
||||||
|
|
||||||
|
} // initMultitouchSteering
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Draws the buttons for multitouch steering.
|
||||||
|
* \param kart The kart for which to show the data.
|
||||||
|
* \param viewport The viewport to use.
|
||||||
|
* \param scaling Which scaling to apply to the buttons.
|
||||||
|
*/
|
||||||
|
void RaceGUI::drawMultitouchSteering(const AbstractKart* kart,
|
||||||
|
const core::recti &viewport,
|
||||||
|
const core::vector2df &scaling)
|
||||||
|
{
|
||||||
|
MultitouchDevice* device = input_manager->getDeviceManager()->
|
||||||
|
getMultitouchDevice();
|
||||||
|
|
||||||
|
if (device == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < device->getButtonsCount(); i++)
|
||||||
|
{
|
||||||
|
MultitouchButton* button = device->getButton(i);
|
||||||
|
|
||||||
|
core::rect<s32> pos(button->x, button->y, button->x + button->width,
|
||||||
|
button->y + button->height);
|
||||||
|
|
||||||
|
if (button->type == MultitouchButtonType::BUTTON_STEERING)
|
||||||
|
{
|
||||||
|
video::ITexture* tex = irr_driver->getTexture(FileManager::GUI,
|
||||||
|
"blue_plus.png");
|
||||||
|
core::rect<s32> coords(core::position2d<s32>(0,0), tex->getSize());
|
||||||
|
|
||||||
|
draw2DImage(tex, pos, coords, NULL, NULL, true);
|
||||||
|
|
||||||
|
float x = (float)(button->x) + (float)(button->width) / 2.0f *
|
||||||
|
(button->axis_x + 1.0f);
|
||||||
|
float y = (float)(button->y) + (float)(button->height) / 2.0f *
|
||||||
|
(button->axis_y + 1.0f);
|
||||||
|
float w = (float)(button->width) / 20.0f;
|
||||||
|
float h = (float)(button->height) / 20.0f;
|
||||||
|
|
||||||
|
core::rect<s32> pos2(round(x - w), round(y - h),
|
||||||
|
round(x + w), round(y + h));
|
||||||
|
|
||||||
|
draw2DImage(tex, pos2, coords, NULL, NULL, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (button->pressed)
|
||||||
|
{
|
||||||
|
core::rect<s32> pos2(button->x - button->width * 0.2f,
|
||||||
|
button->y - button->height * 0.2f,
|
||||||
|
button->x + button->width * 1.2f,
|
||||||
|
button->y + button->height * 1.2f);
|
||||||
|
|
||||||
|
video::ITexture* tex = irr_driver->getTexture(FileManager::GUI,
|
||||||
|
"icons-frame.png");
|
||||||
|
core::rect<s32> coords(core::position2d<s32>(0,0), tex->getSize());
|
||||||
|
|
||||||
|
draw2DImage(tex, pos2, coords, NULL, NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
video::ITexture* tex;
|
||||||
|
|
||||||
|
if (button->type == MultitouchButtonType::BUTTON_SKIDDING)
|
||||||
|
{
|
||||||
|
tex = irr_driver->getTexture(FileManager::TEXTURE,
|
||||||
|
"skid-particle1.png");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string name = "gui_lock.png";
|
||||||
|
|
||||||
|
switch (button->type)
|
||||||
|
{
|
||||||
|
case MultitouchButtonType::BUTTON_ESCAPE:
|
||||||
|
name = "back.png";
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_FIRE:
|
||||||
|
name = "banana.png";
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_NITRO:
|
||||||
|
name = "nitro.png";
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_LOOK_BACKWARDS:
|
||||||
|
name = "down.png";
|
||||||
|
break;
|
||||||
|
case MultitouchButtonType::BUTTON_RESCUE:
|
||||||
|
name = "restart.png";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex = irr_driver->getTexture(FileManager::GUI, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
core::rect<s32> coords(core::position2d<s32>(0,0), tex->getSize());
|
||||||
|
draw2DImage(tex, pos, coords, NULL, NULL, true);
|
||||||
|
|
||||||
|
if (button->type == MultitouchButtonType::BUTTON_NITRO)
|
||||||
|
{
|
||||||
|
float scale = (float)(irr_driver->
|
||||||
|
getActualScreenSize().Height) / 1600.0f;
|
||||||
|
drawEnergyMeter(button->x + button->width,
|
||||||
|
button->y + button->height,
|
||||||
|
kart, viewport, core::vector2df(scale, scale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // drawMultitouchSteering
|
||||||
|
@ -94,6 +94,8 @@ private:
|
|||||||
|
|
||||||
bool m_is_tutorial;
|
bool m_is_tutorial;
|
||||||
|
|
||||||
|
void initMultitouchSteering();
|
||||||
|
|
||||||
/* Display informat for one player on the screen. */
|
/* Display informat for one player on the screen. */
|
||||||
void drawEnergyMeter (int x, int y, const AbstractKart *kart,
|
void drawEnergyMeter (int x, int y, const AbstractKart *kart,
|
||||||
const core::recti &viewport,
|
const core::recti &viewport,
|
||||||
@ -108,6 +110,9 @@ private:
|
|||||||
const core::vector2df &offset,
|
const core::vector2df &offset,
|
||||||
float min_ratio, int meter_width,
|
float min_ratio, int meter_width,
|
||||||
int meter_height, float dt);
|
int meter_height, float dt);
|
||||||
|
void drawMultitouchSteering (const AbstractKart* kart,
|
||||||
|
const core::recti &viewport,
|
||||||
|
const core::vector2df &scaling);
|
||||||
|
|
||||||
/** Display items that are shown once only (for all karts). */
|
/** Display items that are shown once only (for all karts). */
|
||||||
void drawGlobalMiniMap ();
|
void drawGlobalMiniMap ();
|
||||||
|
@ -693,9 +693,16 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
|||||||
const unsigned int kart_amount = world->getNumKarts() - sta;
|
const unsigned int kart_amount = world->getNumKarts() - sta;
|
||||||
|
|
||||||
//where is the limit to hide last icons
|
//where is the limit to hide last icons
|
||||||
int y_icons_limit=irr_driver->getActualScreenSize().Height-bottom_margin-ICON_PLAYER_WIDTH;
|
int y_icons_limit = irr_driver->getActualScreenSize().Height -
|
||||||
|
bottom_margin - ICON_PLAYER_WIDTH;
|
||||||
if (race_manager->getNumLocalPlayers() == 3)
|
if (race_manager->getNumLocalPlayers() == 3)
|
||||||
y_icons_limit=irr_driver->getActualScreenSize().Height-ICON_WIDTH;
|
{
|
||||||
|
y_icons_limit = irr_driver->getActualScreenSize().Height - ICON_WIDTH;
|
||||||
|
}
|
||||||
|
else if (UserConfigParams::m_multitouch_enabled)
|
||||||
|
{
|
||||||
|
y_icons_limit = irr_driver->getActualScreenSize().Height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
world->getKartsDisplayInfo(&m_kart_display_infos);
|
world->getKartsDisplayInfo(&m_kart_display_infos);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user