From 97c34ecd22f5e796cc89a8fb88a4413c0cc94f41 Mon Sep 17 00:00:00 2001 From: y5nw <37980625+y5nw@users.noreply.github.com> Date: Sun, 1 Jun 2025 11:14:04 +0200 Subject: [PATCH] partial --- irr/include/IEventReceiver.h | 14 +++++ irr/src/CIrrDeviceLinux.cpp | 1 + irr/src/CIrrDeviceSDL.cpp | 1 + irr/src/CIrrDeviceWin32.cpp | 1 + src/client/inputhandler.cpp | 8 ++- src/client/keycode.h | 2 + src/gui/touchcontrols.cpp | 119 ++++++++++++----------------------- src/gui/touchcontrols.h | 6 +- 8 files changed, 68 insertions(+), 84 deletions(-) diff --git a/irr/include/IEventReceiver.h b/irr/include/IEventReceiver.h index 332b23158..8f0a07dbf 100644 --- a/irr/include/IEventReceiver.h +++ b/irr/include/IEventReceiver.h @@ -88,6 +88,17 @@ enum EEVENT_TYPE }; +//! Enumeration for "user" event types. +enum UserEventType: s32 +{ + //! In-game touch buttons. + /** This event is currently only fired by the in-game touch controller. + UserData1: The GameKeyType of the button. + UserData2: Whether the button is pressed or released. + */ + USER_EVENT_GAME_KEY = 1 +}; + //! Enumeration for all mouse input events enum EMOUSE_INPUT_EVENT { @@ -512,6 +523,9 @@ struct SEvent //! Any kind of user event. struct SUserEvent { + //! Event code + s32 code; + //! Some user specified data as int size_t UserData1; diff --git a/irr/src/CIrrDeviceLinux.cpp b/irr/src/CIrrDeviceLinux.cpp index f72ccc7a1..86037b39c 100644 --- a/irr/src/CIrrDeviceLinux.cpp +++ b/irr/src/CIrrDeviceLinux.cpp @@ -914,6 +914,7 @@ bool CIrrDeviceLinux::run() } else { // we assume it's a user message irrevent.EventType = irr::EET_USER_EVENT; + irrevent.UserEvent.code = 0; irrevent.UserEvent.UserData1 = static_cast(event.xclient.data.l[0]); irrevent.UserEvent.UserData2 = static_cast(event.xclient.data.l[1]); postEventFromUser(irrevent); diff --git a/irr/src/CIrrDeviceSDL.cpp b/irr/src/CIrrDeviceSDL.cpp index bc7627f73..faa76858f 100644 --- a/irr/src/CIrrDeviceSDL.cpp +++ b/irr/src/CIrrDeviceSDL.cpp @@ -947,6 +947,7 @@ bool CIrrDeviceSDL::run() case SDL_USEREVENT: irrevent.EventType = irr::EET_USER_EVENT; + irrevent.UserEvent.code = SDL_event.user.code; irrevent.UserEvent.UserData1 = reinterpret_cast(SDL_event.user.data1); irrevent.UserEvent.UserData2 = reinterpret_cast(SDL_event.user.data2); diff --git a/irr/src/CIrrDeviceWin32.cpp b/irr/src/CIrrDeviceWin32.cpp index f0947163d..59d84e634 100644 --- a/irr/src/CIrrDeviceWin32.cpp +++ b/irr/src/CIrrDeviceWin32.cpp @@ -678,6 +678,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_USER: event.EventType = irr::EET_USER_EVENT; + event.UserEvent.code = 0; event.UserEvent.UserData1 = static_cast(wParam); event.UserEvent.UserData2 = static_cast(lParam); dev = getDeviceFromHWnd(hWnd); diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index 877de8d1c..7152e4b94 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -76,9 +76,11 @@ void MyEventReceiver::reloadKeybindings() // First clear all keys, then re-add the ones we listen for keysListenedFor.clear(); for (int i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) { + GameKeyType game_key = static_cast(i); for (auto key: keybindings[i]) { - listenForKey(key, static_cast(i)); + listenForKey(key, game_key); } + listenForKey(game_key, game_key); } } @@ -217,6 +219,10 @@ bool MyEventReceiver::OnEvent(const SEvent &event) default: break; } + } else if (event.EventType == irr::EET_USER_EVENT && event.UserEvent.code == irr::USER_EVENT_GAME_KEY) { + KeyPress keyCode(static_cast(event.UserEvent.UserData1)); + setKeyDown(keyCode, event.UserEvent.UserData2); + return true; } // tell Irrlicht to continue processing this event diff --git a/src/client/keycode.h b/src/client/keycode.h index 63b0f5630..4b824d19a 100644 --- a/src/client/keycode.h +++ b/src/client/keycode.h @@ -30,6 +30,8 @@ public: KeyPress(const irr::SEvent::SKeyInput &in); + KeyPress(GameKeyType key) : scancode(key) {} + // Get a string representation that is suitable for use in minetest.conf std::string sym() const; diff --git a/src/gui/touchcontrols.cpp b/src/gui/touchcontrols.cpp index c6a6d8b88..72cd097ec 100644 --- a/src/gui/touchcontrols.cpp +++ b/src/gui/touchcontrols.cpp @@ -31,16 +31,13 @@ TouchControls *g_touchcontrols; -void TouchControls::emitKeyboardEvent(KeyPress key, bool pressed) +void TouchControls::emitGameKeyEvent(GameKeyType key, bool pressed) { SEvent e{}; - e.EventType = EET_KEY_INPUT_EVENT; - e.KeyInput.Key = key.getKeycode(); - e.KeyInput.Control = false; - e.KeyInput.Shift = false; - e.KeyInput.Char = key.getKeychar(); - e.KeyInput.SystemKeyCode = key.getScancode(); - e.KeyInput.PressedDown = pressed; + e.EventType = EET_USER_EVENT; + e.UserEvent.code = irr::USER_EVENT_GAME_KEY; + e.UserEvent.UserData1 = static_cast(key); + e.UserEvent.UserData2 = pressed; m_receiver->OnEvent(e); } @@ -55,10 +52,10 @@ void TouchControls::loadButtonTexture(IGUIImage *gui_button, const std::string & void TouchControls::buttonEmitAction(button_info &btn, bool action) { - if (!btn.keypress) + if (!btn.game_key) return; - emitKeyboardEvent(btn.keypress, action); + emitGameKeyEvent(btn.game_key, action); if (action) { if (btn.toggleable == button_info::FIRST_TEXTURE) { @@ -142,81 +139,48 @@ bool TouchControls::buttonsStep(std::vector &buttons, float dtime) return has_pointers; } -static std::string id_to_setting(touch_gui_button_id id) +static GameKeyType id_to_action(touch_gui_button_id id) { - std::string key = ""; switch (id) { + case exit_id: + return KeyType::ESC; case dig_id: - key = "dig"; - break; + return KeyType::DIG; case place_id: - key = "place"; - break; + return KeyType::PLACE; case jump_id: - key = "jump"; - break; + return KeyType::JUMP; case sneak_id: - key = "sneak"; - break; + return KeyType::SNEAK; case zoom_id: - key = "zoom"; - break; + return KeyType::ZOOM; case aux1_id: - key = "aux1"; - break; + return KeyType::AUX1; case fly_id: - key = "freemove"; - break; + return KeyType::FREEMOVE; case noclip_id: - key = "noclip"; - break; + return KeyType::NOCLIP; case fast_id: - key = "fastmove"; - break; + return KeyType::FASTMOVE; case debug_id: - key = "toggle_debug"; - break; + return KeyType::TOGGLE_DEBUG; case camera_id: - key = "camera_mode"; - break; + return KeyType::CAMERA_MODE; case range_id: - key = "rangeselect"; - break; + return KeyType::RANGESELECT; case minimap_id: - key = "minimap"; - break; + return KeyType::MINIMAP; case toggle_chat_id: - key = "toggle_chat"; - break; + return KeyType::TOGGLE_CHAT; case chat_id: - key = "chat"; - break; + return KeyType::CHAT; case inventory_id: - key = "inventory"; - break; + return KeyType::INVENTORY; case drop_id: - key = "drop"; - break; + return KeyType::DROP; default: - break; + return KeyType::INTERNAL_ENUM_COUNT; } - return key.empty() ? key : "keymap_" + key; -} - -static KeyPress id_to_keypress(touch_gui_button_id id) -{ - // ESC isn't part of the keymap. - if (id == exit_id) - return EscapeKey; - - auto setting_name = id_to_setting(id); - - assert(!setting_name.empty()); - const auto &keylist = getKeySetting(setting_name); - if (keylist.empty()) - warningstream << "TouchControls: Unbound or invalid key for " - << setting_name << ", hiding button." << std::endl; - return keylist[0]; } @@ -239,11 +203,6 @@ TouchControls::TouchControls(IrrlichtDevice *device, ISimpleTextureSource *tsrc) readSettings(); for (auto name : setting_names) g_settings->registerChangedCallback(name, settingChangedCallback, this); - - // Also update layout when keybindings change (e.g. for convertibles) - for (u8 id = 0; id < touch_gui_button_id_END; id++) - if (auto name = id_to_setting((touch_gui_button_id)id); !name.empty()) - g_settings->registerChangedCallback(name, settingChangedCallback, this); } void TouchControls::settingChangedCallback(const std::string &name, void *data) @@ -376,7 +335,7 @@ bool TouchControls::mayAddButton(touch_gui_button_id id) assert(ButtonLayout::isButtonValid(id)); assert(ButtonLayout::isButtonAllowed(id)); // The overflow button doesn't need a keycode to be valid. - return id == overflow_id || id_to_keypress(id); + return id == overflow_id || id_to_action(id) >= KeyType::INTERNAL_ENUM_COUNT; } void TouchControls::addButton(std::vector &buttons, touch_gui_button_id id, @@ -388,7 +347,7 @@ void TouchControls::addButton(std::vector &buttons, touch_gui_butto button_info &btn = buttons.emplace_back(); btn.id = id; - btn.keypress = id_to_keypress(id); + btn.game_key = id_to_action(id); btn.gui_button = grab_gui_element(btn_gui_button); } @@ -655,10 +614,10 @@ void TouchControls::translateEvent(const SEvent &event) void TouchControls::applyJoystickStatus() { if (m_joystick_triggers_aux1) { - auto key = id_to_keypress(aux1_id); - emitKeyboardEvent(key, false); + auto key = id_to_action(aux1_id); + emitGameKeyEvent(key, false); if (m_joystick_status_aux1) - emitKeyboardEvent(key, true); + emitGameKeyEvent(key, true); } } @@ -764,11 +723,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) { - emitKeyboardEvent(id_to_keypress(dig_id), false); + emitGameKeyEvent(id_to_action(dig_id), false); m_dig_pressed = false; } if (m_place_pressed) { - emitKeyboardEvent(id_to_keypress(place_id), false); + emitGameKeyEvent(id_to_action(place_id), false); m_place_pressed = false; } } @@ -852,20 +811,20 @@ void TouchControls::applyContextControls(const TouchInteractionMode &mode) target_place_pressed |= now < m_place_pressed_until; if (target_dig_pressed && !m_dig_pressed) { - emitKeyboardEvent(id_to_keypress(dig_id), true); + emitGameKeyEvent(id_to_action(dig_id), true); m_dig_pressed = true; } else if (!target_dig_pressed && m_dig_pressed) { - emitKeyboardEvent(id_to_keypress(dig_id), false); + emitGameKeyEvent(id_to_action(dig_id), false); m_dig_pressed = false; } if (target_place_pressed && !m_place_pressed) { - emitKeyboardEvent(id_to_keypress(place_id), true); + emitGameKeyEvent(id_to_action(place_id), true); m_place_pressed = true; } else if (!target_place_pressed && m_place_pressed) { - emitKeyboardEvent(id_to_keypress(place_id), false); + emitGameKeyEvent(id_to_action(place_id), false); m_place_pressed = false; } } diff --git a/src/gui/touchcontrols.h b/src/gui/touchcontrols.h index 52a3bd6b2..c79d43fd8 100644 --- a/src/gui/touchcontrols.h +++ b/src/gui/touchcontrols.h @@ -16,7 +16,7 @@ #include "itemdef.h" #include "touchscreenlayout.h" #include "util/basic_macros.h" -#include "client/keycode.h" +#include "client/keys.h" namespace irr { @@ -59,7 +59,7 @@ struct button_info { touch_gui_button_id id; float repeat_counter; - KeyPress keypress; + GameKeyType game_key; std::vector pointer_ids; std::shared_ptr gui_button = nullptr; @@ -204,7 +204,7 @@ private: // for its buttons. We only want static image display, not interactivity, // from Irrlicht. - void emitKeyboardEvent(KeyPress keycode, bool pressed); + void emitGameKeyEvent(GameKeyType, bool pressed); void loadButtonTexture(IGUIImage *gui_button, const std::string &path); void buttonEmitAction(button_info &btn, bool action);