Some improvements for touch device

This commit is contained in:
Deve 2018-04-10 00:22:09 +02:00
parent 8841200a1c
commit 3f69fd37ed
10 changed files with 212 additions and 144 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.supertuxkart.stk"
package="org.supertuxkart.stk_dbg"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">

View File

@ -2,7 +2,7 @@
Icons firstly made for SuperTuxKart UI on Android.
Files: blur_bg_button ; blur_bg_button_focus ; directionnal_wheel ; drift ; nitro ; nitro_empty ; pause ; thunderbird_reset ; wing_mirror
Files: blur_bg_button ; blur_bg_button_focus ; steering_wheel ; drift ; nitro ; nitro_empty ; pause ; thunderbird_reset ; wing_mirror
- CC BY-SA 4.0 / author: Néd J. Édoire
# License information:

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

@ -459,6 +459,8 @@ void DeviceManager::updateMultitouchDevice()
{
m_multitouch_device->setPlayer(NULL);
}
m_multitouch_device->updateController();
} // updateMultitouchDevice
//-----------------------------------------------------------------------------

View File

@ -1192,20 +1192,10 @@ EventPropagation InputManager::input(const SEvent& event)
if (device && device->isAccelerometerActive())
{
m_device_manager->updateMultitouchDevice();
for (unsigned int i = 0; i < device->getButtonsCount(); i++)
{
MultitouchButton* button = device->getButton(i);
if (button->type != BUTTON_STEERING)
continue;
float factor = UserConfigParams::m_multitouch_tilt_factor;
factor = std::max(factor, 0.1f);
button->axis_x = (float)event.AccelerometerEvent.Y / factor;
device->handleControls(button);
}
float factor = UserConfigParams::m_multitouch_tilt_factor;
factor = std::max(factor, 0.1f);
device->updateAxisX(event.AccelerometerEvent.Y / factor);
}
}

View File

@ -36,7 +36,7 @@ MultitouchDevice::MultitouchDevice()
m_type = DT_MULTITOUCH;
m_name = "Multitouch";
m_player = NULL;
m_accelerometer_active = false;
m_controller = NULL;
#ifdef ANDROID
m_android_device = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
@ -136,22 +136,6 @@ void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
}
m_buttons.push_back(button);
#ifdef ANDROID
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
if (UserConfigParams::m_multitouch_controls == 2 &&
!m_android_device->isAccelerometerActive())
{
m_android_device->activateAccelerometer(1.0f / 30);
if (m_android_device->isAccelerometerActive())
{
m_accelerometer_active = true;
}
}
}
#endif
} // addButton
// ----------------------------------------------------------------------------
@ -159,15 +143,6 @@ void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
*/
void MultitouchDevice::clearButtons()
{
#ifdef ANDROID
if (m_accelerometer_active == true &&
m_android_device->isAccelerometerActive())
{
m_android_device->deactivateAccelerometer();
m_accelerometer_active = false;
}
#endif
for (MultitouchButton* button : m_buttons)
{
delete button;
@ -198,6 +173,45 @@ void MultitouchDevice::reset()
}
} // reset
// ----------------------------------------------------------------------------
/** Activates accelerometer
*/
void MultitouchDevice::activateAccelerometer()
{
#ifdef ANDROID
if (!m_android_device->isAccelerometerActive())
{
m_android_device->activateAccelerometer(1.0f / 30);
}
#endif
}
// ----------------------------------------------------------------------------
/** Deativates accelerometer
*/
void MultitouchDevice::deactivateAccelerometer()
{
#ifdef ANDROID
if (m_android_device->isAccelerometerActive())
{
m_android_device->deactivateAccelerometer();
}
#endif
}
// ----------------------------------------------------------------------------
/** Get accelerometer state
* \return true if accelerometer is active
*/
bool MultitouchDevice::isAccelerometerActive()
{
#ifdef ANDROID
return m_android_device->isAccelerometerActive();
#endif
return false;
}
// ----------------------------------------------------------------------------
/** The function that is executed when touch event occurs. It updates the
* buttons state when it's needed.
@ -241,13 +255,15 @@ void MultitouchDevice::updateDeviceState(unsigned int event_id)
if (button->pressed == true)
{
updateButtonAxes(button,
(float)(event.x - button->x) / (button->width/2) - 1,
(float)(event.y - button->y) / (button->height/2) - 1);
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
{
updateButtonAxes(button, 0.0f, 0.0f);
button->axis_x = 0.0f;
button->axis_y = 0.0f;
}
if (prev_axis_x != button->axis_x ||
@ -298,35 +314,95 @@ float MultitouchDevice::getSteeringFactor(float value)
m_deadzone_center), 1.0f);
}
/** Updates the button axes. It leaves X axis untouched if the accelerometer is
* used for turning left/right
* \param button A button that should be updated
* \param x A value from 0 to 1
* \param y A value from 0 to 1
*/
void MultitouchDevice::updateButtonAxes(MultitouchButton* button, float x,
float y)
{
if (m_accelerometer_active == false)
{
button->axis_x = x;
}
// ----------------------------------------------------------------------------
button->axis_y = y;
void MultitouchDevice::updateAxisX(float value)
{
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
}
else
{
m_controller->action(PA_STEER_LEFT, 0);
m_controller->action(PA_STEER_RIGHT, 0);
}
}
// ----------------------------------------------------------------------------
void MultitouchDevice::updateAxisY(float value)
{
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
{
m_controller->action(PA_BRAKE, 0);
m_controller->action(PA_ACCEL, 0);
}
}
// ----------------------------------------------------------------------------
/** 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)
if (m_controller == NULL)
return;
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
#ifdef ANDROID
if (!m_android_device->isAccelerometerActive())
#endif
{
updateAxisX(button->axis_x);
}
updateAxisY(button->axis_y);
}
else
{
if (button->action != PA_BEFORE_FIRST)
{
int value = button->pressed ? Input::MAX_VALUE : 0;
m_controller->action(button->action, value);
}
}
}
// ----------------------------------------------------------------------------
void MultitouchDevice::updateController()
{
if (m_player == NULL)
{
m_controller = 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
@ -335,60 +411,20 @@ void MultitouchDevice::handleControls(MultitouchButton* button)
GUIEngine::ModalDialog::isADialogActive() ||
GUIEngine::ScreenKeyboard::isActive() ||
race_manager->isWatchingReplay())
{
m_controller = NULL;
return;
}
AbstractKart* pk = m_player->getKart();
if (pk == NULL)
return;
Controller* controller = pk->getController();
if (controller == NULL)
return;
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
if (button->axis_y < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_y));
controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (button->axis_y > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_y));
controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
{
controller->action(PA_BRAKE, 0);
controller->action(PA_ACCEL, 0);
}
m_controller = NULL;
return;
}
if (button->axis_x < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_x));
controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (button->axis_x > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_x));
controller->action(PA_STEER_RIGHT, int(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
m_controller = pk->getController();
}
// ----------------------------------------------------------------------------

View File

@ -68,11 +68,15 @@ struct MultitouchButton
float axis_y;
};
class Controller;
class MultitouchDevice : public InputDevice
{
private:
/** The list of pointers to all created buttons */
std::vector<MultitouchButton*> m_buttons;
Controller* m_controller;
/** The parameter that is used for steering button and determines dead area
* in a center of button */
@ -82,16 +86,13 @@ private:
* at the edge of button */
float m_deadzone_edge;
/** True if accelerometer is in use */
bool m_accelerometer_active;
#ifdef ANDROID
/** Pointer to the Android irrlicht device */
CIrrDeviceAndroid* m_android_device;
#endif
float getSteeringFactor(float value);
void updateButtonAxes(MultitouchButton* button, float x, float y);
void handleControls(MultitouchButton* button);
public:
/** The array that contains data for all multitouch input events */
@ -119,12 +120,14 @@ public:
/** Returns pointer to the selected button */
MultitouchButton* getButton(unsigned int i) {return m_buttons.at(i);}
/** True if accelerometer is in use */
bool isAccelerometerActive() {return m_accelerometer_active;}
void activateAccelerometer();
void deactivateAccelerometer();
bool isAccelerometerActive();
void updateAxisX(float value);
void updateAxisY(float value);
void updateDeviceState(unsigned int event_id);
void handleControls(MultitouchButton* button);
void updateController();
void updateConfigParams();
}; // MultitouchDevice

View File

@ -463,7 +463,7 @@ void RaceGUIBase::renderPlayerView(const Camera *camera, float dt)
if (m_multitouch_gui != NULL)
{
m_multitouch_gui->drawMultitouchSteering(kart, viewport, scaling);
m_multitouch_gui->draw(kart, viewport, scaling);
}
} // renderPlayerView

View File

@ -42,7 +42,7 @@ RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui)
m_race_gui = race_gui;
m_minimap_bottom = 0;
m_gui_action = false;
m_directionnal_wheel_tex = NULL;
m_steering_wheel_tex = NULL;
m_pause_tex = NULL;
m_nitro_tex = NULL;
m_nitro_empty_tex = NULL;
@ -51,6 +51,9 @@ RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui)
m_drift_tex = NULL;
m_bg_button_tex = NULL;
m_bg_button_focus_tex = NULL;
m_gui_action_tex = NULL;
m_up_tex = NULL;
m_down_tex = NULL;
m_device = input_manager->getDeviceManager()->getMultitouchDevice();
@ -63,7 +66,7 @@ RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui)
UserConfigParams::m_multitouch_scale = 0.5f;
}
initMultitouchSteering();
init();
} // RaceGUIMultitouch
@ -72,7 +75,7 @@ RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui)
*/
RaceGUIMultitouch::~RaceGUIMultitouch()
{
closeMultitouchSteering();
close();
} // ~RaceGUIMultitouch
@ -91,23 +94,33 @@ void RaceGUIMultitouch::reset()
//-----------------------------------------------------------------------------
/** Clears all previously created buttons in the multitouch device
*/
void RaceGUIMultitouch::closeMultitouchSteering()
void RaceGUIMultitouch::close()
{
if (m_device != NULL)
{
m_device->clearButtons();
}
} // closeMultitouchSteering
if (m_device->isAccelerometerActive())
{
m_device->deactivateAccelerometer();
}
} // close
//-----------------------------------------------------------------------------
/** Makes some initializations and determines the look of multitouch steering
/** Makes some initializations and determines the look of multitouch race GUI
* interface
*/
void RaceGUIMultitouch::initMultitouchSteering()
void RaceGUIMultitouch::init()
{
if (m_device == NULL)
return;
if (UserConfigParams::m_multitouch_controls == 2)
{
m_device->activateAccelerometer();
}
const float scale = UserConfigParams::m_multitouch_scale;
@ -126,6 +139,7 @@ void RaceGUIMultitouch::initMultitouchSteering()
float first_column_x = w - 2 * col_size;
float second_column_x = w - 1 * col_size;
float left_column_x = margin + col_size / 2;
float steering_btn_margin = 0.6f * margin;
float steering_btn_x = steering_btn_margin;
float steering_btn_y = h - steering_btn_margin - btn2_size;
@ -134,14 +148,28 @@ void RaceGUIMultitouch::initMultitouchSteering()
{
first_column_x = margin + 1 * col_size;
second_column_x = margin;
left_column_x = w - 1.5f * col_size;
steering_btn_x = w - btn2_size - steering_btn_margin;
}
m_minimap_bottom = (unsigned int)(h - 2 * col_size);
if (m_device->isAccelerometerActive())
{
m_device->addButton(BUTTON_UP,
int(left_column_x), int(h - 2 * col_size),
int(btn_size), int(btn_size));
m_device->addButton(BUTTON_DOWN,
int(left_column_x), int(h - 1 * col_size),
int(btn_size), int(btn_size));
}
else
{
m_device->addButton(BUTTON_STEERING,
int(steering_btn_x), int(steering_btn_y),
int(btn2_size), int(btn2_size));
}
m_device->addButton(BUTTON_STEERING,
int(steering_btn_x), int(steering_btn_y),
int(btn2_size), int(btn2_size));
m_device->addButton(BUTTON_ESCAPE,
int(margin_top), int(margin_small),
int(btn_small_size), int(btn_small_size));
@ -161,8 +189,8 @@ void RaceGUIMultitouch::initMultitouchSteering()
int(first_column_x), int(h - 1 * col_size),
int(btn_size), int(btn_size));
m_directionnal_wheel_tex = irr_driver->getTexture(FileManager::GUI,
"android/directionnal_wheel.png");
m_steering_wheel_tex = irr_driver->getTexture(FileManager::GUI,
"android/steering_wheel.png");
m_pause_tex = irr_driver->getTexture(FileManager::GUI, "android/pause.png");
m_nitro_tex = irr_driver->getTexture(FileManager::GUI, "android/nitro.png");
m_nitro_empty_tex = irr_driver->getTexture(FileManager::GUI,
@ -177,18 +205,20 @@ void RaceGUIMultitouch::initMultitouchSteering()
m_bg_button_focus_tex = irr_driver->getTexture(FileManager::GUI,
"android/blur_bg_button_focus.png");
m_gui_action_tex = irr_driver->getTexture(FileManager::GUI,"challenge.png");
m_up_tex = irr_driver->getTexture(FileManager::GUI, "up.png");
m_down_tex = irr_driver->getTexture(FileManager::GUI, "down.png");
} // initMultitouchSteering
} // init
//-----------------------------------------------------------------------------
/** Draws the buttons for multitouch steering.
/** Draws the buttons for multitouch race GUI.
* \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 RaceGUIMultitouch::drawMultitouchSteering(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
void RaceGUIMultitouch::draw(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
{
#ifndef SERVER_ONLY
if (m_device == NULL)
@ -210,7 +240,7 @@ void RaceGUIMultitouch::drawMultitouchSteering(const AbstractKart* kart,
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
video::ITexture* btn_texture = m_directionnal_wheel_tex;
video::ITexture* btn_texture = m_steering_wheel_tex;
core::rect<s32> coords(pos_zero, btn_texture->getSize());
draw2DImage(btn_texture, btn_pos, coords, NULL, NULL, true);
@ -277,6 +307,12 @@ void RaceGUIMultitouch::drawMultitouchSteering(const AbstractKart* kart,
case MultitouchButtonType::BUTTON_SKIDDING:
btn_texture = m_drift_tex;
break;
case MultitouchButtonType::BUTTON_UP:
btn_texture = m_up_tex;
break;
case MultitouchButtonType::BUTTON_DOWN:
btn_texture = m_down_tex;
break;
default:
break;
}
@ -321,4 +357,4 @@ void RaceGUIMultitouch::drawMultitouchSteering(const AbstractKart* kart,
}
}
#endif
} // drawMultitouchSteering
} // draw

View File

@ -38,7 +38,7 @@ private:
bool m_gui_action;
unsigned int m_minimap_bottom;
video::ITexture* m_directionnal_wheel_tex;
video::ITexture* m_steering_wheel_tex;
video::ITexture* m_pause_tex;
video::ITexture* m_nitro_tex;
video::ITexture* m_nitro_empty_tex;
@ -48,17 +48,18 @@ private:
video::ITexture* m_bg_button_tex;
video::ITexture* m_bg_button_focus_tex;
video::ITexture* m_gui_action_tex;
video::ITexture* m_up_tex;
video::ITexture* m_down_tex;
void initMultitouchSteering();
void closeMultitouchSteering();
void init();
void close();
public:
RaceGUIMultitouch(RaceGUIBase* race_gui);
~RaceGUIMultitouch();
void drawMultitouchSteering(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling);
void draw(const AbstractKart* kart, const core::recti &viewport,
const core::vector2df &scaling);
unsigned int getMinimapBottom() {return m_minimap_bottom;}
void setGuiAction(bool enabled = true) {m_gui_action = enabled;}