]> git.lizzy.rs Git - minetest.git/commitdiff
Add crosshair support for Android (#7865)
authorMuhammad Rifqi Priyo Susanto <muhammadrifqipriyosusanto@gmail.com>
Thu, 29 Sep 2022 18:30:33 +0000 (01:30 +0700)
committerGitHub <noreply@github.com>
Thu, 29 Sep 2022 18:30:33 +0000 (20:30 +0200)
If enabled, a crosshair will be shown to select object.
This will give Android players a way to play like they play on desktop.
On third-person back camera mode, player is forced to use crosshair.
On third-person front camera mode, player is unable to select anything.

Co-authored-by: ROllerozxa <temporaryemail4meh+github@gmail.com>
Co-authored-by: rubenwardy <rw@rubenwardy.com>
builtin/mainmenu/tab_settings.lua
builtin/settingtypes.txt
src/client/game.cpp
src/defaultsettings.cpp
src/gui/touchscreengui.cpp
src/gui/touchscreengui.h

index 21c77aa8eb0a688bb8bdf171c909aac62b6ff036..ec2d7b1f55138150beaf8093e553b18204997c0b 100644 (file)
@@ -308,10 +308,6 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
                core.show_keys_menu()
                return true
        end
-       if fields["cb_touchscreen_target"] then
-               core.settings:set("touchtarget", fields["cb_touchscreen_target"])
-               return true
-       end
 
        --Note dropdowns have to be handled LAST!
        local ddhandled = false
index 7376c0cb70f8b9349a52ce0719bb45240b242020..91cc3ec32a3dc96726f180d747a315fc584f2400 100644 (file)
@@ -117,6 +117,10 @@ mouse_sensitivity (Mouse sensitivity) float 0.2 0.001 10.0
 #    The length in pixels it takes for touch screen interaction to start.
 touchscreen_threshold (Touch screen threshold) int 20 0 100
 
+#    Use crosshair to select object instead of whole screen.
+#    If enabled, a crosshair will be shown and will be used for selecting object.
+touch_use_crosshair (Use crosshair for touch screen) bool false
+
 #    (Android) Fixes the position of virtual joystick.
 #    If disabled, virtual joystick will center to first-touch's position.
 fixed_virtual_joystick (Fixed virtual joystick) bool false
index acf54d557116bd7988686a7f44082d84411cc416..d484e81933ac1ae0dde88ce9235a138718bb8190 100644 (file)
@@ -920,6 +920,10 @@ class Game {
 
 #ifdef HAVE_TOUCHSCREENGUI
        bool m_cache_hold_aux1;
+       bool m_touch_use_crosshair;
+       inline bool isNoCrosshairAllowed() {
+               return !m_touch_use_crosshair && camera->getCameraMode() == CAMERA_MODE_FIRST;
+       }
 #endif
 #ifdef __ANDROID__
        bool m_android_chat_open;
@@ -1051,6 +1055,10 @@ bool Game::startup(bool *kill,
        m_invert_mouse = g_settings->getBool("invert_mouse");
        m_first_loop_after_window_activation = true;
 
+#ifdef HAVE_TOUCHSCREENGUI
+       m_touch_use_crosshair = g_settings->getBool("touch_use_crosshair");
+#endif
+
        g_client_translations->clear();
 
        // address can change if simple_singleplayer_mode
@@ -2981,6 +2989,11 @@ void Game::updateCamera(f32 dtime)
 
                camera->toggleCameraMode();
 
+#ifdef HAVE_TOUCHSCREENGUI
+               if (g_touchscreengui)
+                       g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
+#endif
+
                // Make the player visible depending on camera mode.
                playercao->updateMeshCulling();
                playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
@@ -3091,16 +3104,14 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
        shootline.end = shootline.start + camera_direction * BS * d;
 
 #ifdef HAVE_TOUCHSCREENGUI
-
-       if ((g_settings->getBool("touchtarget")) && (g_touchscreengui)) {
+       if (g_touchscreengui && isNoCrosshairAllowed()) {
                shootline = g_touchscreengui->getShootline();
                // Scale shootline to the acual distance the player can reach
-               shootline.end = shootline.start
-                       + shootline.getVector().normalize() * BS * d;
+               shootline.end = shootline.start +
+                               shootline.getVector().normalize() * BS * d;
                shootline.start += intToFloat(camera_offset, BS);
                shootline.end += intToFloat(camera_offset, BS);
        }
-
 #endif
 
        PointedThing pointed = updatePointedThing(shootline,
@@ -3991,10 +4002,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                        (player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
                        (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
 #ifdef HAVE_TOUCHSCREENGUI
-       try {
-               draw_crosshair = !g_settings->getBool("touchtarget");
-       } catch (SettingNotFoundException) {
-       }
+       if (isNoCrosshairAllowed())
+               draw_crosshair = false;
 #endif
        m_rendering_engine->draw_scene(skycolor, m_game_ui->m_flags.show_hud,
                        m_game_ui->m_flags.show_minimap, draw_wield_tool, draw_crosshair);
index f96149070213a0416cc2f902e44e11c4ab1f6217..bc1c98988460dfe8fc32d2583c31d6f294896499 100644 (file)
@@ -465,8 +465,8 @@ void set_default_settings()
 #endif
 
 #ifdef HAVE_TOUCHSCREENGUI
-       settings->setDefault("touchtarget", "true");
        settings->setDefault("touchscreen_threshold","20");
+       settings->setDefault("touch_use_crosshair", "false");
        settings->setDefault("fixed_virtual_joystick", "false");
        settings->setDefault("virtual_joystick_triggers_aux1", "false");
        settings->setDefault("clickable_chat_weblinks", "false");
index d483c136e56a11e80827f2ed3b4739da34125750..b2a4b489a53e002eee67c8087dd1ab0e03698fa9 100644 (file)
@@ -684,6 +684,10 @@ void TouchScreenGUI::handleReleaseEvent(size_t evt_id)
                        translated->MouseInput.Control      = false;
                        translated->MouseInput.ButtonStates = 0;
                        translated->MouseInput.Event        = EMIE_LMOUSE_LEFT_UP;
+                       if (m_draw_crosshair) {
+                               translated->MouseInput.X = m_screensize.X / 2;
+                               translated->MouseInput.Y = m_screensize.Y / 2;
+                       }
                        m_receiver->OnEvent(*translated);
                        delete translated;
                } else {
@@ -805,6 +809,8 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                                        m_move_downtime            = porting::getTimeMs();
                                        m_move_downlocation        = v2s32(event.TouchInput.X, event.TouchInput.Y);
                                        m_move_sent_as_mouse_event = false;
+                                       if (m_draw_crosshair)
+                                               m_move_downlocation = v2s32(m_screensize.X / 2, m_screensize.Y / 2);
                                }
                        }
                }
@@ -823,9 +829,8 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                        return;
 
                if (m_has_move_id) {
-                       if ((event.TouchInput.ID == m_move_id) &&
-                               (!m_move_sent_as_mouse_event)) {
-
+                       if (event.TouchInput.ID == m_move_id &&
+                                       (!m_move_sent_as_mouse_event || m_draw_crosshair)) {
                                double distance = sqrt(
                                                (m_pointerpos[event.TouchInput.ID].X - event.TouchInput.X) *
                                                (m_pointerpos[event.TouchInput.ID].X - event.TouchInput.X) +
@@ -841,6 +846,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                                        // update camera_yaw and camera_pitch
                                        s32 dx = X - m_pointerpos[event.TouchInput.ID].X;
                                        s32 dy = Y - m_pointerpos[event.TouchInput.ID].Y;
+                                       m_pointerpos[event.TouchInput.ID] = v2s32(X, Y);
 
                                        // adapt to similar behaviour as pc screen
                                        const double d = g_settings->getFloat("mouse_sensitivity", 0.001f, 10.0f) * 3.0f;
@@ -849,11 +855,11 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
                                        m_camera_pitch = MYMIN(MYMAX(m_camera_pitch + (dy * d), -180), 180);
 
                                        // update shootline
+                                       // no need to update (X, Y) when using crosshair since the shootline is not used
                                        m_shootline = m_device
                                                        ->getSceneManager()
                                                        ->getSceneCollisionManager()
                                                        ->getRayFromScreenCoordinates(v2s32(X, Y));
-                                       m_pointerpos[event.TouchInput.ID] = v2s32(X, Y);
                                }
                        } else if ((event.TouchInput.ID == m_move_id) &&
                                        (m_move_sent_as_mouse_event)) {
@@ -1010,11 +1016,17 @@ bool TouchScreenGUI::doubleTapDetection()
        if (distance > (20 + m_touchscreen_threshold))
                return false;
 
+       v2s32 mPos = v2s32(m_key_events[0].x, m_key_events[0].y);
+       if (m_draw_crosshair) {
+               mPos.X = m_screensize.X / 2;
+               mPos.Y = m_screensize.Y / 2;
+       }
+
        auto *translated = new SEvent();
        memset(translated, 0, sizeof(SEvent));
        translated->EventType               = EET_MOUSE_INPUT_EVENT;
-       translated->MouseInput.X            = m_key_events[0].x;
-       translated->MouseInput.Y            = m_key_events[0].y;
+       translated->MouseInput.X            = mPos.X;
+       translated->MouseInput.Y            = mPos.Y;
        translated->MouseInput.Shift        = false;
        translated->MouseInput.Control      = false;
        translated->MouseInput.ButtonStates = EMBSM_RIGHT;
@@ -1023,7 +1035,7 @@ bool TouchScreenGUI::doubleTapDetection()
        m_shootline = m_device
                        ->getSceneManager()
                        ->getSceneCollisionManager()
-                       ->getRayFromScreenCoordinates(v2s32(m_key_events[0].x, m_key_events[0].y));
+                       ->getRayFromScreenCoordinates(mPos);
 
        translated->MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN;
        verbosestream << "TouchScreenGUI::translateEvent right click press" << std::endl;
@@ -1124,17 +1136,23 @@ void TouchScreenGUI::step(float dtime)
                u64 delta = porting::getDeltaMs(m_move_downtime, porting::getTimeMs());
 
                if (delta > MIN_DIG_TIME_MS) {
+                       s32 mX = m_move_downlocation.X;
+                       s32 mY = m_move_downlocation.Y;
+                       if (m_draw_crosshair) {
+                               mX = m_screensize.X / 2;
+                               mY = m_screensize.Y / 2;
+                       }
                        m_shootline = m_device
                                        ->getSceneManager()
                                        ->getSceneCollisionManager()
                                        ->getRayFromScreenCoordinates(
-                                                       v2s32(m_move_downlocation.X,m_move_downlocation.Y));
+                                                       v2s32(mX, mY));
 
                        SEvent translated;
                        memset(&translated, 0, sizeof(SEvent));
                        translated.EventType               = EET_MOUSE_INPUT_EVENT;
-                       translated.MouseInput.X            = m_move_downlocation.X;
-                       translated.MouseInput.Y            = m_move_downlocation.Y;
+                       translated.MouseInput.X            = mX;
+                       translated.MouseInput.Y            = mY;
                        translated.MouseInput.Shift        = false;
                        translated.MouseInput.Control      = false;
                        translated.MouseInput.ButtonStates = EMBSM_LEFT;
index 6b36c0d599eaab0ed34eb357acc90bdcbe600a77..82d6a4a9c8358652c1700136272b4bbfc219b3ea 100644 (file)
@@ -194,6 +194,7 @@ class TouchScreenGUI
        void step(float dtime);
        void resetHud();
        void registerHudItem(int index, const rect<s32> &rect);
+       inline void setUseCrosshair(bool use_crosshair) { m_draw_crosshair = use_crosshair; }
        void Toggle(bool visible);
 
        void hide();
@@ -240,6 +241,7 @@ class TouchScreenGUI
        bool m_joystick_has_really_moved = false;
        bool m_fixed_joystick = false;
        bool m_joystick_triggers_aux1 = false;
+       bool m_draw_crosshair = false;
        button_info *m_joystick_btn_off = nullptr;
        button_info *m_joystick_btn_bg = nullptr;
        button_info *m_joystick_btn_center = nullptr;