summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/input_map.cpp4
-rw-r--r--core/input_map.h8
-rw-r--r--core/os/input.cpp2
-rw-r--r--core/os/input.h20
-rw-r--r--core/os/os.cpp3
-rw-r--r--core/os/os.h8
-rw-r--r--main/input_default.cpp87
-rw-r--r--main/input_default.h31
-rw-r--r--main/main.cpp6
-rw-r--r--modules/visual_script/visual_script_nodes.cpp57
-rw-r--r--modules/visual_script/visual_script_nodes.h13
11 files changed, 197 insertions, 42 deletions
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 08ee8138a3..3a0f9596f5 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -290,6 +290,10 @@ bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) con
}
+const Map<StringName, InputMap::Action>& InputMap::get_action_map() const {
+ return input_map;
+}
+
void InputMap::load_from_globals() {
input_map.clear();;
diff --git a/core/input_map.h b/core/input_map.h
index dc5a911963..a224765d8c 100644
--- a/core/input_map.h
+++ b/core/input_map.h
@@ -35,12 +35,14 @@
class InputMap : public Object {
OBJ_TYPE( InputMap, Object );
- static InputMap *singleton;
-
+public:
struct Action {
int id;
List<InputEvent> inputs;
};
+private:
+ static InputMap *singleton;
+
mutable Map<StringName, Action> input_map;
mutable Map<int,StringName> input_id_map;
@@ -72,7 +74,7 @@ public:
bool event_is_action(const InputEvent& p_event, const StringName& p_action) const;
bool event_is_joy_motion_action_pressed(const InputEvent& p_event) const;
-
+ const Map<StringName, Action>& get_action_map() const;
void load_from_globals();
void load_default();
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 531db73838..401ab7ffe2 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -53,6 +53,8 @@ void Input::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_mouse_button_pressed","button"),&Input::is_mouse_button_pressed);
ObjectTypeDB::bind_method(_MD("is_joy_button_pressed","device","button"),&Input::is_joy_button_pressed);
ObjectTypeDB::bind_method(_MD("is_action_pressed","action"),&Input::is_action_pressed);
+ ObjectTypeDB::bind_method(_MD("is_action_just_pressed","action"),&Input::is_action_just_pressed);
+ ObjectTypeDB::bind_method(_MD("is_action_just_released","action"),&Input::is_action_just_released);
ObjectTypeDB::bind_method(_MD("add_joy_mapping","mapping", "update_existing"),&Input::add_joy_mapping, DEFVAL(false));
ObjectTypeDB::bind_method(_MD("remove_joy_mapping","guid"),&Input::remove_joy_mapping);
ObjectTypeDB::bind_method(_MD("is_joy_known","device"),&Input::is_joy_known);
diff --git a/core/os/input.h b/core/os/input.h
index 16bcc0ff9a..665fb4ad99 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -55,12 +55,14 @@ public:
static Input *get_singleton();
- virtual bool is_key_pressed(int p_scancode)=0;
- virtual bool is_mouse_button_pressed(int p_button)=0;
- virtual bool is_joy_button_pressed(int p_device, int p_button)=0;
- virtual bool is_action_pressed(const StringName& p_action)=0;
-
- virtual float get_joy_axis(int p_device,int p_axis)=0;
+ virtual bool is_key_pressed(int p_scancode) const=0;
+ virtual bool is_mouse_button_pressed(int p_button) const=0;
+ virtual bool is_joy_button_pressed(int p_device, int p_button) const=0;
+ virtual bool is_action_pressed(const StringName& p_action) const=0;
+ virtual bool is_action_just_pressed(const StringName& p_action) const=0;
+ virtual bool is_action_just_released(const StringName& p_action) const=0;
+
+ virtual float get_joy_axis(int p_device,int p_axis) const=0;
virtual String get_joy_name(int p_idx)=0;
virtual Array get_connected_joysticks()=0;
virtual void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid)=0;
@@ -80,9 +82,9 @@ public:
virtual void warp_mouse_pos(const Vector2& p_to)=0;
- virtual Vector3 get_accelerometer()=0;
- virtual Vector3 get_magnetometer()=0;
- virtual Vector3 get_gyroscope()=0;
+ virtual Vector3 get_accelerometer() const=0;
+ virtual Vector3 get_magnetometer() const=0;
+ virtual Vector3 get_gyroscope() const=0;
virtual void action_press(const StringName& p_action)=0;
virtual void action_release(const StringName& p_action)=0;
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 5f86962048..ee32476234 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -587,6 +587,9 @@ OS::OS() {
_time_scale=1.0;
_pixel_snap=false;
_allow_hidpi=true;
+ _fixed_frames=0;
+ _idle_frames=0;
+ _in_fixed=false;
Math::seed(1234567);
}
diff --git a/core/os/os.h b/core/os/os.h
index 2521d67e29..8e9293b3c8 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -62,6 +62,10 @@ class OS {
bool _pixel_snap;
bool _allow_hidpi;
+ uint64_t _fixed_frames;
+ uint64_t _idle_frames;
+ bool _in_fixed;
+
char *last_error;
public:
@@ -282,6 +286,10 @@ public:
uint64_t get_frames_drawn();
+ uint64_t get_fixed_frames() const { return _fixed_frames; }
+ uint64_t get_idle_frames() const { return _idle_frames; }
+ bool is_in_fixed_frame() const { return _in_fixed; }
+
bool is_stdout_verbose() const;
enum CursorShape {
diff --git a/main/input_default.cpp b/main/input_default.cpp
index f93a142c54..ea08bfc2ef 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -71,13 +71,13 @@ InputDefault::SpeedTrack::SpeedTrack() {
reset();
}
-bool InputDefault::is_key_pressed(int p_scancode) {
+bool InputDefault::is_key_pressed(int p_scancode) const {
_THREAD_SAFE_METHOD_
return keys_pressed.has(p_scancode);
}
-bool InputDefault::is_mouse_button_pressed(int p_button) {
+bool InputDefault::is_mouse_button_pressed(int p_button) const {
_THREAD_SAFE_METHOD_
return (mouse_button_mask&(1<<p_button))!=0;
@@ -89,14 +89,16 @@ 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) {
+bool InputDefault::is_joy_button_pressed(int p_device, int p_button) const{
_THREAD_SAFE_METHOD_
return joy_buttons_pressed.has(_combine_device(p_button,p_device));
}
-bool InputDefault::is_action_pressed(const StringName& p_action) {
+bool InputDefault::is_action_pressed(const StringName& p_action) const{
+ return action_state.has(p_action) && action_state[p_action].pressed;
+#if 0
if (custom_action_press.has(p_action))
return true; //simpler
@@ -147,9 +149,37 @@ bool InputDefault::is_action_pressed(const StringName& p_action) {
}
return false;
+#endif
}
-float InputDefault::get_joy_axis(int p_device,int p_axis) {
+bool InputDefault::is_action_just_pressed(const StringName& p_action) const {
+
+ const Map<StringName,Action>::Element *E=action_state.find(p_action);
+ if (!E)
+ return false;
+
+ if (OS::get_singleton()->is_in_fixed_frame()) {
+ return E->get().pressed && E->get().fixed_frame==OS::get_singleton()->get_fixed_frames();
+ } else {
+ return E->get().pressed && E->get().idle_frame==OS::get_singleton()->get_idle_frames();
+ }
+}
+
+bool InputDefault::is_action_just_released(const StringName& p_action) const{
+
+ const Map<StringName,Action>::Element *E=action_state.find(p_action);
+ if (!E)
+ return false;
+
+ if (OS::get_singleton()->is_in_fixed_frame()) {
+ return !E->get().pressed && E->get().fixed_frame==OS::get_singleton()->get_fixed_frames();
+ } else {
+ return !E->get().pressed && E->get().idle_frame==OS::get_singleton()->get_idle_frames();
+ }
+}
+
+
+float InputDefault::get_joy_axis(int p_device,int p_axis) const{
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis,p_device);
@@ -247,19 +277,19 @@ void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_
emit_signal("joy_connection_changed", p_idx, p_connected);
};
-Vector3 InputDefault::get_accelerometer() {
+Vector3 InputDefault::get_accelerometer() const{
_THREAD_SAFE_METHOD_
return accelerometer;
}
-Vector3 InputDefault::get_magnetometer() {
+Vector3 InputDefault::get_magnetometer() const{
_THREAD_SAFE_METHOD_
return magnetometer;
}
-Vector3 InputDefault::get_gyroscope() {
+Vector3 InputDefault::get_gyroscope() const {
_THREAD_SAFE_METHOD_
return gyroscope;
@@ -341,6 +371,23 @@ void InputDefault::parse_input_event(const 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()) {
+
+ if (InputMap::get_singleton()->event_is_action(p_event,E->key())) {
+
+ Action action;
+ action.fixed_frame=OS::get_singleton()->get_fixed_frames();
+ action.idle_frame=OS::get_singleton()->get_idle_frames();
+ action.pressed=p_event.is_pressed();
+
+ action_state[E->key()]=action;
+
+ }
+ }
+ }
+
if (main_loop)
main_loop->input_event(p_event);
@@ -441,21 +488,25 @@ void InputDefault::iteration(float p_step) {
void InputDefault::action_press(const StringName& p_action) {
- if (custom_action_press.has(p_action)) {
+ Action action;
+
+ action.fixed_frame=OS::get_singleton()->get_fixed_frames();
+ action.idle_frame=OS::get_singleton()->get_idle_frames();
+ action.pressed=true;
+
+ action_state[p_action]=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);
- }
+ Action action;
+
+ action.fixed_frame=OS::get_singleton()->get_fixed_frames();
+ action.idle_frame=OS::get_singleton()->get_idle_frames();
+ action.pressed=true;
+
+ action_state[p_action]=action;
}
void InputDefault::set_emulate_touch(bool p_emulate) {
diff --git a/main/input_default.h b/main/input_default.h
index cb71312e22..fbf7837b3b 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -38,16 +38,27 @@ class InputDefault : public 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<StringName,int> custom_action_press;
Vector3 accelerometer;
Vector3 magnetometer;
Vector3 gyroscope;
Vector2 mouse_pos;
MainLoop *main_loop;
+ struct Action {
+ uint64_t fixed_frame;
+ uint64_t idle_frame;
+ bool pressed;
+ };
+
+ Map<StringName,Action> action_state;
+
+
bool emulate_touch;
struct VibrationInfo {
@@ -164,12 +175,14 @@ 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 bool is_key_pressed(int p_scancode) const;
+ virtual bool is_mouse_button_pressed(int p_button) const;
+ virtual bool is_joy_button_pressed(int p_device, int p_button) const;
+ 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_joy_axis(int p_device,int p_axis);
+ virtual float get_joy_axis(int p_device,int p_axis) const;
String get_joy_name(int p_idx);
virtual Array get_connected_joysticks();
virtual Vector2 get_joy_vibration_strength(int p_device);
@@ -178,9 +191,9 @@ public:
void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid = "");
void parse_joystick_mapping(String p_mapping, bool p_update_existing);
- virtual Vector3 get_accelerometer();
- virtual Vector3 get_magnetometer();
- virtual Vector3 get_gyroscope();
+ virtual Vector3 get_accelerometer() const;
+ virtual Vector3 get_magnetometer() const;
+ virtual Vector3 get_gyroscope() const;
virtual Point2 get_mouse_pos() const;
virtual Point2 get_mouse_speed() const;
diff --git a/main/main.cpp b/main/main.cpp
index aa8540632f..e339f399de 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1560,6 +1560,8 @@ bool Main::iteration() {
int iters = 0;
+ OS::get_singleton()->_in_fixed=true;
+
while(time_accum>frame_slice) {
uint64_t fixed_begin = OS::get_singleton()->get_ticks_usec();
@@ -1590,8 +1592,11 @@ bool Main::iteration() {
fixed_process_ticks=MAX(fixed_process_ticks,OS::get_singleton()->get_ticks_usec()-fixed_begin); // keep the largest one for reference
fixed_process_max=MAX(OS::get_singleton()->get_ticks_usec()-fixed_begin,fixed_process_max);
iters++;
+ OS::get_singleton()->_fixed_frames++;
}
+ OS::get_singleton()->_in_fixed=false;
+
uint64_t idle_begin = OS::get_singleton()->get_ticks_usec();
OS::get_singleton()->get_main_loop()->idle( step*time_scale );
@@ -1640,6 +1645,7 @@ bool Main::iteration() {
// x11_delay_usec(10000);
frames++;
+ OS::get_singleton()->_idle_frames++;
if (frame>1000000) {
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index f5c5159af7..c0efa8b4ba 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -3247,13 +3247,29 @@ PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) cons
String VisualScriptInputAction::get_caption() const {
+
return "Action";
}
String VisualScriptInputAction::get_text() const {
- return name;
+ switch(mode) {
+ case MODE_PRESSED: {
+ return name;
+ } break;
+ case MODE_RELEASED: {
+ return "not "+name;
+ } break;
+ case MODE_JUST_PRESSED: {
+ return String(name)+" "+TTR("just pressed");
+ } break;
+ case MODE_JUST_RELEASED: {
+ return String(name)+" "+TTR("just released");
+ } break;
+ }
+
+ return String();
}
@@ -3278,19 +3294,50 @@ StringName VisualScriptInputAction::get_action_name() const {
return name;
}
+void VisualScriptInputAction::set_action_mode(Mode p_mode) {
+
+ if (mode==p_mode)
+ return;
+
+ mode=p_mode;
+ ports_changed_notify();
+
+}
+VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const {
+
+ return mode;
+}
+
class VisualScriptNodeInstanceInputAction : public VisualScriptNodeInstance {
public:
VisualScriptInstance* instance;
StringName action;
+ VisualScriptInputAction::Mode mode;
virtual int get_working_memory_size() const { return 1; }
virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
- *p_outputs[0]=Input::get_singleton()->is_action_pressed(action);
+ switch(mode) {
+ case VisualScriptInputAction::MODE_PRESSED: {
+ *p_outputs[0]=Input::get_singleton()->is_action_pressed(action);
+ } break;
+ case VisualScriptInputAction::MODE_RELEASED: {
+ *p_outputs[0]=!Input::get_singleton()->is_action_pressed(action);
+ } break;
+ case VisualScriptInputAction::MODE_JUST_PRESSED: {
+ *p_outputs[0]=Input::get_singleton()->is_action_just_pressed(action);
+ } break;
+ case VisualScriptInputAction:: MODE_JUST_RELEASED: {
+ *p_outputs[0]=Input::get_singleton()->is_action_just_released(action);
+ } break;
+
+ }
+
+
return 0;
}
@@ -3302,6 +3349,7 @@ VisualScriptNodeInstance* VisualScriptInputAction::instance(VisualScriptInstance
VisualScriptNodeInstanceInputAction * instance = memnew(VisualScriptNodeInstanceInputAction );
instance->instance=p_instance;
instance->action=name;
+ instance->mode=mode;
return instance;
}
@@ -3348,13 +3396,18 @@ void VisualScriptInputAction::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_action_name","name"),&VisualScriptInputAction::set_action_name);
ObjectTypeDB::bind_method(_MD("get_action_name"),&VisualScriptInputAction::get_action_name);
+ ObjectTypeDB::bind_method(_MD("set_action_mode","mode"),&VisualScriptInputAction::set_action_mode);
+ ObjectTypeDB::bind_method(_MD("get_action_mode"),&VisualScriptInputAction::get_action_mode);
+
ADD_PROPERTY( PropertyInfo(Variant::STRING,"action"),_SCS("set_action_name"),_SCS("get_action_name"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Pressed,Released,JustPressed,JustReleased"),_SCS("set_action_mode"),_SCS("get_action_mode"));
}
VisualScriptInputAction::VisualScriptInputAction() {
name="";
+ mode=MODE_PRESSED;
}
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index c0ffb17e15..eeb2f3328d 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -906,8 +906,16 @@ public:
class VisualScriptInputAction: public VisualScriptNode {
OBJ_TYPE(VisualScriptInputAction,VisualScriptNode)
+public:
+ enum Mode {
+ MODE_PRESSED,
+ MODE_RELEASED,
+ MODE_JUST_PRESSED,
+ MODE_JUST_RELEASED,
+ };
StringName name;
+ Mode mode;
protected:
@@ -936,12 +944,15 @@ public:
void set_action_name(const StringName& p_name);
StringName get_action_name() const;
+ void set_action_mode(Mode p_mode);
+ Mode get_action_mode() const;
+
virtual VisualScriptNodeInstance* instance(VisualScriptInstance* p_instance);
VisualScriptInputAction();
};
-
+VARIANT_ENUM_CAST( VisualScriptInputAction::Mode )
class VisualScriptDeconstruct: public VisualScriptNode {