summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/input_default.cpp158
-rw-r--r--main/input_default.h23
-rw-r--r--main/main.cpp25
-rw-r--r--main/tests/test_oa_hash_map.cpp6
4 files changed, 165 insertions, 47 deletions
diff --git a/main/input_default.cpp b/main/input_default.cpp
index c3bc83b2de..29d30110e3 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -127,6 +127,14 @@ bool InputDefault::is_action_just_released(const StringName &p_action) const {
}
}
+float InputDefault::get_action_strength(const StringName &p_action) const {
+ const Map<StringName, Action>::Element *E = action_state.find(p_action);
+ if (!E)
+ return 0.0f;
+
+ return E->get().strength;
+}
+
float InputDefault::get_joy_axis(int p_device, int p_axis) const {
_THREAD_SAFE_METHOD_
@@ -186,8 +194,6 @@ void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_
Joypad js;
js.name = p_connected ? p_name : "";
js.uid = p_connected ? p_guid : "";
- js.mapping = -1;
- js.hat_current = 0;
if (p_connected) {
@@ -250,6 +256,11 @@ Vector3 InputDefault::get_gyroscope() const {
void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
+ _parse_input_event_impl(p_event, false);
+}
+
+void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
+
_THREAD_SAFE_METHOD_
Ref<InputEventKey> k = p_event;
@@ -273,25 +284,30 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
mouse_button_mask &= ~(1 << (mb->get_button_index() - 1));
}
- if (main_loop && emulate_touch && mb->get_button_index() == 1) {
+ Point2 pos = mb->get_global_position();
+ if (mouse_pos != pos) {
+ set_mouse_position(pos);
+ }
+
+ if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == 1) {
Ref<InputEventScreenTouch> touch_event;
touch_event.instance();
touch_event->set_pressed(mb->is_pressed());
touch_event->set_position(mb->get_position());
main_loop->input_event(touch_event);
}
-
- Point2 pos = mb->get_global_position();
- if (mouse_pos != pos) {
- set_mouse_position(pos);
- }
}
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
- if (main_loop && emulate_touch && mm->get_button_mask() & 1) {
+ Point2 pos = mm->get_global_position();
+ if (mouse_pos != pos) {
+ set_mouse_position(pos);
+ }
+
+ if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask() & 1) {
Ref<InputEventScreenDrag> drag_event;
drag_event.instance();
@@ -303,6 +319,58 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
}
}
+ if (emulate_mouse_from_touch) {
+
+ Ref<InputEventScreenTouch> st = p_event;
+
+ if (st.is_valid()) {
+ bool translate = false;
+ if (st->is_pressed()) {
+ if (mouse_from_touch_index == -1) {
+ translate = true;
+ mouse_from_touch_index = st->get_index();
+ }
+ } else {
+ if (st->get_index() == mouse_from_touch_index) {
+ translate = true;
+ mouse_from_touch_index = -1;
+ }
+ }
+
+ if (translate) {
+ Ref<InputEventMouseButton> button_event;
+ button_event.instance();
+
+ button_event->set_position(st->get_position());
+ button_event->set_global_position(st->get_position());
+ button_event->set_pressed(st->is_pressed());
+ button_event->set_button_index(BUTTON_LEFT);
+ if (st->is_pressed()) {
+ button_event->set_button_mask(mouse_button_mask | (1 << BUTTON_LEFT - 1));
+ } else {
+ button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1));
+ }
+
+ _parse_input_event_impl(button_event, true);
+ }
+ }
+
+ Ref<InputEventScreenDrag> sd = p_event;
+
+ if (sd.is_valid() && sd->get_index() == mouse_from_touch_index) {
+ Ref<InputEventMouseMotion> motion_event;
+ motion_event.instance();
+
+ motion_event->set_position(sd->get_position());
+ motion_event->set_global_position(sd->get_position());
+ motion_event->set_relative(sd->get_relative());
+ motion_event->set_speed(sd->get_speed());
+ motion_event->set_button_mask(mouse_button_mask);
+
+ _parse_input_event_impl(motion_event, true);
+ }
+ }
+
Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_valid()) {
@@ -330,16 +398,18 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
}
}
- if (!p_event->is_echo()) {
- for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) {
+ for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) {
+ if (InputMap::get_singleton()->event_is_action(p_event, E->key())) {
- if (InputMap::get_singleton()->event_is_action(p_event, E->key()) && is_action_pressed(E->key()) != p_event->is_pressed()) {
+ // Save the action's state
+ if (!p_event->is_echo() && is_action_pressed(E->key()) != p_event->is_action_pressed(E->key())) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
action.idle_frame = Engine::get_singleton()->get_idle_frames();
- action.pressed = p_event->is_pressed();
+ action.pressed = p_event->is_action_pressed(E->key());
action_state[E->key()] = action;
}
+ action_state[E->key()].strength = p_event->get_action_strength(E->key());
}
}
@@ -413,10 +483,6 @@ void InputDefault::set_mouse_position(const Point2 &p_posf) {
mouse_speed_track.update(p_posf - mouse_pos);
mouse_pos = p_posf;
- if (custom_cursor.is_valid()) {
- //removed, please insist that we implement hardware cursors
- // VisualServer::get_singleton()->cursor_set_pos(get_mouse_position());
- }
}
Point2 InputDefault::get_mouse_position() const {
@@ -489,25 +555,59 @@ void InputDefault::action_release(const StringName &p_action) {
action_state[p_action] = action;
}
-void InputDefault::set_emulate_touch(bool p_emulate) {
+void InputDefault::set_emulate_touch_from_mouse(bool p_emulate) {
+
+ emulate_touch_from_mouse = p_emulate;
+}
+
+bool InputDefault::is_emulating_touch_from_mouse() const {
+
+ return emulate_touch_from_mouse;
+}
+
+// Calling this whenever the game window is focused helps unstucking the "touch mouse"
+// if the OS or its abstraction class hasn't properly reported that touch pointers raised
+void InputDefault::ensure_touch_mouse_raised() {
+
+ if (mouse_from_touch_index != -1) {
+ mouse_from_touch_index = -1;
+
+ Ref<InputEventMouseButton> button_event;
+ button_event.instance();
+
+ button_event->set_position(mouse_pos);
+ button_event->set_global_position(mouse_pos);
+ button_event->set_pressed(false);
+ button_event->set_button_index(BUTTON_LEFT);
+ button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1));
+
+ _parse_input_event_impl(button_event, true);
+ }
+}
+
+void InputDefault::set_emulate_mouse_from_touch(bool p_emulate) {
- emulate_touch = p_emulate;
+ emulate_mouse_from_touch = p_emulate;
}
-bool InputDefault::is_emulating_touchscreen() const {
+bool InputDefault::is_emulating_mouse_from_touch() const {
- return emulate_touch;
+ return emulate_mouse_from_touch;
+}
+
+Input::CursorShape InputDefault::get_default_cursor_shape() {
+ return default_shape;
+}
+
+void InputDefault::set_default_cursor_shape(CursorShape p_shape) {
+ default_shape = p_shape;
+ OS::get_singleton()->set_cursor_shape((OS::CursorShape)p_shape);
}
void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (Engine::get_singleton()->is_editor_hint())
return;
- if (custom_cursor == p_cursor)
- return;
-
- custom_cursor = p_cursor;
-
OS::get_singleton()->set_custom_mouse_cursor(p_cursor, (OS::CursorShape)p_shape, p_hotspot);
}
@@ -529,7 +629,9 @@ void InputDefault::set_mouse_in_window(bool p_in_window) {
InputDefault::InputDefault() {
mouse_button_mask = 0;
- emulate_touch = false;
+ emulate_touch_from_mouse = false;
+ emulate_mouse_from_touch = false;
+ mouse_from_touch_index = -1;
main_loop = NULL;
hat_map_default[HAT_UP].type = TYPE_BUTTON;
@@ -787,12 +889,12 @@ InputDefault::JoyEvent InputDefault::_find_to_event(String p_to) {
JoyEvent ret;
ret.type = -1;
+ ret.index = 0;
int i = 0;
while (buttons[i]) {
if (p_to == buttons[i]) {
- //printf("mapping button %s\n", buttons[i]);
ret.type = TYPE_BUTTON;
ret.index = i;
ret.value = 0;
diff --git a/main/input_default.h b/main/input_default.h
index 0479fdc0ff..2e3cae8520 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -55,11 +55,15 @@ class InputDefault : public Input {
uint64_t physics_frame;
uint64_t idle_frame;
bool pressed;
+ float strength;
};
Map<StringName, Action> action_state;
- bool emulate_touch;
+ bool emulate_touch_from_mouse;
+ bool emulate_mouse_from_touch;
+
+ int mouse_from_touch_index;
struct VibrationInfo {
float weak_magnitude;
@@ -96,7 +100,6 @@ class InputDefault : public Input {
int hat_current;
Joypad() {
-
for (int i = 0; i < JOY_AXIS_MAX; i++) {
last_axis[i] = 0.0f;
@@ -109,13 +112,14 @@ class InputDefault : public Input {
last_hat = HAT_MASK_CENTER;
filter = 0.01f;
mapping = -1;
+ hat_current = 0;
}
};
SpeedTrack mouse_speed_track;
Map<int, Joypad> joy_names;
int fallback_mapping;
- RES custom_cursor;
+ CursorShape default_shape = CURSOR_ARROW;
public:
enum HatMask {
@@ -175,6 +179,8 @@ private:
void _axis_event(int p_device, int p_axis, float p_value);
float _handle_deadzone(int p_device, int p_axis, float p_value);
+ void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
+
public:
virtual bool is_key_pressed(int p_scancode) const;
virtual bool is_mouse_button_pressed(int p_button) const;
@@ -182,6 +188,7 @@ public:
virtual bool is_action_pressed(const StringName &p_action) const;
virtual bool is_action_just_pressed(const StringName &p_action) const;
virtual bool is_action_just_released(const StringName &p_action) const;
+ virtual float get_action_strength(const StringName &p_action) const;
virtual float get_joy_axis(int p_device, int p_axis) const;
String get_joy_name(int p_idx);
@@ -223,9 +230,15 @@ public:
void iteration(float p_step);
- void set_emulate_touch(bool p_emulate);
- virtual bool is_emulating_touchscreen() const;
+ void set_emulate_touch_from_mouse(bool p_emulate);
+ virtual bool is_emulating_touch_from_mouse() const;
+ void ensure_touch_mouse_raised();
+
+ void set_emulate_mouse_from_touch(bool p_emulate);
+ virtual bool is_emulating_mouse_from_touch() const;
+ virtual CursorShape get_default_cursor_shape();
+ virtual void set_default_cursor_shape(CursorShape p_shape);
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
virtual void set_mouse_in_window(bool p_in_window);
diff --git a/main/main.cpp b/main/main.cpp
index a01ef00cd0..fa60bd4e96 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1142,13 +1142,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
GLOBAL_DEF("application/config/icon", String());
ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
- if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false))) {
- if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton() && !(editor || project_manager)) {
- //only if no touchscreen ui hint, set emulation
- InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
- if (id)
- id->set_emulate_touch(true);
+ InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
+ if (id) {
+ if (bool(GLOBAL_DEF("input/pointing_devices/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
+ if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
+ //only if no touchscreen ui hint, set emulation
+ id->set_emulate_touch_from_mouse(true);
+ }
}
+
+ id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input/pointing_devices/emulate_mouse_from_touch", true)));
}
MAIN_PRINT("Main: Load Remaps");
@@ -1538,7 +1541,7 @@ bool Main::start() {
DocData docsrc;
Map<String, String> doc_data_classes;
Set<String> checked_paths;
- print_line("Loading docs..");
+ print_line("Loading docs...");
for (int i = 0; i < _doc_data_class_path_count; i++) {
String path = doc_tool.plus_file(_doc_data_class_paths[i].path);
@@ -1556,14 +1559,14 @@ bool Main::start() {
checked_paths.insert(index_path);
print_line("Loading docs from: " + index_path);
- print_line("Merging docs..");
+ print_line("Merging docs...");
doc.merge_from(docsrc);
for (Set<String>::Element *E = checked_paths.front(); E; E = E->next()) {
print_line("Erasing old docs at: " + E->get());
DocData::erase_classes(E->get());
}
- print_line("Generating new docs..");
+ print_line("Generating new docs...");
doc.save_classes(index_path, doc_data_classes);
return false;
@@ -1738,7 +1741,7 @@ bool Main::start() {
bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
sml->get_root()->set_snap_controls_to_pixels(snap_controls);
- bool font_oversampling = GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", false);
+ bool font_oversampling = GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true);
sml->set_use_font_oversampling(font_oversampling);
} else {
@@ -1751,7 +1754,7 @@ bool Main::start() {
sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
- GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", false);
+ GLOBAL_DEF("rendering/quality/dynamic_fonts/use_oversampling", true);
}
String local_game_path;
diff --git a/main/tests/test_oa_hash_map.cpp b/main/tests/test_oa_hash_map.cpp
index ac65fdf19c..0e34faace7 100644
--- a/main/tests/test_oa_hash_map.cpp
+++ b/main/tests/test_oa_hash_map.cpp
@@ -49,7 +49,7 @@ MainLoop *test() {
map.set(42, 11880);
int value;
- map.lookup(42, &value);
+ map.lookup(42, value);
OS::get_singleton()->print("capacity %d\n", map.get_capacity());
OS::get_singleton()->print("elements %d\n", map.get_num_elements());
@@ -72,7 +72,7 @@ MainLoop *test() {
uint32_t num_elems = 0;
for (int i = 0; i < 500; i++) {
int tmp;
- if (map.lookup(i, &tmp))
+ if (map.lookup(i, tmp) && tmp == i * 2)
num_elems++;
}
@@ -88,7 +88,7 @@ MainLoop *test() {
map.set("Godot rocks", 42);
for (OAHashMap<String, int>::Iterator it = map.iter(); it.valid; it = map.next_iter(it)) {
- OS::get_singleton()->print("map[\"%s\"] = %d\n", it.key->utf8().get_data(), *it.data);
+ OS::get_singleton()->print("map[\"%s\"] = %d\n", it.key->utf8().get_data(), *it.value);
}
}