diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/input_default.cpp | 343 | ||||
-rw-r--r-- | main/input_default.h | 83 | ||||
-rw-r--r-- | main/main.cpp | 19 |
3 files changed, 444 insertions, 1 deletions
diff --git a/main/input_default.cpp b/main/input_default.cpp new file mode 100644 index 0000000000..878d21c302 --- /dev/null +++ b/main/input_default.cpp @@ -0,0 +1,343 @@ +#include "input_default.h" +#include "servers/visual_server.h" +#include "os/os.h" +#include "input_map.h" + +void InputDefault::SpeedTrack::update(const Vector2& p_delta_p) { + + uint64_t tick = OS::get_singleton()->get_ticks_usec(); + uint32_t tdiff = tick-last_tick; + float delta_t = tdiff / 1000000.0; + last_tick=tick; + + + accum+=p_delta_p; + accum_t+=delta_t; + + if (accum_t>max_ref_frame*10) + accum_t=max_ref_frame*10; + + while( accum_t>=min_ref_frame ) { + + float slice_t = min_ref_frame / accum_t; + Vector2 slice = accum*slice_t; + accum=accum-slice; + accum_t-=min_ref_frame; + + speed=(slice/min_ref_frame).linear_interpolate(speed,min_ref_frame/max_ref_frame); + } + +} + +void InputDefault::SpeedTrack::reset() { + last_tick = OS::get_singleton()->get_ticks_usec(); + speed=Vector2(); + accum_t=0; +} + +InputDefault::SpeedTrack::SpeedTrack() { + + min_ref_frame=0.1; + max_ref_frame=0.3; + reset(); +} + +bool InputDefault::is_key_pressed(int p_scancode) { + + _THREAD_SAFE_METHOD_ + return keys_pressed.has(p_scancode); +} + +bool InputDefault::is_mouse_button_pressed(int p_button) { + + _THREAD_SAFE_METHOD_ + return (mouse_button_mask&(1<<p_button))!=0; +} + + +static int _combine_device(int p_value,int p_device) { + + return p_value|(p_device<<20); +} + +bool InputDefault::is_joy_button_pressed(int p_device, int p_button) { + + _THREAD_SAFE_METHOD_ + return joy_buttons_pressed.has(_combine_device(p_button,p_device)); +} + +bool InputDefault::is_action_pressed(const StringName& p_action) { + + if (custom_action_press.has(p_action)) + return true; //simpler + + const List<InputEvent> *alist = InputMap::get_singleton()->get_action_list(p_action); + if (!alist) + return NULL; + + + for (const List<InputEvent>::Element *E=alist->front();E;E=E->next()) { + + + int device=E->get().device; + + switch(E->get().type) { + + case InputEvent::KEY: { + + const InputEventKey &iek=E->get().key; + if ((keys_pressed.has(iek.scancode))) + return true; + } break; + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &iemb=E->get().mouse_button; + if(mouse_button_mask&(1<<iemb.button_index)) + return true; + } break; + case InputEvent::JOYSTICK_BUTTON: { + + const InputEventJoystickButton &iejb=E->get().joy_button; + int c = _combine_device(iejb.button_index,device); + if (joy_buttons_pressed.has(c)) + return true; + } break; + } + } + + return false; +} + +float InputDefault::get_joy_axis(int p_device,int p_axis) { + + _THREAD_SAFE_METHOD_ + int c = _combine_device(p_axis,p_device); + if (joy_axis.has(c)) { + return joy_axis[c]; + } else { + return 0; + } +} + +String InputDefault::get_joy_name(int p_idx) { + + _THREAD_SAFE_METHOD_ + return joy_names[p_idx]; +}; + +void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_name) { + + _THREAD_SAFE_METHOD_ + joy_names[p_idx] = p_connected ? p_name : ""; + + emit_signal("joy_connection_changed", p_idx, p_connected); +}; + +Vector3 InputDefault::get_accelerometer() { + + _THREAD_SAFE_METHOD_ + return accelerometer; +} + +void InputDefault::parse_input_event(const InputEvent& p_event) { + + _THREAD_SAFE_METHOD_ + switch(p_event.type) { + + case InputEvent::KEY: { + + if (p_event.key.echo) + break; + if (p_event.key.scancode==0) + break; + + // print_line(p_event); + + if (p_event.key.pressed) + keys_pressed.insert(p_event.key.scancode); + else + keys_pressed.erase(p_event.key.scancode); + } break; + case InputEvent::MOUSE_BUTTON: { + + if (p_event.mouse_button.doubleclick) + break; + + if (p_event.mouse_button.pressed) + mouse_button_mask|=(1<<p_event.mouse_button.button_index); + else + mouse_button_mask&=~(1<<p_event.mouse_button.button_index); + + if (main_loop && emulate_touch && p_event.mouse_button.button_index==1) { + InputEventScreenTouch touch_event; + touch_event.index=0; + touch_event.pressed=p_event.mouse_button.pressed; + touch_event.x=p_event.mouse_button.x; + touch_event.y=p_event.mouse_button.y; + InputEvent ev; + ev.type=InputEvent::SCREEN_TOUCH; + ev.screen_touch=touch_event; + main_loop->input_event(ev); + } + } break; + case InputEvent::MOUSE_MOTION: { + + if (main_loop && emulate_touch && p_event.mouse_motion.button_mask&1) { + InputEventScreenDrag drag_event; + drag_event.index=0; + drag_event.x=p_event.mouse_motion.x; + drag_event.y=p_event.mouse_motion.y; + drag_event.relative_x=p_event.mouse_motion.relative_x; + drag_event.relative_y=p_event.mouse_motion.relative_y; + drag_event.speed_x=p_event.mouse_motion.speed_x; + drag_event.speed_y=p_event.mouse_motion.speed_y; + + InputEvent ev; + ev.type=InputEvent::SCREEN_DRAG; + ev.screen_drag=drag_event; + + main_loop->input_event(ev); + } + + } break; + case InputEvent::JOYSTICK_BUTTON: { + + int c = _combine_device(p_event.joy_button.button_index,p_event.device); + + if (p_event.joy_button.pressed) + joy_buttons_pressed.insert(c); + else + joy_buttons_pressed.erase(c); + } break; + case InputEvent::JOYSTICK_MOTION: { + set_joy_axis(p_event.device, p_event.joy_motion.axis, p_event.joy_motion.axis_value); + } break; + + } + + if (main_loop) + main_loop->input_event(p_event); + +} + +void InputDefault::set_joy_axis(int p_device,int p_axis,float p_value) { + + _THREAD_SAFE_METHOD_ + int c = _combine_device(p_axis,p_device); + joy_axis[c]=p_value; +} + +void InputDefault::set_accelerometer(const Vector3& p_accel) { + + _THREAD_SAFE_METHOD_ + + accelerometer=p_accel; + +} + +void InputDefault::set_main_loop(MainLoop *p_main_loop) { + main_loop=p_main_loop; + +} + +void InputDefault::set_mouse_pos(const Point2& p_posf) { + + mouse_speed_track.update(p_posf-mouse_pos); + mouse_pos=p_posf; + if (custom_cursor.is_valid()) { + VisualServer::get_singleton()->cursor_set_pos(get_mouse_pos()); + } +} + +Point2 InputDefault::get_mouse_pos() const { + + return mouse_pos; +} +Point2 InputDefault::get_mouse_speed() const { + + return mouse_speed_track.speed; +} + +int InputDefault::get_mouse_button_mask() const { + + return OS::get_singleton()->get_mouse_button_state(); +} + +void InputDefault::warp_mouse_pos(const Vector2& p_to) { + + OS::get_singleton()->warp_mouse_pos(p_to); +} + + +void InputDefault::iteration(float p_step) { + + +} + +void InputDefault::action_press(const StringName& p_action) { + + if (custom_action_press.has(p_action)) { + + custom_action_press[p_action]++; + } else { + custom_action_press[p_action]=1; + } +} + +void InputDefault::action_release(const StringName& p_action){ + + ERR_FAIL_COND(!custom_action_press.has(p_action)); + custom_action_press[p_action]--; + if (custom_action_press[p_action]==0) { + custom_action_press.erase(p_action); + } +} + +void InputDefault::set_emulate_touch(bool p_emulate) { + + emulate_touch=p_emulate; +} + +bool InputDefault::is_emulating_touchscreen() const { + + return emulate_touch; +} + +void InputDefault::set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot) { + if (custom_cursor==p_cursor) + return; + + custom_cursor=p_cursor; + + if (p_cursor.is_null()) { + set_mouse_mode(MOUSE_MODE_VISIBLE); + VisualServer::get_singleton()->cursor_set_visible(false); + } else { + set_mouse_mode(MOUSE_MODE_HIDDEN); + VisualServer::get_singleton()->cursor_set_visible(true); + VisualServer::get_singleton()->cursor_set_texture(custom_cursor->get_rid(),p_hotspot); + VisualServer::get_singleton()->cursor_set_pos(get_mouse_pos()); + } +} + +void InputDefault::set_mouse_in_window(bool p_in_window) { + + if (custom_cursor.is_valid()) { + + if (p_in_window) { + set_mouse_mode(MOUSE_MODE_HIDDEN); + VisualServer::get_singleton()->cursor_set_visible(true); + } else { + set_mouse_mode(MOUSE_MODE_VISIBLE); + VisualServer::get_singleton()->cursor_set_visible(false); + } + + } +} + +InputDefault::InputDefault() { + + mouse_button_mask=0; + emulate_touch=false; + main_loop=NULL; +} diff --git a/main/input_default.h b/main/input_default.h new file mode 100644 index 0000000000..2ef4f727c6 --- /dev/null +++ b/main/input_default.h @@ -0,0 +1,83 @@ +#ifndef INPUT_DEFAULT_H +#define INPUT_DEFAULT_H + +#include "os/input.h" + +class InputDefault : public Input { + + OBJ_TYPE( InputDefault, Input ); + _THREAD_SAFE_CLASS_ + + int mouse_button_mask; + Set<int> keys_pressed; + Set<int> joy_buttons_pressed; + Map<int,float> joy_axis; + Map<StringName,int> custom_action_press; + Map<int, String> joy_names; + Vector3 accelerometer; + Vector2 mouse_pos; + MainLoop *main_loop; + + bool emulate_touch; + + struct SpeedTrack { + + uint64_t last_tick; + Vector2 speed; + Vector2 accum; + float accum_t; + float min_ref_frame; + float max_ref_frame; + + void update(const Vector2& p_delta_p); + void reset(); + SpeedTrack(); + }; + + SpeedTrack mouse_speed_track; + + RES custom_cursor; + +public: + + virtual bool is_key_pressed(int p_scancode); + virtual bool is_mouse_button_pressed(int p_button); + virtual bool is_joy_button_pressed(int p_device, int p_button); + virtual bool is_action_pressed(const StringName& p_action); + + virtual float get_joy_axis(int p_device,int p_axis); + String get_joy_name(int p_idx); + void joy_connection_changed(int p_idx, bool p_connected, String p_name); + + virtual Vector3 get_accelerometer(); + + virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_speed() const; + virtual int get_mouse_button_mask() const; + + virtual void warp_mouse_pos(const Vector2& p_to); + + + void parse_input_event(const InputEvent& p_event); + void set_accelerometer(const Vector3& p_accel); + void set_joy_axis(int p_device,int p_axis,float p_value); + + void set_main_loop(MainLoop *main_loop); + void set_mouse_pos(const Point2& p_posf); + + void action_press(const StringName& p_action); + void action_release(const StringName& p_action); + + void iteration(float p_step); + + void set_emulate_touch(bool p_emulate); + virtual bool is_emulating_touchscreen() const; + + virtual void set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot=Vector2()); + virtual void set_mouse_in_window(bool p_in_window); + + InputDefault(); + +}; + +#endif // INPUT_DEFAULT_H diff --git a/main/main.cpp b/main/main.cpp index 7006b48282..84f7c3a88e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -75,7 +75,7 @@ #include "core/io/file_access_zip.h" #include "translation.h" #include "version.h" -#include "os/input.h" +#include "main/input_default.h" #include "performance.h" static Globals *globals=NULL; @@ -926,6 +926,9 @@ Error Main::setup2() { id->set_emulate_touch(true); } } + + + MAIN_PRINT("Main: Load Remaps"); MAIN_PRINT("Main: Load Scene Types"); @@ -933,6 +936,20 @@ Error Main::setup2() { register_scene_types(); register_server_types(); + GLOBAL_DEF("display/custom_mouse_cursor",String()); + GLOBAL_DEF("display/custom_mouse_cursor_hotspot",Vector2()); + Globals::get_singleton()->set_custom_property_info("display/custom_mouse_cursor",PropertyInfo(Variant::STRING,"display/custom_mouse_cursor",PROPERTY_HINT_FILE,"*.png,*.webp")); + + if (String(Globals::get_singleton()->get("display/custom_mouse_cursor"))!=String()) { + + print_line("use custom cursor"); + Ref<Texture> cursor=ResourceLoader::load(Globals::get_singleton()->get("display/custom_mouse_cursor")); + if (cursor.is_valid()) { + print_line("loaded ok"); + Vector2 hotspot = Globals::get_singleton()->get("display/custom_mouse_cursor_hotspot"); + Input::get_singleton()->set_custom_mouse_cursor(cursor,hotspot); + } + } #ifdef TOOLS_ENABLED EditorNode::register_editor_types(); ObjectTypeDB::register_type<PCKPacker>(); // todo: move somewhere else |