From 5f0a65a07bd9e31ada1e50d915a83790f764f574 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Fri, 16 Dec 2016 20:21:09 -0500 Subject: [PATCH 1/6] Fix bug where an animated texture matrix could never be reset to identity. Fixes #2692 --- src/graphics/stk_animated_mesh.cpp | 4 +++- src/graphics/stk_animated_mesh.hpp | 1 + src/graphics/stk_mesh_scene_node.cpp | 4 +++- src/graphics/stk_mesh_scene_node.hpp | 1 + src/states_screens/race_gui_base.cpp | 2 ++ 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/graphics/stk_animated_mesh.cpp b/src/graphics/stk_animated_mesh.cpp index 74524dddb..da996c11a 100644 --- a/src/graphics/stk_animated_mesh.cpp +++ b/src/graphics/stk_animated_mesh.cpp @@ -40,6 +40,7 @@ const core::vector3df& scale, RenderInfo* render_info, bool all_parts_colorized) { isGLInitialized = false; isMaterialInitialized = false; + m_got_animated_matrix = false; m_mesh_render_info = render_info; m_all_parts_colorized = all_parts_colorized; #ifdef DEBUG @@ -192,10 +193,11 @@ void STKAnimatedMesh::updateNoGL() { // Test if texture matrix needs to be updated every frame const core::matrix4& mat = getMaterial(i).getTextureMatrix(0); - if (mat.isIdentity()) + if (mat.isIdentity() && !m_got_animated_matrix) continue; else { + m_got_animated_matrix = true; GLmeshes[i].texture_trans.X = mat[8]; GLmeshes[i].texture_trans.Y = mat[9]; } diff --git a/src/graphics/stk_animated_mesh.hpp b/src/graphics/stk_animated_mesh.hpp index f7c10019e..6bc2a3b5b 100644 --- a/src/graphics/stk_animated_mesh.hpp +++ b/src/graphics/stk_animated_mesh.hpp @@ -53,6 +53,7 @@ public: private: RenderInfo* m_mesh_render_info; bool m_all_parts_colorized; + bool m_got_animated_matrix; }; #endif // STKANIMATEDMESH_HPP diff --git a/src/graphics/stk_mesh_scene_node.cpp b/src/graphics/stk_mesh_scene_node.cpp index cf7473a58..749388d29 100644 --- a/src/graphics/stk_mesh_scene_node.cpp +++ b/src/graphics/stk_mesh_scene_node.cpp @@ -61,6 +61,7 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, update_each_frame = false; m_frame_for_mesh = frame_for_mesh; isGlow = false; + m_got_animated_matrix = false; m_debug_name = debug_name; @@ -244,10 +245,11 @@ void STKMeshSceneNode::updateNoGL() { // Test if texture matrix needs to be updated every frame const core::matrix4& mat = getMaterial(i).getTextureMatrix(0); - if (mat.isIdentity()) + if (mat.isIdentity() && !m_got_animated_matrix) continue; else { + m_got_animated_matrix = true; GLmeshes[i].texture_trans.X = mat[8]; GLmeshes[i].texture_trans.Y = mat[9]; } diff --git a/src/graphics/stk_mesh_scene_node.hpp b/src/graphics/stk_mesh_scene_node.hpp index c75e52d00..5275217f3 100644 --- a/src/graphics/stk_mesh_scene_node.hpp +++ b/src/graphics/stk_mesh_scene_node.hpp @@ -30,6 +30,7 @@ class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon protected: PtrVector m_static_render_info; int m_frame_for_mesh; + bool m_got_animated_matrix; std::vector GLmeshes; core::matrix4 ModelViewProjectionMatrix; core::vector3df windDir; diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index 800d68290..3320508f6 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -146,6 +146,8 @@ void RaceGUIBase::reset() m_referee_height = 10.0f; m_referee->attachToSceneNode(); + m_referee->selectReadySetGo(0); // set red color + m_plunger_move_time = 0; m_plunger_offset = core::vector2di(0,0); m_plunger_speed = core::vector2df(0,0); From fc9a51b7f4a8765a175a8cce4f9978f4572dcd79 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Fri, 16 Dec 2016 20:33:30 -0500 Subject: [PATCH 2/6] Reset cameras when resetting 3 strikes battle. Fixes #2687 --- src/modes/three_strikes_battle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 2e5c1d9e1..bf5a07bc0 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -117,6 +117,9 @@ void ThreeStrikesBattle::reset() // no positions in this mode m_karts[n]->setPosition(-1); + Camera *camera = Camera::getCamera(n); + camera->setKart(m_karts[n]); + scene::ISceneNode* kart_node = m_karts[n]->getNode(); core::list& children = kart_node->getChildren(); From 488af78fa3e1609a25d5f8ad668f11796ea3b602 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Fri, 16 Dec 2016 21:03:05 -0500 Subject: [PATCH 3/6] Fix #2687, reset cameras properly --- src/modes/follow_the_leader.cpp | 16 +++++++++++++++- src/modes/three_strikes_battle.cpp | 9 +++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/modes/follow_the_leader.cpp b/src/modes/follow_the_leader.cpp index 69eedc350..e8f0303d7 100644 --- a/src/modes/follow_the_leader.cpp +++ b/src/modes/follow_the_leader.cpp @@ -23,6 +23,7 @@ #include "graphics/camera.hpp" #include "items/powerup_manager.hpp" #include "karts/abstract_kart.hpp" +#include "karts/controller/controller.hpp" #include "states_screens/race_gui_base.hpp" #include "tracks/track.hpp" #include "utils/translation.hpp" @@ -83,7 +84,20 @@ void FollowTheLeaderRace::reset() stk_config->m_leader_time_per_kart*race_manager->getNumberOfKarts(); WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN, m_leader_intervals[0]); - + + const unsigned int kart_amount = (unsigned int)m_karts.size(); + int idCamera = 0; + for (unsigned int n = 1; n < kart_amount; n++) + { + if (m_karts[n]->getController()->isPlayerController()) + { + Camera *camera = Camera::getCamera(idCamera); + camera->setMode(Camera::CM_NORMAL); + camera->setKart(getKart(n)); + idCamera++; + } + } + m_is_over_delay = 2.0f; } // reset diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index bf5a07bc0..3297723b7 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -102,6 +102,7 @@ void ThreeStrikesBattle::reset() const unsigned int kart_amount = (unsigned int)m_karts.size(); + int idCamera = 0; for(unsigned int n=0; n(m_karts[n]->getController()) != NULL) @@ -117,8 +118,12 @@ void ThreeStrikesBattle::reset() // no positions in this mode m_karts[n]->setPosition(-1); - Camera *camera = Camera::getCamera(n); - camera->setKart(m_karts[n]); + if (m_karts[n]->getController()->isPlayerController()) + { + Camera *camera = Camera::getCamera(idCamera); + camera->setKart(m_karts[n]); + idCamera++; + } scene::ISceneNode* kart_node = m_karts[n]->getNode(); From f314c1ff2ac851c7e13daebb054a78052d24ad26 Mon Sep 17 00:00:00 2001 From: Deve Date: Sat, 17 Dec 2016 23:28:22 +0100 Subject: [PATCH 4/6] Some improvements for multitouch steering GUI - move it to separate class, so that it can be displayed in Overworld too - add a possibility to scale the interface (atm. only in config.xml) - touch steering buttons are created only for single player races I removed unused drawEnergyMeter function from Overworld GUI. The reason was that I use this function from race_gui.cpp for nitro button and this function in overworld breaks it. And still the proper drawEnergyMeter function is available in race_gui.cpp and can be moved to RaceGuiBase if it will be needed in Overworld in future. I moved the font size computation to the top of constructor because I use it to check available space for minimap. --- sources.cmake | 2 +- src/config/user_config.hpp | 6 + src/states_screens/race_gui.cpp | 239 ++++----------------- src/states_screens/race_gui.hpp | 5 - src/states_screens/race_gui_base.cpp | 20 +- src/states_screens/race_gui_base.hpp | 9 +- src/states_screens/race_gui_multitouch.cpp | 237 ++++++++++++++++++++ src/states_screens/race_gui_multitouch.hpp | 54 +++++ src/states_screens/race_gui_overworld.cpp | 122 ++++------- src/states_screens/race_gui_overworld.hpp | 5 - 10 files changed, 406 insertions(+), 293 deletions(-) create mode 100644 src/states_screens/race_gui_multitouch.cpp create mode 100644 src/states_screens/race_gui_multitouch.hpp diff --git a/sources.cmake b/sources.cmake index d4f28ae4d..3ed01563c 100644 --- a/sources.cmake +++ b/sources.cmake @@ -3,4 +3,4 @@ file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*") -file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc") +file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc") diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 20ee557d5..d71292b4b 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -410,6 +410,12 @@ namespace UserConfigParams &m_multitouch_group, "A parameter in range [0, 0.5] that determines the zone that is " "considered as max value in steering button.")); + + PARAM_PREFIX FloatUserConfigParam m_multitouch_scale + PARAM_DEFAULT( FloatUserConfigParam(1.0f, "multitouch_scale", + &m_multitouch_group, + "A parameter in range [0.5, 1.5] that determines the scale of the " + "multitouch interface.")); // ---- GP start order PARAM_PREFIX GroupUserConfigParam m_gp_start_order diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index a041dd930..50153aa40 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -36,10 +36,6 @@ using namespace irr; #include "guiengine/modaldialog.hpp" #include "guiengine/scalable_font.hpp" #include "io/file_manager.hpp" -#include "input/input.hpp" -#include "input/input_manager.hpp" -#include "input/device_manager.hpp" -#include "input/multitouch_device.hpp" #include "items/attachment.hpp" #include "items/attachment_manager.hpp" #include "items/powerup_manager.hpp" @@ -53,6 +49,7 @@ using namespace irr; #include "modes/world.hpp" #include "modes/soccer_world.hpp" #include "race/race_manager.hpp" +#include "states_screens/race_gui_multitouch.hpp" #include "tracks/track.hpp" #include "tracks/track_object_manager.hpp" #include "utils/constants.hpp" @@ -66,15 +63,43 @@ using namespace irr; RaceGUI::RaceGUI() { m_enabled = true; + + // Determine maximum length of the rank/lap text, in order to + // align those texts properly on the right side of the viewport. + gui::ScalableFont* font = GUIEngine::getHighresDigitFont(); + core::dimension2du area = font->getDimension(L"99:99:99"); + m_timer_width = area.Width; + m_font_height = area.Height; + + if (race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER || + race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES || + race_manager->getNumLaps() > 9) + m_lap_width = font->getDimension(L"99/99").Width; + else + m_lap_width = font->getDimension(L"9/9").Width; // Originally m_map_height was 100, and we take 480 as minimum res - const float scaling = irr_driver->getFrameSize().Height / 480.0f; + float scaling = irr_driver->getFrameSize().Height / 480.0f; + const float map_size = 100.0f; + const float top_margin = 3.5f * m_font_height; + + // Check if we have enough space for minimap when touch steering is enabled + if (UserConfigParams::m_multitouch_enabled) + { + const float map_bottom = (float)(m_multitouch_gui->getMinimapBottom()); + + 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)( 14.0f * scaling); m_minimap_player_size = (int)( 16.0f * scaling); - m_map_width = (int)(100.0f * scaling); - m_map_height = (int)(100.0f * scaling); + m_map_width = (int)(map_size * scaling); + m_map_height = (int)(map_size * scaling); m_map_left = (int)( 10.0f * scaling); m_map_bottom = (int)( 10.0f * scaling); @@ -91,8 +116,10 @@ RaceGUI::RaceGUI() } else if (UserConfigParams::m_multitouch_enabled) { - m_map_left = irr_driver->getActualScreenSize().Width - m_map_width; - m_map_bottom = int(irr_driver->getActualScreenSize().Height * 0.55f); + 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); } m_is_tutorial = (race_manager->getTrackName() == "tutorial"); @@ -100,37 +127,11 @@ RaceGUI::RaceGUI() m_speed_meter_icon = material_manager->getMaterial("speedback.png"); m_speed_bar_icon = material_manager->getMaterial("speedfore.png"); //createMarkerTexture(); - - // Determine maximum length of the rank/lap text, in order to - // align those texts properly on the right side of the viewport. - gui::ScalableFont* font = GUIEngine::getHighresDigitFont(); - core::dimension2du area = font->getDimension(L"99:99:99"); - m_timer_width = area.Width; - m_font_height = area.Height; - - if (race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER || - race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES || - race_manager->getNumLaps() > 9) - m_lap_width = font->getDimension(L"99/99").Width; - else - m_lap_width = font->getDimension(L"9/9").Width; - - if (UserConfigParams::m_multitouch_enabled) - { - initMultitouchSteering(); - } } // RaceGUI //----------------------------------------------------------------------------- RaceGUI::~RaceGUI() { - MultitouchDevice* device = input_manager->getDeviceManager()-> - getMultitouchDevice(); - - if (device != NULL) - { - device->clearButtons(); - } } // ~Racegui @@ -229,22 +230,19 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt) { if (!m_enabled) return; + RaceGUIBase::renderPlayerView(camera, dt); + const core::recti &viewport = camera->getViewport(); core::vector2df scaling = camera->getScaling(); const AbstractKart *kart = camera->getKart(); if(!kart) return; - + drawPlungerInFace(camera, dt); scaling *= viewport.getWidth()/800.0f; // scale race GUI along screen size drawAllMessages(kart, viewport, scaling); - if (UserConfigParams::m_multitouch_enabled) - { - drawMultitouchSteering(kart, viewport, scaling); - } - if(!World::getWorld()->isRacePhase()) return; drawPowerupIcons(kart, viewport, scaling); @@ -256,8 +254,6 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt) if (!m_is_tutorial) drawLap(kart, viewport, scaling); - - RaceGUIBase::renderPlayerView(camera, dt); } // renderPlayerView //----------------------------------------------------------------------------- @@ -899,160 +895,3 @@ void RaceGUI::drawLap(const AbstractKart* kart, font->setScale(1.0f); } // 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, - int(0.5f * margin), int(h - 0.5f * margin - btn2_size), - int(btn2_size), int(btn2_size)); - device->addButton(BUTTON_ESCAPE, - int(top_margin), int(small_ratio * margin), - int(small_ratio * btn_size), int(small_ratio * btn_size)); - device->addButton(BUTTON_RESCUE, - int(top_margin + small_ratio * col_size), - int(small_ratio * margin), - int(small_ratio * btn_size), int(small_ratio * btn_size)); - device->addButton(BUTTON_NITRO, - int(w - 1 * col_size), int(h - 2 * col_size), - int(btn_size), int(btn_size)); - device->addButton(BUTTON_SKIDDING, - int(w - 1 * col_size), int(h - 1 * col_size), - int(btn_size), int(btn_size)); - device->addButton(BUTTON_FIRE, - int(w - 2 * col_size), int(h - 2 * col_size), - int(btn_size), int(btn_size)); - device->addButton(BUTTON_LOOK_BACKWARDS, - int(w - 2 * col_size), int(h - 1 * col_size), - int(btn_size), int(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) -{ -#ifndef SERVER_ONLY - 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 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 coords(core::position2d(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 pos2(int(round(x - w)), int(round(y - h)), - int(round(x + w)), int(round(y + h)) ); - - draw2DImage(tex, pos2, coords, NULL, NULL, true); - } - else - { - if (button->pressed) - { - core::rect pos2(int(button->x - button->width * 0.2f), - int(button->y - button->height * 0.2f), - int(button->x + button->width * 1.2f), - int(button->y + button->height * 1.2f) ); - - video::ITexture* tex = irr_driver->getTexture(FileManager::GUI, - "icons-frame.png"); - core::rect coords(core::position2d(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 coords(core::position2d(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)); - } - } - } -#endif -} // drawMultitouchSteering diff --git a/src/states_screens/race_gui.hpp b/src/states_screens/race_gui.hpp index 49b9a5c27..93e7e31e3 100644 --- a/src/states_screens/race_gui.hpp +++ b/src/states_screens/race_gui.hpp @@ -94,8 +94,6 @@ private: bool m_is_tutorial; - void initMultitouchSteering(); - /* Display informat for one player on the screen. */ void drawEnergyMeter (int x, int y, const AbstractKart *kart, const core::recti &viewport, @@ -110,9 +108,6 @@ private: const core::vector2df &offset, float min_ratio, int meter_width, 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). */ void drawGlobalMiniMap (); diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index 3320508f6..e65cdbb0f 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -42,6 +42,7 @@ #include "karts/rescue_animation.hpp" #include "modes/linear_world.hpp" #include "modes/world.hpp" +#include "states_screens/race_gui_multitouch.hpp" #include "tracks/track.hpp" #include "utils/constants.hpp" @@ -99,6 +100,13 @@ RaceGUIBase::RaceGUIBase() m_icons_inertia = 2; m_referee = NULL; + m_multitouch_gui = NULL; + + if (UserConfigParams::m_multitouch_enabled && + race_manager->getNumLocalPlayers() == 1) + { + m_multitouch_gui = new RaceGUIMultitouch(this); + } } // RaceGUIBase // ---------------------------------------------------------------------------- @@ -147,7 +155,6 @@ void RaceGUIBase::reset() m_referee_height = 10.0f; m_referee->attachToSceneNode(); m_referee->selectReadySetGo(0); // set red color - m_plunger_move_time = 0; m_plunger_offset = core::vector2di(0,0); m_plunger_speed = core::vector2df(0,0); @@ -165,6 +172,7 @@ RaceGUIBase::~RaceGUIBase() // If the referee is currently being shown, // remove it from the scene graph. delete m_referee; + delete m_multitouch_gui; } // ~RaceGUIBase //----------------------------------------------------------------------------- @@ -435,7 +443,15 @@ void RaceGUIBase::preRenderCallback(const Camera *camera) // ---------------------------------------------------------------------------- void RaceGUIBase::renderPlayerView(const Camera *camera, float dt) { - + const core::recti &viewport = camera->getViewport(); + const core::vector2df scaling = camera->getScaling(); + const AbstractKart* kart = camera->getKart(); + if(!kart) return; + + if (m_multitouch_gui != NULL) + { + m_multitouch_gui->drawMultitouchSteering(kart, viewport, scaling); + } } // renderPlayerView diff --git a/src/states_screens/race_gui_base.hpp b/src/states_screens/race_gui_base.hpp index 3e53a51f8..30dbec35f 100644 --- a/src/states_screens/race_gui_base.hpp +++ b/src/states_screens/race_gui_base.hpp @@ -39,6 +39,7 @@ class AbstractKart; class Camera; class Material; class Referee; +class RaceGUIMultitouch; /** * \brief An abstract base class for the two race guis (race_gui and @@ -139,7 +140,7 @@ private: /** The referee scene node. */ Referee *m_referee; - + protected: /** Material for the 'plunger in the face' texture. */ @@ -178,6 +179,8 @@ protected: /** The frame around player karts in the mini map. */ Material *m_icons_frame; + + RaceGUIMultitouch* m_multitouch_gui; void cleanupMessages(const float dt); //void createMarkerTexture(); @@ -237,6 +240,10 @@ public: virtual void clearAllMessages() { m_messages.clear(); } void drawGlobalPlayerIcons(int bottom_margin); + + virtual void drawEnergyMeter(int x, int y, const AbstractKart *kart, + const core::recti &viewport, + const core::vector2df &scaling) {}; }; // RaceGUIBase diff --git a/src/states_screens/race_gui_multitouch.cpp b/src/states_screens/race_gui_multitouch.cpp new file mode 100644 index 000000000..547ea10e7 --- /dev/null +++ b/src/states_screens/race_gui_multitouch.cpp @@ -0,0 +1,237 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2014-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 "states_screens/race_gui_multitouch.hpp" + +using namespace irr; + +#include + +#include "config/user_config.hpp" +#include "graphics/camera.hpp" +#include "graphics/2dutils.hpp" +#include "graphics/irr_driver.hpp" +#include "input/device_manager.hpp" +#include "input/multitouch_device.hpp" +#include "karts/abstract_kart.hpp" +#include "states_screens/race_gui_base.hpp" + + +//----------------------------------------------------------------------------- +/** The multitouch GUI constructor + */ +RaceGUIMultitouch::RaceGUIMultitouch(RaceGUIBase* race_gui) +{ + m_race_gui = race_gui; + m_minimap_bottom = 0; + + m_device = input_manager->getDeviceManager()->getMultitouchDevice(); + + if (UserConfigParams::m_multitouch_scale > 1.5f) + { + UserConfigParams::m_multitouch_scale = 1.5f; + } + else if (UserConfigParams::m_multitouch_scale < 0.5f) + { + UserConfigParams::m_multitouch_scale = 0.5f; + } + + initMultitouchSteering(); +} // RaceGUIMultitouch + + +//----------------------------------------------------------------------------- +/** The multitouch GUI destructor + */ +RaceGUIMultitouch::~RaceGUIMultitouch() +{ + closeMultitouchSteering(); +} // ~RaceGUIMultitouch + + +//----------------------------------------------------------------------------- +/** Clears all previously created buttons in the multitouch device + */ +void RaceGUIMultitouch::closeMultitouchSteering() +{ + if (m_device != NULL) + { + m_device->clearButtons(); + } +} // closeMultitouchSteering + + +//----------------------------------------------------------------------------- +/** Makes some initializations and determines the look of multitouch steering + * interface + */ +void RaceGUIMultitouch::initMultitouchSteering() +{ + if (m_device == NULL) + return; + + const float scale = UserConfigParams::m_multitouch_scale; + + const int w = irr_driver->getActualScreenSize().Width; + const int h = irr_driver->getActualScreenSize().Height; + const float btn_size = 0.1f * h * scale; + const float btn2_size = 0.35f * h * scale; + const float margin = 0.1f * h * scale; + const float top_margin = 0.3f * h; + const float col_size = (btn_size + margin); + const float small_ratio = 0.6f; + + m_minimap_bottom = (unsigned int)(h - 2 * col_size); + + m_device->addButton(BUTTON_STEERING, + int(0.5f * margin), int(h - 0.5f * margin - btn2_size), + int(btn2_size), int(btn2_size)); + m_device->addButton(BUTTON_ESCAPE, + int(top_margin), int(small_ratio * margin), + int(small_ratio * btn_size), int(small_ratio * btn_size)); + m_device->addButton(BUTTON_RESCUE, + int(top_margin + small_ratio * col_size), + int(small_ratio * margin), + int(small_ratio * btn_size), int(small_ratio * btn_size)); + m_device->addButton(BUTTON_NITRO, + int(w - 1 * col_size), int(h - 2 * col_size), + int(btn_size), int(btn_size)); + m_device->addButton(BUTTON_SKIDDING, + int(w - 1 * col_size), int(h - 1 * col_size), + int(btn_size), int(btn_size)); + m_device->addButton(BUTTON_FIRE, + int(w - 2 * col_size), int(h - 2 * col_size), + int(btn_size), int(btn_size)); + m_device->addButton(BUTTON_LOOK_BACKWARDS, + int(w - 2 * col_size), int(h - 1 * col_size), + int(btn_size), int(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 RaceGUIMultitouch::drawMultitouchSteering(const AbstractKart* kart, + const core::recti &viewport, + const core::vector2df &scaling) +{ +#ifndef SERVER_ONLY + if (m_device == NULL) + return; + + for (unsigned int i = 0; i < m_device->getButtonsCount(); i++) + { + MultitouchButton* button = m_device->getButton(i); + + core::rect 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 coords(core::position2d(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 pos2(int(round(x - w)), int(round(y - h)), + int(round(x + w)), int(round(y + h)) ); + + draw2DImage(tex, pos2, coords, NULL, NULL, true); + } + else + { + if (button->pressed) + { + core::rect pos2(int(button->x - button->width * 0.2f), + int(button->y - button->height * 0.2f), + int(button->x + button->width * 1.2f), + int(button->y + button->height * 1.2f) ); + + video::ITexture* tex = irr_driver->getTexture(FileManager::GUI, + "icons-frame.png"); + core::rect coords(core::position2d(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 coords(core::position2d(0,0), tex->getSize()); + draw2DImage(tex, pos, coords, NULL, NULL, true); + + if (button->type == MultitouchButtonType::BUTTON_NITRO) + { + float scale = UserConfigParams::m_multitouch_scale * + (float)(irr_driver->getActualScreenSize().Height) / 1600.0f; + + if (m_race_gui != NULL) + { + m_race_gui->drawEnergyMeter(button->x + button->width, + button->y + button->height, + kart, viewport, + core::vector2df(scale, scale)); + } + } + } + } +#endif +} // drawMultitouchSteering diff --git a/src/states_screens/race_gui_multitouch.hpp b/src/states_screens/race_gui_multitouch.hpp new file mode 100644 index 000000000..744229626 --- /dev/null +++ b/src/states_screens/race_gui_multitouch.hpp @@ -0,0 +1,54 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2014-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_RACE_GUI_MULTITOUCH_HPP +#define HEADER_RACE_GUI_MULTITOUCH_HPP + +#include +#include +#include +using namespace irr; + +class AbstractKart; +class MultitouchDevice; +class RaceGUIBase; + +class RaceGUIMultitouch +{ +private: + RaceGUIBase* m_race_gui; + MultitouchDevice* m_device; + + unsigned int m_minimap_bottom; + + + void initMultitouchSteering(); + void closeMultitouchSteering(); + +public: + RaceGUIMultitouch(RaceGUIBase* race_gui); + ~RaceGUIMultitouch(); + + void drawMultitouchSteering(const AbstractKart* kart, + const core::recti &viewport, + const core::vector2df &scaling); + + unsigned int getMinimapBottom() {return m_minimap_bottom;} + +}; // RaceGUIMultitouch + +#endif diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index 5ed8ac3bd..1c6106dba 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -46,6 +46,7 @@ #include "modes/world.hpp" #include "race/grand_prix_manager.hpp" #include "race/race_manager.hpp" +#include "states_screens/race_gui_multitouch.hpp" #include "tracks/track.hpp" #include "tracks/track_manager.hpp" #include "utils/constants.hpp" @@ -78,13 +79,26 @@ RaceGUIOverworld::RaceGUIOverworld() m_trophy2 = irr_driver->getTexture(FileManager::GUI, "cup_silver.png"); m_trophy3 = irr_driver->getTexture(FileManager::GUI, "cup_gold.png" ); - const float scaling = irr_driver->getFrameSize().Height / 420.0f; + float scaling = irr_driver->getFrameSize().Height / 420.0f; + const float map_size = 250.0f; + + // Check if we have enough space for minimap when touch steering is enabled + if (UserConfigParams::m_multitouch_enabled) + { + const float map_bottom = (float)(m_multitouch_gui->getMinimapBottom()); + + 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)(250.0f * scaling); - m_map_height = (int)(250.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; @@ -100,6 +114,12 @@ RaceGUIOverworld::RaceGUIOverworld() { m_map_left = irr_driver->getActualScreenSize().Width - m_map_width; } + else if (UserConfigParams::m_multitouch_enabled) + { + m_map_left = (int)((irr_driver->getActualScreenSize().Width - + m_map_width) * 0.9f); + m_map_bottom = m_map_height + 10 * scaling; + } m_speed_meter_icon = material_manager->getMaterial("speedback.png"); m_speed_bar_icon = material_manager->getMaterial("speedfore.png"); @@ -169,7 +189,10 @@ void RaceGUIOverworld::renderGlobal(float dt) if(!world->isRacePhase()) return; if (!m_enabled) return; - drawTrophyPoints(); + if (!UserConfigParams::m_multitouch_enabled) + { + drawTrophyPoints(); + } // minimap has no mipmaps so disable material2D //irr_driver->getVideoDriver()->enableMaterial2D(false); @@ -188,9 +211,12 @@ void RaceGUIOverworld::renderGlobal(float dt) void RaceGUIOverworld::renderPlayerView(const Camera *camera, float dt) { if (!m_enabled) return; + + RaceGUIBase::renderPlayerView(camera, dt); + const AbstractKart *kart = camera->getKart(); if(!kart) return; - + const core::recti &viewport = camera->getViewport(); core::vector2df scaling = camera->getScaling(); //Log::info("RaceGUIOverworld", "Applied ratio: %f", viewport.getWidth()/800.0f); @@ -204,8 +230,6 @@ void RaceGUIOverworld::renderPlayerView(const Camera *camera, float dt) if(!World::getWorld()->isRacePhase()) return; drawPowerupIcons (kart, viewport, scaling); - - RaceGUIBase::renderPlayerView(camera, dt); } // renderPlayerView //----------------------------------------------------------------------------- @@ -305,7 +329,6 @@ void RaceGUIOverworld::drawGlobalMiniMap() // arenas currently don't have a map. Track* track = Track::getCurrentTrack(); if(track->isArena() || track->isSoccer()) return; - const std::vector& challenges = track->getChallengeList(); @@ -317,13 +340,24 @@ void RaceGUIOverworld::drawGlobalMiniMap() if(m_is_first_render_call) { float left_most = 0; + float right_most = 0; + for (unsigned int n=0; nmapPoint2MiniMap(challenges[n].m_position, &draw_at); if(draw_at.getX()right_most) right_most = draw_at.getX(); + } + + if (UserConfigParams::m_multitouch_enabled) + { + m_map_left += m_map_width - (int)right_most; + } + else + { + m_map_left -= (int)left_most; } - m_map_left -= (int)left_most; } int upper_y = m_map_bottom - m_map_height; @@ -545,74 +579,4 @@ void RaceGUIOverworld::drawGlobalMiniMap() } // drawGlobalMiniMap //----------------------------------------------------------------------------- -/** Energy meter that gets filled with nitro. This function is called from - * drawSpeedAndEnergy, which defines the correct position of the energy - * meter. - * \param x X position of the meter. - * \param y Y position of the meter. - * \param kart Kart to display the data for. - * \param scaling Scaling applied (in case of split screen) - */ -void RaceGUIOverworld::drawEnergyMeter(int x, int y, const AbstractKart *kart, - const core::recti &viewport, - const core::vector2df &scaling) -{ -#ifndef SERVER_ONLY - float state = (float)(kart->getEnergy()) - / kart->getKartProperties()->getNitroMax(); - if (state < 0.0f) state = 0.0f; - else if (state > 1.0f) state = 1.0f; - - int h = (int)(viewport.getHeight()/3); - int w = h/4; // gauge image is so 1:4 - - y -= h; - - x -= w; - - // Background - draw2DImage(m_gauge_empty, core::rect(x, y, x+w, y+h) /* dest rect */, - core::rect(0, 0, 64, 256) /* source rect */, - NULL /* clip rect */, NULL /* colors */, - true /* alpha */); - - // Target - if (race_manager->getCoinTarget() > 0) - { - float coin_target = (float)race_manager->getCoinTarget() - / kart->getKartProperties()->getNitroMax(); - - const int EMPTY_TOP_PIXELS = 4; - const int EMPTY_BOTTOM_PIXELS = 3; - int y1 = y + (int)(EMPTY_TOP_PIXELS + - (h - EMPTY_TOP_PIXELS - EMPTY_BOTTOM_PIXELS) - *(1.0f - coin_target) ); - if (state >= 1.0f) y1 = y; - - core::rect clip(x, y1, x + w, y + h); - draw2DImage(m_gauge_goal, core::rect(x, y, x+w, y+h) /* dest rect */, - core::rect(0, 0, 64, 256) /* source rect */, - &clip, NULL /* colors */, true /* alpha */); - } - - // Filling (current state) - if (state > 0.0f) - { - const int EMPTY_TOP_PIXELS = 4; - const int EMPTY_BOTTOM_PIXELS = 3; - int y1 = y + (int)(EMPTY_TOP_PIXELS - + (h - EMPTY_TOP_PIXELS - EMPTY_BOTTOM_PIXELS) - *(1.0f - state) ); - if (state >= 1.0f) y1 = y; - - core::rect clip(x, y1, x + w, y + h); - draw2DImage(m_gauge_full, core::rect(x, y, x+w, y+h) /* dest rect */, - core::rect(0, 0, 64, 256) /* source rect */, - &clip, NULL /* colors */, true /* alpha */); - } - -#endif -} // drawEnergyMeter - -//----------------------------------------------------------------------------- diff --git a/src/states_screens/race_gui_overworld.hpp b/src/states_screens/race_gui_overworld.hpp index 56d72823b..3779d5371 100644 --- a/src/states_screens/race_gui_overworld.hpp +++ b/src/states_screens/race_gui_overworld.hpp @@ -109,11 +109,6 @@ private: /** The current challenge over which the mouse is hovering. */ const OverworldChallenge *m_current_challenge; - /* Display informat for one player on the screen. */ - void drawEnergyMeter (int x, int y, const AbstractKart *kart, - const core::recti &viewport, - const core::vector2df &scaling); - /** Display items that are shown once only (for all karts). */ void drawGlobalMiniMap (); void drawTrophyPoints (); From 2b13a5643e9a4044a017b41d65f95c49a3f5e864 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sat, 17 Dec 2016 17:43:03 -0500 Subject: [PATCH 5/6] Ignore the "applesmc" accelerator as input device. see #2691 --- src/input/device_manager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index 83c8a51e1..e5fc6f144 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -100,8 +100,9 @@ bool DeviceManager::initialize() { core::stringc name = m_irrlicht_gamepads[id].Name; - // Some linux systems report a disk accelerometer as a gamepad, skip that + // Some systems report a disk accelerometer as a gamepad, skip that if (name.find("LIS3LV02DL") != -1) continue; + if (name == "applesmc") continue; if(m_irrlicht_gamepads[id].HasGenericName) { From da795b69edb094e395da09e403368d60136eafd3 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sat, 17 Dec 2016 18:49:00 -0500 Subject: [PATCH 6/6] Better fix for #2687 --- src/graphics/camera.cpp | 2 +- src/modes/follow_the_leader.cpp | 13 ------------- src/modes/three_strikes_battle.cpp | 7 ------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index f84f8f8bd..d70d5f419 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -94,7 +94,7 @@ void Camera::changeCamera(unsigned int camera_index, CameraType type) if(old_camera->getType()==type) return; Camera *new_camera = createCamera(old_camera->getIndex(), type, - old_camera->m_kart ); + old_camera->m_original_kart); // Replace the previous camera m_all_cameras[camera_index] = new_camera; if(s_active_camera == old_camera) diff --git a/src/modes/follow_the_leader.cpp b/src/modes/follow_the_leader.cpp index e8f0303d7..06cf0b461 100644 --- a/src/modes/follow_the_leader.cpp +++ b/src/modes/follow_the_leader.cpp @@ -85,19 +85,6 @@ void FollowTheLeaderRace::reset() WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN, m_leader_intervals[0]); - const unsigned int kart_amount = (unsigned int)m_karts.size(); - int idCamera = 0; - for (unsigned int n = 1; n < kart_amount; n++) - { - if (m_karts[n]->getController()->isPlayerController()) - { - Camera *camera = Camera::getCamera(idCamera); - camera->setMode(Camera::CM_NORMAL); - camera->setKart(getKart(n)); - idCamera++; - } - } - m_is_over_delay = 2.0f; } // reset diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 3297723b7..edb21c57f 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -118,13 +118,6 @@ void ThreeStrikesBattle::reset() // no positions in this mode m_karts[n]->setPosition(-1); - if (m_karts[n]->getController()->isPlayerController()) - { - Camera *camera = Camera::getCamera(idCamera); - camera->setKart(m_karts[n]); - idCamera++; - } - scene::ISceneNode* kart_node = m_karts[n]->getNode(); core::list& children = kart_node->getChildren();