Allow to modify multitouch settings during the race

This commit is contained in:
Deve 2019-06-05 22:59:33 +02:00
parent 75be2b16c9
commit 7f42b84432
12 changed files with 244 additions and 163 deletions

View File

@ -24,6 +24,8 @@
#include "input/device_manager.hpp"
#include "input/input_manager.hpp"
#include "input/multitouch_device.hpp"
#include "modes/world.hpp"
#include "states_screens/race_gui_multitouch.hpp"
#include "utils/translation.hpp"
#ifdef ANDROID
@ -80,6 +82,13 @@ void MultitouchSettingsDialog::beforeAddingWidgets()
assert(gyroscope != NULL);
gyroscope->setActive(false);
}
if (StateManager::get()->getGameState() == GUIEngine::INGAME_MENU)
{
CheckBoxWidget* buttons_en = getWidget<CheckBoxWidget>("buttons_enabled");
assert(buttons_en != NULL);
buttons_en->setActive(false);
}
updateValues();
}
@ -143,6 +152,11 @@ GUIEngine::EventPropagation MultitouchSettingsDialog::processEvent(
{
touch_device->updateConfigParams();
}
if (World::getWorld() && World::getWorld()->getRaceGUI())
{
World::getWorld()->getRaceGUI()->recreateMultitouchGUI();
}
user_config->saveConfig();
@ -157,8 +171,6 @@ GUIEngine::EventPropagation MultitouchSettingsDialog::processEvent(
UserConfigParams::m_multitouch_controls.revertToDefaults();
#ifdef ANDROID
UserConfigParams::m_multitouch_draw_gui = true;
int32_t screen_size = AConfiguration_getScreenSize(
global_android_app->config);
@ -183,10 +195,18 @@ GUIEngine::EventPropagation MultitouchSettingsDialog::processEvent(
break;
}
#else
UserConfigParams::m_multitouch_draw_gui.revertToDefaults();
UserConfigParams::m_multitouch_scale.revertToDefaults();
UserConfigParams::m_multitouch_sensitivity_x.revertToDefaults();
#endif
if (StateManager::get()->getGameState() != GUIEngine::INGAME_MENU)
{
#ifdef ANDROID
UserConfigParams::m_multitouch_draw_gui = true;
#else
UserConfigParams::m_multitouch_draw_gui.revertToDefaults();
#endif
}
updateValues();

View File

@ -278,12 +278,7 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
}
else if (selection.find("touch_device") != std::string::npos)
{
// Don't edit multitouch settings during a race, because it needs
// to re-create all buttons to take an effect
if (StateManager::get()->getGameState() != GUIEngine::INGAME_MENU)
{
new MultitouchSettingsDialog(0.8f, 0.9f);
}
new MultitouchSettingsDialog(0.8f, 0.9f);
}
else
{

View File

@ -92,32 +92,6 @@ RaceGUI::RaceGUI()
else
m_lap_width = font->getDimension(L"9/9").Width;
float map_size_splitscreen = 1.0f;
// If there are four players or more in splitscreen
// and the map is in a player view, scale down the map
if (race_manager->getNumLocalPlayers() >= 4 && !race_manager->getIfEmptyScreenSpaceExists())
{
// If the resolution is wider than 4:3, we don't have to scaledown the minimap as much
// Uses some margin, in case the game's screen is not exactly 4:3
if ( ((float) irr_driver->getFrameSize().Width / (float) irr_driver->getFrameSize().Height) >
(4.1f/3.0f))
{
if (race_manager->getNumLocalPlayers() == 4)
map_size_splitscreen = 0.75f;
else
map_size_splitscreen = 0.5f;
}
else
map_size_splitscreen = 0.5f;
}
// Originally m_map_height was 100, and we take 480 as minimum res
float scaling = std::min(irr_driver->getFrameSize().Height,
irr_driver->getFrameSize().Width) / 480.0f;
const float map_size = stk_config->m_minimap_size * map_size_splitscreen;
const float top_margin = 3.5f * m_font_height;
bool multitouch_enabled = (UserConfigParams::m_multitouch_active == 1 &&
irr_driver->getDevice()->supportsTouchDevice()) ||
UserConfigParams::m_multitouch_active > 1;
@ -128,59 +102,7 @@ RaceGUI::RaceGUI()
m_multitouch_gui = new RaceGUIMultitouch(this);
}
// Check if we have enough space for minimap when touch steering is enabled
if (m_multitouch_gui != NULL && !m_multitouch_gui->isSpectatorMode())
{
const float map_bottom = (float)(irr_driver->getActualScreenSize().Height -
m_multitouch_gui->getHeight());
if ((map_size + 20.0f) * scaling > map_bottom - top_margin)
{
scaling = (map_bottom - top_margin) / (map_size + 20.0f);
}
}
// Marker texture has to be power-of-two for (old) OpenGL compliance
//m_marker_rendered_size = 2 << ((int) ceil(1.0 + log(32.0 * scaling)));
m_minimap_ai_size = (int)( stk_config->m_minimap_ai_icon * scaling);
m_minimap_player_size = (int)( stk_config->m_minimap_player_icon * scaling);
m_map_width = (int)(map_size * scaling);
m_map_height = (int)(map_size * scaling);
if(UserConfigParams::m_minimap_display == 1 && /*map on the right side*/
race_manager->getNumLocalPlayers() == 1)
{
m_map_left = (int)(irr_driver->getActualScreenSize().Width -
m_map_width - 10.0f*scaling);
m_map_bottom = (int)(3*irr_driver->getActualScreenSize().Height/4 -
m_map_height);
}
else // default, map in the bottom-left corner
{
m_map_left = (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
}
// Minimap is also rendered bigger via OpenGL, so find power-of-two again
const int map_texture = 2 << ((int) ceil(1.0 + log(128.0 * scaling)));
m_map_rendered_width = map_texture;
m_map_rendered_height = map_texture;
// special case : when 3 players play, use available 4th space for such things
if (race_manager->getIfEmptyScreenSpaceExists())
{
m_map_left = irr_driver->getActualScreenSize().Width -
m_map_width - (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
}
else if (m_multitouch_gui != NULL && !m_multitouch_gui->isSpectatorMode())
{
m_map_left = (int)((irr_driver->getActualScreenSize().Width -
m_map_width) * 0.95f);
m_map_bottom = (int)(irr_driver->getActualScreenSize().Height -
top_margin - m_map_height);
}
calculateMinimapSize();
m_is_tutorial = (race_manager->getTrackName() == "tutorial");
@ -235,6 +157,96 @@ void RaceGUI::reset()
}
} // reset
//-----------------------------------------------------------------------------
void RaceGUI::calculateMinimapSize()
{
float map_size_splitscreen = 1.0f;
// If there are four players or more in splitscreen
// and the map is in a player view, scale down the map
if (race_manager->getNumLocalPlayers() >= 4 && !race_manager->getIfEmptyScreenSpaceExists())
{
// If the resolution is wider than 4:3, we don't have to scaledown the minimap as much
// Uses some margin, in case the game's screen is not exactly 4:3
if ( ((float) irr_driver->getFrameSize().Width / (float) irr_driver->getFrameSize().Height) >
(4.1f/3.0f))
{
if (race_manager->getNumLocalPlayers() == 4)
map_size_splitscreen = 0.75f;
else
map_size_splitscreen = 0.5f;
}
else
map_size_splitscreen = 0.5f;
}
// Originally m_map_height was 100, and we take 480 as minimum res
float scaling = std::min(irr_driver->getFrameSize().Height,
irr_driver->getFrameSize().Width) / 480.0f;
const float map_size = stk_config->m_minimap_size * map_size_splitscreen;
const float top_margin = 3.5f * m_font_height;
// Check if we have enough space for minimap when touch steering is enabled
if (m_multitouch_gui != NULL && !m_multitouch_gui->isSpectatorMode())
{
const float map_bottom = (float)(irr_driver->getActualScreenSize().Height -
m_multitouch_gui->getHeight());
if ((map_size + 20.0f) * scaling > map_bottom - top_margin)
{
scaling = (map_bottom - top_margin) / (map_size + 20.0f);
}
// Use some reasonable minimum scale, because minimap size can be
// changed during the race
scaling = std::max(scaling,
irr_driver->getActualScreenSize().Height * 0.15f /
(map_size + 20.0f));
}
// Marker texture has to be power-of-two for (old) OpenGL compliance
//m_marker_rendered_size = 2 << ((int) ceil(1.0 + log(32.0 * scaling)));
m_minimap_ai_size = (int)( stk_config->m_minimap_ai_icon * scaling);
m_minimap_player_size = (int)( stk_config->m_minimap_player_icon * scaling);
m_map_width = (int)(map_size * scaling);
m_map_height = (int)(map_size * scaling);
if(UserConfigParams::m_minimap_display == 1 && /*map on the right side*/
race_manager->getNumLocalPlayers() == 1)
{
m_map_left = (int)(irr_driver->getActualScreenSize().Width -
m_map_width - 10.0f*scaling);
m_map_bottom = (int)(3*irr_driver->getActualScreenSize().Height/4 -
m_map_height);
}
else // default, map in the bottom-left corner
{
m_map_left = (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
}
// Minimap is also rendered bigger via OpenGL, so find power-of-two again
const int map_texture = 2 << ((int) ceil(1.0 + log(128.0 * scaling)));
m_map_rendered_width = map_texture;
m_map_rendered_height = map_texture;
// special case : when 3 players play, use available 4th space for such things
if (race_manager->getIfEmptyScreenSpaceExists())
{
m_map_left = irr_driver->getActualScreenSize().Width -
m_map_width - (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
}
else if (m_multitouch_gui != NULL && !m_multitouch_gui->isSpectatorMode())
{
m_map_left = (int)((irr_driver->getActualScreenSize().Width -
m_map_width) * 0.95f);
m_map_bottom = (int)(irr_driver->getActualScreenSize().Height -
top_margin - m_map_height);
}
} // calculateMinimapSize
//-----------------------------------------------------------------------------
/** Render all global parts of the race gui, i.e. things that are only
* displayed once even in splitscreen.

View File

@ -155,7 +155,7 @@ public:
/** Returns the size of the texture on which to render the minimap to. */
virtual const core::dimension2du getMiniMapSize() const
{ return core::dimension2du(m_map_width, m_map_height); }
virtual void calculateMinimapSize();
}; // RaceGUI
#endif

View File

@ -181,6 +181,20 @@ RaceGUIBase::~RaceGUIBase()
delete m_referee;
} // ~RaceGUIBase
//-----------------------------------------------------------------------------
void RaceGUIBase::recreateMultitouchGUI()
{
if (!m_multitouch_gui)
return;
m_multitouch_gui->recreate();
calculateMinimapSize();
Track* track = Track::getCurrentTrack();
assert(track != NULL);
track->updateMiniMapScale();
} // recreateMultitouchGUI
//-----------------------------------------------------------------------------
/** Creates the 2D vertices for a regular polygon. Adopted from Irrlicht.
* \param n Number of vertices to use.

View File

@ -245,6 +245,7 @@ public:
/** Returns the size of the texture on which to render the minimap to. */
virtual const core::dimension2du
getMiniMapSize() const = 0;
virtual void calculateMinimapSize() {};
// ------------------------------------------------------------------------
virtual void clearAllMessages() { m_messages.clear(); }
@ -258,6 +259,9 @@ public:
void cleanupMessages(const float dt);
void removeReferee();
RaceGUIMultitouch* getMultitouchGUI() {return m_multitouch_gui;}
void recreateMultitouchGUI();
}; // RaceGUIBase

View File

@ -62,19 +62,9 @@ RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui)
m_device = input_manager->getDeviceManager()->getMultitouchDevice();
if (UserConfigParams::m_multitouch_scale > 1.6f)
{
UserConfigParams::m_multitouch_scale = 1.6f;
}
else if (UserConfigParams::m_multitouch_scale < 0.8f)
{
UserConfigParams::m_multitouch_scale = 0.8f;
}
init();
} // RaceGUIMultitouch
//-----------------------------------------------------------------------------
/** The multitouch GUI destructor
*/
@ -83,7 +73,6 @@ RaceGUIMultitouch::~RaceGUIMultitouch()
close();
} // ~RaceGUIMultitouch
//-----------------------------------------------------------------------------
/** Sets the multitouch race gui to its initial state
*/
@ -95,6 +84,16 @@ void RaceGUIMultitouch::reset()
}
} // reset
//-----------------------------------------------------------------------------
/** Recreate multitouch race gui when config was changed
*/
void RaceGUIMultitouch::recreate()
{
close();
reset();
init();
} // recreate
//-----------------------------------------------------------------------------
/** Clears all previously created buttons in the multitouch device
@ -122,19 +121,13 @@ void RaceGUIMultitouch::close()
*/
void RaceGUIMultitouch::init()
{
if (m_device == NULL)
return;
auto cl = LobbyProtocol::get<ClientLobby>();
if (cl && cl->isSpectator())
if (UserConfigParams::m_multitouch_scale > 1.6f)
{
createSpectatorGUI();
m_is_spectator_mode = true;
UserConfigParams::m_multitouch_scale = 1.6f;
}
else
else if (UserConfigParams::m_multitouch_scale < 0.8f)
{
createRaceGUI();
UserConfigParams::m_multitouch_scale = 0.8f;
}
m_steering_wheel_tex = irr_driver->getTexture(FileManager::GUI_ICON,
@ -157,6 +150,18 @@ void RaceGUIMultitouch::init()
m_gui_action_tex = irr_driver->getTexture(FileManager::GUI_ICON,"challenge.png");
m_up_tex = irr_driver->getTexture(FileManager::GUI_ICON, "up.png");
m_down_tex = irr_driver->getTexture(FileManager::GUI_ICON, "down.png");
auto cl = LobbyProtocol::get<ClientLobby>();
if (cl && cl->isSpectator())
{
createSpectatorGUI();
m_is_spectator_mode = true;
}
else
{
createRaceGUI();
}
}
//-----------------------------------------------------------------------------
@ -164,6 +169,9 @@ void RaceGUIMultitouch::init()
*/
void RaceGUIMultitouch::createRaceGUI()
{
if (m_device == NULL)
return;
if (UserConfigParams::m_multitouch_controls == MULTITOUCH_CONTROLS_ACCELEROMETER)
{
m_device->activateAccelerometer();
@ -246,6 +254,9 @@ void RaceGUIMultitouch::createRaceGUI()
*/
void RaceGUIMultitouch::createSpectatorGUI()
{
if (m_device == NULL)
return;
const float scale = UserConfigParams::m_multitouch_scale;
const int h = irr_driver->getActualScreenSize().Height;

View File

@ -70,6 +70,7 @@ public:
bool isSpectatorMode() {return m_is_spectator_mode;}
void setGuiAction(bool enabled = true) {m_gui_action = enabled;}
void reset();
void recreate();
}; // RaceGUIMultitouch

View File

@ -78,7 +78,7 @@ RaceGUIOverworld::RaceGUIOverworld()
if (UserConfigParams::m_artist_debug_mode && UserConfigParams::m_hide_gui)
m_enabled = false;
m_is_first_render_call = true;
m_is_minimap_initialized = false;
m_close_to_a_challenge = false;
m_current_challenge = NULL;
m_trophy[0] = irr_driver->getTexture(FileManager::GUI_ICON, "cup_bronze.png");
@ -86,10 +86,6 @@ RaceGUIOverworld::RaceGUIOverworld()
m_trophy[2] = irr_driver->getTexture(FileManager::GUI_ICON, "cup_gold.png" );
m_trophy[3] = irr_driver->getTexture(FileManager::GUI_ICON, "cup_platinum.png" );
float scaling = std::min(irr_driver->getFrameSize().Height,
irr_driver->getFrameSize().Width) / 420.0f;
const float map_size = 250.0f;
bool multitouch_enabled = (UserConfigParams::m_multitouch_active == 1 &&
irr_driver->getDevice()->supportsTouchDevice()) ||
UserConfigParams::m_multitouch_active > 1;
@ -100,39 +96,7 @@ RaceGUIOverworld::RaceGUIOverworld()
m_multitouch_gui = new RaceGUIMultitouch(this);
}
// Check if we have enough space for minimap when touch steering is enabled
if (m_multitouch_gui != NULL)
{
const float map_bottom = (float)(irr_driver->getActualScreenSize().Height -
m_multitouch_gui->getHeight());
if ((map_size + 20.0f) * scaling > map_bottom)
{
scaling = map_bottom / (map_size + 20.0f);
}
}
// Marker texture has to be power-of-two for (old) OpenGL compliance
//m_marker_rendered_size = 2 << ((int) ceil(1.0 + log(32.0 * scaling)));
m_minimap_challenge_size = (int)( 12.0f * scaling);
m_minimap_player_size = (int)( 24.0f * scaling);
m_map_width = (int)(map_size * scaling);
m_map_height = (int)(map_size * scaling);
m_map_left = 20;
m_map_bottom = irr_driver->getActualScreenSize().Height-10;
// Minimap is also rendered bigger via OpenGL, so find power-of-two again
const int map_texture = 2 << ((int) ceil(1.0 + log(128.0 * scaling)));
m_map_rendered_width = map_texture;
m_map_rendered_height = map_texture;
if (m_multitouch_gui != NULL)
{
m_map_left = (int)((irr_driver->getActualScreenSize().Width -
m_map_width) * 0.9f);
m_map_bottom = m_map_height + int(10 * scaling);
}
calculateMinimapSize();
m_speed_meter_icon = material_manager->getMaterial("speedback.png");
m_speed_bar_icon = material_manager->getMaterial("speedfore.png");
@ -164,6 +128,56 @@ RaceGUIOverworld::~RaceGUIOverworld()
delete m_multitouch_gui;
} // ~RaceGUIOverworld
//-----------------------------------------------------------------------------
void RaceGUIOverworld::calculateMinimapSize()
{
float scaling = std::min(irr_driver->getFrameSize().Height,
irr_driver->getFrameSize().Width) / 420.0f;
const float map_size = 250.0f;
// Check if we have enough space for minimap when touch steering is enabled
if (m_multitouch_gui != NULL)
{
const float map_bottom = (float)(irr_driver->getActualScreenSize().Height -
m_multitouch_gui->getHeight());
if ((map_size + 20.0f) * scaling > map_bottom)
{
scaling = map_bottom / (map_size + 20.0f);
}
// Use some reasonable minimum scale, because minimap size can be
// changed during the race
scaling = std::max(scaling,
irr_driver->getActualScreenSize().Height * 0.2f /
(map_size + 20.0f));
}
// Marker texture has to be power-of-two for (old) OpenGL compliance
//m_marker_rendered_size = 2 << ((int) ceil(1.0 + log(32.0 * scaling)));
m_minimap_challenge_size = (int)( 12.0f * scaling);
m_minimap_player_size = (int)( 24.0f * scaling);
m_map_width = (int)(map_size * scaling);
m_map_height = (int)(map_size * scaling);
m_map_left = 20;
m_map_bottom = irr_driver->getActualScreenSize().Height-10;
// Minimap is also rendered bigger via OpenGL, so find power-of-two again
const int map_texture = 2 << ((int) ceil(1.0 + log(128.0 * scaling)));
m_map_rendered_width = map_texture;
m_map_rendered_height = map_texture;
if (m_multitouch_gui != NULL)
{
m_map_left = (int)((irr_driver->getActualScreenSize().Width -
m_map_width) * 0.9f);
m_map_bottom = m_map_height + int(10 * scaling);
}
m_is_minimap_initialized = false;
}
//-----------------------------------------------------------------------------
/** Render all global parts of the race gui, i.e. things that are only
* displayed once even in splitscreen.
@ -183,8 +197,6 @@ void RaceGUIOverworld::renderGlobal(float dt)
}
drawGlobalMiniMap();
m_is_first_render_call = false;
#endif
} // renderGlobal
@ -335,7 +347,7 @@ void RaceGUIOverworld::drawGlobalMiniMap()
// This can't be done in the constructor of this object, since at
// that time the scene.xml file has not been read (so the challenges
// are not defined yet).
if(m_is_first_render_call)
if (!m_is_minimap_initialized)
{
float left_most = 0;
float right_most = 0;
@ -356,6 +368,8 @@ void RaceGUIOverworld::drawGlobalMiniMap()
{
m_map_left -= (int)left_most;
}
m_is_minimap_initialized = true;
}
int upper_y = m_map_bottom - m_map_height;

View File

@ -87,8 +87,8 @@ private:
/** Distance of map from left side of screen. */
int m_map_left;
/** True if this is the first time the renderer is called. */
bool m_is_first_render_call;
/** True if the minimap is initialized */
bool m_is_minimap_initialized;
/** Distance of map from bottom of screen. */
int m_map_bottom;
@ -125,7 +125,8 @@ public:
// ------------------------------------------------------------------------
/** Returns the size of the texture on which to render the minimap to. */
virtual const core::dimension2du getMiniMapSize() const
{ return core::dimension2du(m_map_width, m_map_height); }
{ return core::dimension2du(m_map_width, m_map_height); }
virtual void calculateMinimapSize();
}; // RaceGUI

View File

@ -1156,27 +1156,36 @@ void Track::loadMinimap()
{
#ifndef SERVER_ONLY
//Create the minimap resizing it as necessary.
m_mini_map_size = World::getWorld()->getRaceGUI()->getMiniMapSize();
core::dimension2du mini_map_size = World::getWorld()->getRaceGUI()->getMiniMapSize();
//Use twice the size of the rendered minimap to reduce significantly aliasing
m_render_target = Graph::get()->makeMiniMap(m_mini_map_size * 2,
m_render_target = Graph::get()->makeMiniMap(mini_map_size * 2,
"minimap::" + m_ident, video::SColor(127, 255, 255, 255),
m_minimap_invert_x_z);
if (!m_render_target) return;
updateMiniMapScale();
#endif
} // loadMinimap
// ----------------------------------------------------------------------------
void Track::updateMiniMapScale()
{
if (!m_render_target)
return;
core::dimension2du mini_map_size = World::getWorld()->getRaceGUI()->getMiniMapSize();
core::dimension2du mini_map_texture_size = m_render_target->getTextureSize();
if(mini_map_texture_size.Width)
m_minimap_x_scale = float(m_mini_map_size.Width) / float(mini_map_texture_size.Width);
if(mini_map_texture_size.Width)
m_minimap_x_scale = float(mini_map_size.Width) / float(mini_map_texture_size.Width);
else
m_minimap_x_scale = 0;
if(mini_map_texture_size.Height)
m_minimap_y_scale = float(m_mini_map_size.Height) / float(mini_map_texture_size.Height);
m_minimap_y_scale = float(mini_map_size.Height) / float(mini_map_texture_size.Height);
else
m_minimap_y_scale = 0;
#endif
} // loadMinimap
}
// ----------------------------------------------------------------------------
/** Loads the main track model (i.e. all other objects contained in the

View File

@ -351,7 +351,6 @@ private:
/** The render target for the mini map, which is displayed in the race gui. */
RenderTarget *m_render_target;
core::dimension2du m_mini_map_size;
float m_minimap_x_scale;
float m_minimap_y_scale;
@ -448,6 +447,7 @@ public:
std::vector< std::vector<float> > buildHeightMap();
void drawMiniMap(const core::rect<s32>& dest_rect) const;
void updateMiniMapScale();
// ------------------------------------------------------------------------
/** Returns true if this track has an arena mode. */
bool isArena() const { return m_is_arena; }