diff --git a/src/client/game.cpp b/src/client/game.cpp index 12a39e6ee..b66716036 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -772,9 +772,10 @@ private: bool m_is_paused = false; bool m_touch_simulate_aux1 = false; - bool m_touch_use_crosshair; - inline bool isTouchCrosshairDisabled() { - return !m_touch_use_crosshair && camera->getCameraMode() == CAMERA_MODE_FIRST; + inline bool isTouchShootlineUsed() + { + return g_touchcontrols && g_touchcontrols->isShootlineAvailable() && + camera->getCameraMode() == CAMERA_MODE_FIRST; } #ifdef __ANDROID__ bool m_android_chat_open; @@ -823,8 +824,6 @@ Game::Game() : &settingChangedCallback, this); g_settings->registerChangedCallback("pause_on_lost_focus", &settingChangedCallback, this); - g_settings->registerChangedCallback("touch_use_crosshair", - &settingChangedCallback, this); readSettings(); } @@ -1380,10 +1379,8 @@ bool Game::initGui() gui_chat_console = make_irr(guienv, guienv->getRootGUIElement(), -1, chat_backend, client, &g_menumgr); - if (shouldShowTouchControls()) { + if (shouldShowTouchControls()) g_touchcontrols = new TouchControls(device, texture_src); - g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled()); - } return true; } @@ -2980,9 +2977,6 @@ void Game::updateCameraMode() if (player->allowed_camera_mode != CAMERA_MODE_ANY) camera->setCameraMode(player->allowed_camera_mode); - if (g_touchcontrols) - g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled()); - GenericCAO *playercao = player->getCAO(); if (playercao) { // Make the player visible depending on camera mode. @@ -3086,7 +3080,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud) } shootline.end = shootline.start + camera_direction * BS * d; - if (g_touchcontrols && isTouchCrosshairDisabled()) { + if (isTouchShootlineUsed()) { shootline = g_touchcontrols->getShootline(); // Scale shootline to the acual distance the player can reach shootline.end = shootline.start + @@ -4059,7 +4053,7 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats) (player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) && (this->camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT)); - if (g_touchcontrols && isTouchCrosshairDisabled()) + if (isTouchShootlineUsed()) draw_crosshair = false; this->m_rendering_engine->draw_scene(sky_color, this->m_game_ui->m_flags.show_hud, @@ -4139,10 +4133,6 @@ void Game::readSettings() m_invert_hotbar_mouse_wheel = g_settings->getBool("invert_hotbar_mouse_wheel"); m_does_lost_focus_pause_game = g_settings->getBool("pause_on_lost_focus"); - - m_touch_use_crosshair = g_settings->getBool("touch_use_crosshair"); - if (g_touchcontrols) - g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled()); } /****************************************************************************/ diff --git a/src/gui/touchcontrols.cpp b/src/gui/touchcontrols.cpp index 8a829d90e..7dd837d9e 100644 --- a/src/gui/touchcontrols.cpp +++ b/src/gui/touchcontrols.cpp @@ -142,6 +142,12 @@ static EKEY_CODE id_to_keycode(touch_gui_button_id id) std::string key = ""; switch (id) { + case dig_id: + key = "dig"; + break; + case place_id: + key = "place"; + break; case jump_id: key = "jump"; break; @@ -204,6 +210,7 @@ static EKEY_CODE id_to_keycode(touch_gui_button_id id) static const char *setting_names[] = { + "touch_use_crosshair", "touchscreen_threshold", "touch_long_tap_delay", "fixed_virtual_joystick", "virtual_joystick_triggers_aux1", "touch_layout", @@ -230,6 +237,7 @@ void TouchControls::settingChangedCallback(const std::string &name, void *data) void TouchControls::readSettings() { + m_use_crosshair = g_settings->getBool("touch_use_crosshair"); m_touchscreen_threshold = g_settings->getU16("touchscreen_threshold"); m_long_tap_delay = g_settings->getU16("touch_long_tap_delay"); m_fixed_joystick = g_settings->getBool("fixed_virtual_joystick"); @@ -542,10 +550,11 @@ void TouchControls::translateEvent(const SEvent &event) m_move_has_really_moved = false; m_move_downtime = porting::getTimeMs(); m_move_pos = touch_pos; - // DON'T reset m_tap_state here, otherwise many short taps - // will be ignored if you tap very fast. m_had_move_id = true; m_move_prevent_short_tap = prevent_short_tap; + + // DON'T reset m_tap_state here, otherwise many short taps + // will be ignored if you tap very fast. } } } @@ -663,15 +672,13 @@ void TouchControls::step(float dtime) // Since not only the pointer position, but also the player position and // thus the camera position can change, it doesn't suffice to update the // shootline when a touch event occurs. - // Note that the shootline isn't used if touch_use_crosshair is enabled. // Only updating when m_has_move_id means that the shootline will stay at // it's last in-world position when the player doesn't need it. - if (!m_draw_crosshair && (m_has_move_id || m_had_move_id)) { - v2s32 pointer_pos = getPointerPos(); + if (!m_use_crosshair && (m_has_move_id || m_had_move_id)) { m_shootline = m_device ->getSceneManager() ->getSceneCollisionManager() - ->getRayFromScreenCoordinates(pointer_pos); + ->getRayFromScreenCoordinates(m_move_pos); } m_had_move_id = false; } @@ -734,11 +741,11 @@ void TouchControls::releaseAll() // Release those manually too since the change initiated by // handleReleaseEvent will only be applied later by applyContextControls. if (m_dig_pressed) { - emitMouseEvent(EMIE_LMOUSE_LEFT_UP); + emitKeyboardEvent(id_to_keycode(dig_id), false); m_dig_pressed = false; } if (m_place_pressed) { - emitMouseEvent(EMIE_RMOUSE_LEFT_UP); + emitKeyboardEvent(id_to_keycode(place_id), false); m_place_pressed = false; } } @@ -753,31 +760,6 @@ void TouchControls::show() setVisible(true); } -v2s32 TouchControls::getPointerPos() -{ - if (m_draw_crosshair) - return v2s32(m_screensize.X / 2, m_screensize.Y / 2); - // We can't just use m_pointer_pos[m_move_id] because applyContextControls - // may emit release events after m_pointer_pos[m_move_id] is erased. - return m_move_pos; -} - -void TouchControls::emitMouseEvent(EMOUSE_INPUT_EVENT type) -{ - v2s32 pointer_pos = getPointerPos(); - - SEvent event{}; - event.EventType = EET_MOUSE_INPUT_EVENT; - event.MouseInput.X = pointer_pos.X; - event.MouseInput.Y = pointer_pos.Y; - event.MouseInput.Shift = false; - event.MouseInput.Control = false; - event.MouseInput.ButtonStates = 0; - event.MouseInput.Event = type; - event.MouseInput.Simulated = true; - m_receiver->OnEvent(event); -} - void TouchControls::applyContextControls(const TouchInteractionMode &mode) { // Since the pointed thing has already been determined when this function @@ -844,20 +826,20 @@ void TouchControls::applyContextControls(const TouchInteractionMode &mode) target_place_pressed |= now < m_place_pressed_until; if (target_dig_pressed && !m_dig_pressed) { - emitMouseEvent(EMIE_LMOUSE_PRESSED_DOWN); + emitKeyboardEvent(id_to_keycode(dig_id), true); m_dig_pressed = true; } else if (!target_dig_pressed && m_dig_pressed) { - emitMouseEvent(EMIE_LMOUSE_LEFT_UP); + emitKeyboardEvent(id_to_keycode(dig_id), false); m_dig_pressed = false; } if (target_place_pressed && !m_place_pressed) { - emitMouseEvent(EMIE_RMOUSE_PRESSED_DOWN); + emitKeyboardEvent(id_to_keycode(place_id), true); m_place_pressed = true; } else if (!target_place_pressed && m_place_pressed) { - emitMouseEvent(EMIE_RMOUSE_LEFT_UP); + emitKeyboardEvent(id_to_keycode(place_id), false); m_place_pressed = false; } } diff --git a/src/gui/touchcontrols.h b/src/gui/touchcontrols.h index ea71e2c86..9241e3252 100644 --- a/src/gui/touchcontrols.h +++ b/src/gui/touchcontrols.h @@ -93,6 +93,8 @@ public: return res; } + bool isShootlineAvailable() { return !m_use_crosshair; } + /** * Returns a line which describes what the player is pointing at. * The starting point and looking direction are significant, @@ -100,6 +102,9 @@ public: * the player can reach. * The line starts at the camera and ends on the camera's far plane. * The coordinates do not contain the camera offset. + * + * This may only be used if isShootlineAvailable returns true. + * Otherwise, the normal crosshair must be used. */ line3d getShootline() { return m_shootline; } @@ -107,7 +112,6 @@ public: float getJoystickSpeed() { return m_joystick_speed; } void step(float dtime); - inline void setUseCrosshair(bool use_crosshair) { m_draw_crosshair = use_crosshair; } void setVisible(bool visible); void hide(); @@ -132,6 +136,7 @@ private: s32 m_button_size; // cached settings + bool m_use_crosshair; double m_touchscreen_threshold; u16 m_long_tap_delay; bool m_fixed_joystick; @@ -143,9 +148,6 @@ private: ButtonLayout m_layout; void applyLayout(const ButtonLayout &layout); - // not read from a setting, but set by Game via setUseCrosshair - bool m_draw_crosshair = false; - std::unordered_map m_hotbar_rects; std::optional m_hotbar_selection = std::nullopt; @@ -157,6 +159,8 @@ private: * A line starting at the camera and pointing towards the selected object. * The line ends on the camera's far plane. * The coordinates do not contain the camera offset. + * + * Only valid if !m_use_crosshair */ line3d m_shootline; @@ -164,7 +168,9 @@ private: size_t m_move_id; bool m_move_has_really_moved = false; u64 m_move_downtime = 0; - // m_move_pos stays valid even after m_move_id has been released. + // m_move_pos stays valid even after the m_move_id pointer has been + // released and m_pointer_pos[m_move_id] has been erased + // (or even overwritten by a new pointer reusing the same id). v2s32 m_move_pos; // This is needed so that we don't miss if m_has_move_id is true for less // than one client step, i.e. press and release happen in the same step. @@ -236,8 +242,6 @@ private: // map to store the IDs and positions of currently pressed pointers std::unordered_map m_pointer_pos; - v2s32 getPointerPos(); - void emitMouseEvent(EMOUSE_INPUT_EVENT type); TouchInteractionMode m_last_mode = TouchInteractionMode_END; TapState m_tap_state = TapState::None; diff --git a/src/gui/touchscreenlayout.cpp b/src/gui/touchscreenlayout.cpp index 0a88f5dd5..e0ad5b723 100644 --- a/src/gui/touchscreenlayout.cpp +++ b/src/gui/touchscreenlayout.cpp @@ -14,6 +14,9 @@ #include "IGUIStaticText.h" const char *button_names[] = { + "dig", + "place", + "jump", "sneak", "zoom", @@ -41,6 +44,9 @@ const char *button_names[] = { // compare with GUIKeyChangeMenu::init_keys const char *button_titles[] = { + N_("Dig/punch/use"), + N_("Place/use"), + N_("Jump"), N_("Sneak"), N_("Zoom"), @@ -67,6 +73,9 @@ const char *button_titles[] = { }; const char *button_image_names[] = { + "", + "", + "jump_btn.png", "down.png", "zoom.png", @@ -123,7 +132,8 @@ void ButtonMeta::setPos(v2s32 pos, v2u32 screensize, s32 button_size) bool ButtonLayout::isButtonAllowed(touch_gui_button_id id) { - return id != joystick_off_id && id != joystick_bg_id && id != joystick_center_id && + return id != dig_id && id != place_id && + id != joystick_off_id && id != joystick_bg_id && id != joystick_center_id && id != touch_gui_button_id_END; } diff --git a/src/gui/touchscreenlayout.h b/src/gui/touchscreenlayout.h index 9c7d72fbf..fe0d99b9d 100644 --- a/src/gui/touchscreenlayout.h +++ b/src/gui/touchscreenlayout.h @@ -22,7 +22,11 @@ namespace irr::video enum touch_gui_button_id : u8 { - jump_id = 0, + // these two are no actual buttons ... yet + dig_id = 0, + place_id, + + jump_id, sneak_id, zoom_id, aux1_id,