summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/globals.cpp2
-rw-r--r--core/io/config_file.cpp2
-rw-r--r--core/io/file_access_pack.cpp4
-rw-r--r--core/io/resource_format_xml.cpp2
-rw-r--r--core/math/math_funcs.cpp7
-rw-r--r--core/object.cpp17
-rw-r--r--core/object.h1
-rw-r--r--core/undo_redo.cpp8
-rw-r--r--demos/2d/isometric/bastiles.resbin1840 -> 2918 bytes
-rw-r--r--demos/2d/isometric/dungeon.scnbin4721 -> 2841 bytes
-rw-r--r--demos/2d/isometric/tileset.scnbin2305 -> 2565 bytes
-rw-r--r--demos/2d/isometric/troll.scnbin1839 -> 2100 bytes
-rw-r--r--demos/2d/isometric_light/cubio.scnbin7003 -> 7006 bytes
-rw-r--r--demos/2d/isometric_light/map.scnbin8634 -> 8661 bytes
-rw-r--r--demos/2d/isometric_light/tileset.resbin2781 -> 2779 bytes
-rw-r--r--demos/2d/kinematic_char/player.gd2
-rw-r--r--demos/2d/lookat/arrow.pngbin0 -> 2528 bytes
-rw-r--r--demos/2d/lookat/engine.cfg4
-rw-r--r--demos/2d/lookat/lookat.gd43
-rw-r--r--demos/2d/lookat/lookat.scnbin0 -> 1622 bytes
-rw-r--r--demos/2d/platformer/player.gd1
-rw-r--r--demos/2d/tetris/grid.gd1
-rw-r--r--demos/3d/navmesh/navmesh.scnbin37856 -> 38129 bytes
-rw-r--r--demos/3d/platformer/bullet.scnbin6156 -> 6157 bytes
-rw-r--r--demos/3d/platformer/coin.scnbin6013 -> 6791 bytes
-rw-r--r--demos/3d/platformer/enemy.scnbin36976 -> 37784 bytes
-rw-r--r--demos/3d/shader_materials/shader_materials.scnbin5494 -> 6382 bytes
-rw-r--r--demos/gui/translation/controls.gd20
-rw-r--r--demos/gui/translation/controls.scnbin0 -> 2349 bytes
-rw-r--r--demos/gui/translation/engine.cfg9
-rw-r--r--demos/gui/translation/flag_japan.pngbin0 -> 1473 bytes
-rw-r--r--demos/gui/translation/flag_spain.pngbin0 -> 3048 bytes
-rw-r--r--demos/gui/translation/flag_uk.pngbin0 -> 6544 bytes
-rw-r--r--demos/gui/translation/main.gd42
-rw-r--r--demos/gui/translation/main.scnbin0 -> 2671 bytes
-rw-r--r--demos/gui/translation/noto.fntbin0 -> 9171 bytes
-rw-r--r--demos/gui/translation/notosans.otfbin0 -> 16426032 bytes
-rw-r--r--demos/gui/translation/text.csv3
-rw-r--r--demos/gui/translation/translations/text.en.xlbin0 -> 575 bytes
-rw-r--r--demos/gui/translation/translations/text.es.xlbin0 -> 579 bytes
-rw-r--r--demos/gui/translation/translations/text.ja.xlbin0 -> 595 bytes
-rw-r--r--demos/misc/window_management/control.gd10
-rw-r--r--demos/misc/window_management/window_management.scnbin5129 -> 5132 bytes
-rw-r--r--drivers/mpc/mpc_reader.c1
-rw-r--r--drivers/pvr/ColorRgba.h12
-rw-r--r--drivers/rtaudio/RtAudio.cpp358
-rw-r--r--drivers/rtaudio/RtAudio.h3
-rw-r--r--drivers/vorbis/psy.c2
-rw-r--r--drivers/windows/dir_access_windows.cpp36
-rw-r--r--main/main.cpp19
-rw-r--r--modules/gdscript/gd_functions.cpp24
-rw-r--r--modules/gdscript/gd_functions.h1
-rw-r--r--modules/gdscript/gd_tokenizer.cpp2
-rw-r--r--platform/android/java/src/com/android/godot/Godot.java3
-rw-r--r--platform/osx/os_osx.mm19
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/x11/os_x11.cpp4
-rw-r--r--scene/2d/camera_2d.cpp3
-rw-r--r--scene/2d/node_2d.cpp14
-rw-r--r--scene/2d/node_2d.h3
-rw-r--r--scene/2d/physics_body_2d.cpp14
-rw-r--r--scene/2d/physics_body_2d.h5
-rw-r--r--scene/animation/tween_interpolaters.cpp12
-rw-r--r--scene/gui/button.cpp2
-rw-r--r--scene/gui/check_box.cpp2
-rw-r--r--scene/gui/label.cpp2
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp10
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--scene/main/node.cpp36
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/timer.cpp69
-rw-r--r--scene/main/timer.h14
-rw-r--r--scene/main/viewport.cpp6
-rw-r--r--scene/main/viewport.h1
-rw-r--r--servers/physics/collision_object_sw.h4
-rw-r--r--servers/physics/physics_server_sw.cpp2
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp15
-rw-r--r--servers/physics_2d/body_pair_2d_sw.h1
-rw-r--r--servers/physics_2d/space_2d_sw.cpp7
-rw-r--r--servers/visual/rasterizer.h10
-rw-r--r--servers/visual/visual_server_raster.cpp2
-rw-r--r--tools/docdump/doc_dump.cpp2
-rw-r--r--tools/editor/animation_editor.cpp2
-rw-r--r--tools/editor/editor_file_system.cpp8
-rw-r--r--tools/editor/editor_node.cpp2
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.cpp2
-rw-r--r--tools/editor/plugins/shader_graph_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp7
-rw-r--r--tools/editor/project_manager.cpp2
-rw-r--r--tools/editor/project_settings.cpp5
-rw-r--r--tools/editor/spatial_editor_gizmos.cpp3
-rw-r--r--tools/pck/pck_packer.cpp2
93 files changed, 709 insertions, 232 deletions
diff --git a/core/globals.cpp b/core/globals.cpp
index b128914de5..23d8c16ace 100644
--- a/core/globals.cpp
+++ b/core/globals.cpp
@@ -1381,7 +1381,7 @@ Globals::Globals() {
set("application/name","" );
set("application/main_scene","");
- custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"xml,res,scn,xscn");
+ custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"scn,res,xscn,xml");
set("application/disable_stdout",false);
set("application/use_shared_user_dir",true);
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 95ae31f3dd..75388f514a 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -357,6 +357,7 @@ if (res!=-1 && res < min_pos) {\
} break;
case MIN_OPEN: {
int level=1;
+ end++;
while(end<close_pos) {
if (str[end]=='[')
@@ -373,6 +374,7 @@ if (res!=-1 && res < min_pos) {\
} break;
case MIN_CURLY_OPEN: {
int level=1;
+ end++;
while(end<close_pos) {
if (str[end]=='{')
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index bf1211f2b3..339a6d0528 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -92,7 +92,9 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o
void PackedData::add_pack_source(PackSource *p_source) {
- sources.push_back(p_source);
+ if (p_source != NULL) {
+ sources.push_back(p_source);
+ }
};
PackedData *PackedData::singleton=NULL;
diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp
index 9de33e7ef3..3e625ba6fd 100644
--- a/core/io/resource_format_xml.cpp
+++ b/core/io/resource_format_xml.cpp
@@ -1850,7 +1850,7 @@ void ResourceFormatSaverXMLInstance::escape(String& p_str) {
p_str=p_str.replace(">","&lt;");
p_str=p_str.replace("'","&apos;");
p_str=p_str.replace("\"","&quot;");
- for (int i=1;i<32;i++) {
+ for (char i=1;i<32;i++) {
char chr[2]={i,0};
const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 6ad5c7499b..3c94ac5bc7 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -36,8 +36,9 @@ uint32_t Math::default_seed=1;
#define PHI 0x9e3779b9
-static uint32_t Q[4096], c = 362436;
-
+#if 0
+static uint32_t Q[4096];
+#endif
uint32_t Math::rand_from_seed(uint32_t *seed) {
@@ -269,7 +270,7 @@ bool Math::is_inf(double p_val) {
uint32_t Math::larger_prime(uint32_t p_val) {
- static const int primes[] = {
+ static const uint32_t primes[] = {
5,
13,
23,
diff --git a/core/object.cpp b/core/object.cpp
index 07e24655c2..c1904d05d7 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1282,6 +1282,23 @@ void Object::get_signal_list(List<MethodInfo> *p_signals ) const {
}
}
+
+void Object::get_all_signal_connections(List<Connection> *p_connections) const {
+
+ const StringName *S=NULL;
+
+ while((S=signal_map.next(S))) {
+
+ const Signal *s=&signal_map[*S];
+
+ for(int i=0;i<s->slot_map.size();i++) {
+
+ p_connections->push_back(s->slot_map.getv(i).conn);
+ }
+ }
+
+}
+
void Object::get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const {
const Signal *s=signal_map.getptr(p_signal);
diff --git a/core/object.h b/core/object.h
index 44464ab199..fc64b91412 100644
--- a/core/object.h
+++ b/core/object.h
@@ -574,6 +574,7 @@ public:
void emit_signal(const StringName& p_name,VARIANT_ARG_LIST);
void get_signal_list(List<MethodInfo> *p_signals ) const;
void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const;
+ void get_all_signal_connections(List<Connection> *p_connections) const;
Error connect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method,const Vector<Variant>& p_binds=Vector<Variant>(),uint32_t p_flags=0);
void disconnect(const StringName& p_signal, Object *p_to_object, const StringName& p_to_method);
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index f266595772..5e7df3be7e 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -234,11 +234,17 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
ERR_FAIL_COND(!obj);
}
+
switch(op.type) {
case Operation::TYPE_METHOD: {
- obj->call(op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
+ obj->call(op.name,VARIANT_ARGS_FROM_ARRAY(op.args));
+#ifdef TOOLS_ENABLED
+ Resource* res = obj->cast_to<Resource>();
+ if (res)
+ res->set_edited(true);
+#endif
} break;
case Operation::TYPE_PROPERTY: {
diff --git a/demos/2d/isometric/bastiles.res b/demos/2d/isometric/bastiles.res
index 2161c88f1e..50f3c78321 100644
--- a/demos/2d/isometric/bastiles.res
+++ b/demos/2d/isometric/bastiles.res
Binary files differ
diff --git a/demos/2d/isometric/dungeon.scn b/demos/2d/isometric/dungeon.scn
index 58c530d5c5..64efc257c0 100644
--- a/demos/2d/isometric/dungeon.scn
+++ b/demos/2d/isometric/dungeon.scn
Binary files differ
diff --git a/demos/2d/isometric/tileset.scn b/demos/2d/isometric/tileset.scn
index edb0bc0276..c04ea5382c 100644
--- a/demos/2d/isometric/tileset.scn
+++ b/demos/2d/isometric/tileset.scn
Binary files differ
diff --git a/demos/2d/isometric/troll.scn b/demos/2d/isometric/troll.scn
index f5d87c3631..19b566fe05 100644
--- a/demos/2d/isometric/troll.scn
+++ b/demos/2d/isometric/troll.scn
Binary files differ
diff --git a/demos/2d/isometric_light/cubio.scn b/demos/2d/isometric_light/cubio.scn
index c52b7dfd4b..fc931b0c8d 100644
--- a/demos/2d/isometric_light/cubio.scn
+++ b/demos/2d/isometric_light/cubio.scn
Binary files differ
diff --git a/demos/2d/isometric_light/map.scn b/demos/2d/isometric_light/map.scn
index c1d11f8e4c..89002f991f 100644
--- a/demos/2d/isometric_light/map.scn
+++ b/demos/2d/isometric_light/map.scn
Binary files differ
diff --git a/demos/2d/isometric_light/tileset.res b/demos/2d/isometric_light/tileset.res
index dab6f36f57..f64a4e32bd 100644
--- a/demos/2d/isometric_light/tileset.res
+++ b/demos/2d/isometric_light/tileset.res
Binary files differ
diff --git a/demos/2d/kinematic_char/player.gd b/demos/2d/kinematic_char/player.gd
index ddc0271de0..329382408b 100644
--- a/demos/2d/kinematic_char/player.gd
+++ b/demos/2d/kinematic_char/player.gd
@@ -34,8 +34,6 @@ func _fixed_process(delta):
#create forces
var force = Vector2(0,GRAVITY)
-
- var stop = velocity.x!=0.0
var walk_left = Input.is_action_pressed("move_left")
var walk_right = Input.is_action_pressed("move_right")
diff --git a/demos/2d/lookat/arrow.png b/demos/2d/lookat/arrow.png
new file mode 100644
index 0000000000..25db91e8d1
--- /dev/null
+++ b/demos/2d/lookat/arrow.png
Binary files differ
diff --git a/demos/2d/lookat/engine.cfg b/demos/2d/lookat/engine.cfg
new file mode 100644
index 0000000000..56917a39ec
--- /dev/null
+++ b/demos/2d/lookat/engine.cfg
@@ -0,0 +1,4 @@
+[application]
+
+name="Look At Pointer"
+main_scene="res://lookat.scn"
diff --git a/demos/2d/lookat/lookat.gd b/demos/2d/lookat/lookat.gd
new file mode 100644
index 0000000000..742c5b0671
--- /dev/null
+++ b/demos/2d/lookat/lookat.gd
@@ -0,0 +1,43 @@
+
+extends Sprite
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+const MODE_DIRECT=0
+const MODE_CONSTANT=1
+const MODE_SMOOTH=2
+
+const ROTATION_SPEED = 1
+const SMOOTH_SPEED = 2.0
+
+export(int,"Direct","Constant","Smooth") var mode=MODE_DIRECT
+
+func _process(delta):
+ var mpos = get_viewport().get_mouse_pos()
+
+ if (mode==MODE_DIRECT):
+
+ look_at(mpos)
+
+ elif (mode==MODE_CONSTANT):
+
+ var ang = get_angle_to(mpos)
+ var s = sign(ang)
+ ang=abs(ang)
+
+ rotate( min(ang,ROTATION_SPEED*delta)*s )
+
+ elif (mode==MODE_SMOOTH):
+
+ var ang = get_angle_to(mpos)
+
+ rotate( ang*delta*SMOOTH_SPEED )
+
+func _ready():
+ # Initialization here
+ set_process(true)
+ pass
+
+
diff --git a/demos/2d/lookat/lookat.scn b/demos/2d/lookat/lookat.scn
new file mode 100644
index 0000000000..880070b4c7
--- /dev/null
+++ b/demos/2d/lookat/lookat.scn
Binary files differ
diff --git a/demos/2d/platformer/player.gd b/demos/2d/platformer/player.gd
index b08105212c..9ee189df21 100644
--- a/demos/2d/platformer/player.gd
+++ b/demos/2d/platformer/player.gd
@@ -33,7 +33,6 @@ var shooting=false
var WALK_ACCEL = 800.0
var WALK_DEACCEL= 800.0
var WALK_MAX_VELOCITY= 200.0
-var GRAVITY = 700.0
var AIR_ACCEL = 200.0
var AIR_DEACCEL= 200.0
var JUMP_VELOCITY=460
diff --git a/demos/2d/tetris/grid.gd b/demos/2d/tetris/grid.gd
index dc89300881..8708d168e4 100644
--- a/demos/2d/tetris/grid.gd
+++ b/demos/2d/tetris/grid.gd
@@ -143,6 +143,7 @@ func restart_pressed():
cells.clear()
get_node("gameover").set_text("")
piece_active=true
+ get_node("../restart").release_focus()
update()
diff --git a/demos/3d/navmesh/navmesh.scn b/demos/3d/navmesh/navmesh.scn
index 73df340b1e..1202985dec 100644
--- a/demos/3d/navmesh/navmesh.scn
+++ b/demos/3d/navmesh/navmesh.scn
Binary files differ
diff --git a/demos/3d/platformer/bullet.scn b/demos/3d/platformer/bullet.scn
index 4f1623b7d9..da90dba1a5 100644
--- a/demos/3d/platformer/bullet.scn
+++ b/demos/3d/platformer/bullet.scn
Binary files differ
diff --git a/demos/3d/platformer/coin.scn b/demos/3d/platformer/coin.scn
index 449bb0f895..a4148b4060 100644
--- a/demos/3d/platformer/coin.scn
+++ b/demos/3d/platformer/coin.scn
Binary files differ
diff --git a/demos/3d/platformer/enemy.scn b/demos/3d/platformer/enemy.scn
index b3f69af600..06d725061d 100644
--- a/demos/3d/platformer/enemy.scn
+++ b/demos/3d/platformer/enemy.scn
Binary files differ
diff --git a/demos/3d/shader_materials/shader_materials.scn b/demos/3d/shader_materials/shader_materials.scn
index d6a3efe73f..243c6c8f06 100644
--- a/demos/3d/shader_materials/shader_materials.scn
+++ b/demos/3d/shader_materials/shader_materials.scn
Binary files differ
diff --git a/demos/gui/translation/controls.gd b/demos/gui/translation/controls.gd
new file mode 100644
index 0000000000..f8403f49a7
--- /dev/null
+++ b/demos/gui/translation/controls.gd
@@ -0,0 +1,20 @@
+
+extends Panel
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+func _ready():
+ # Initialization here
+ pass
+
+
+
+
+func _on_back_pressed():
+ var s = load("res://main.scn")
+ var si = s.instance()
+ get_parent().add_child(si)
+ queue_free()
+ pass # replace with function body
diff --git a/demos/gui/translation/controls.scn b/demos/gui/translation/controls.scn
new file mode 100644
index 0000000000..66e6d47702
--- /dev/null
+++ b/demos/gui/translation/controls.scn
Binary files differ
diff --git a/demos/gui/translation/engine.cfg b/demos/gui/translation/engine.cfg
new file mode 100644
index 0000000000..169b65e154
--- /dev/null
+++ b/demos/gui/translation/engine.cfg
@@ -0,0 +1,9 @@
+[application]
+
+name="Translation Demo"
+main_scene="res://main.scn"
+
+[locale]
+
+translations=["res://translations/text.en.xl", "res://translations/text.es.xl", "res://translations/text.ja.xl"]
+translation_remaps={"res://flag_uk.png":["res://flag_spain.png:es", "res://flag_japan.png:ja"]}
diff --git a/demos/gui/translation/flag_japan.png b/demos/gui/translation/flag_japan.png
new file mode 100644
index 0000000000..4cc8267a5c
--- /dev/null
+++ b/demos/gui/translation/flag_japan.png
Binary files differ
diff --git a/demos/gui/translation/flag_spain.png b/demos/gui/translation/flag_spain.png
new file mode 100644
index 0000000000..4d00f93593
--- /dev/null
+++ b/demos/gui/translation/flag_spain.png
Binary files differ
diff --git a/demos/gui/translation/flag_uk.png b/demos/gui/translation/flag_uk.png
new file mode 100644
index 0000000000..53fbef3d67
--- /dev/null
+++ b/demos/gui/translation/flag_uk.png
Binary files differ
diff --git a/demos/gui/translation/main.gd b/demos/gui/translation/main.gd
new file mode 100644
index 0000000000..bf3c0c0840
--- /dev/null
+++ b/demos/gui/translation/main.gd
@@ -0,0 +1,42 @@
+
+extends Panel
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+func _ready():
+ # Initialization here
+ pass
+
+
+
+func _goto_scene():
+ var s = load("res://controls.scn")
+ var si = s.instance()
+ get_parent().add_child(si)
+ queue_free()
+ pass
+
+
+func _on_system_pressed():
+ #will autodetect based on system, then fall back
+ #to english if not found
+ _goto_scene()
+
+#NOTE: Changling locale will not change the text in the controls,
+# The scene must be reloaded for changes to take effect.
+
+func _on_english_pressed():
+ TranslationServer.set_locale("en")
+ _goto_scene()
+
+
+func _on_spanish_pressed():
+ TranslationServer.set_locale("es")
+ _goto_scene()
+
+
+func _on_japanese_pressed():
+ TranslationServer.set_locale("ja")
+ _goto_scene()
diff --git a/demos/gui/translation/main.scn b/demos/gui/translation/main.scn
new file mode 100644
index 0000000000..76c9ba7b45
--- /dev/null
+++ b/demos/gui/translation/main.scn
Binary files differ
diff --git a/demos/gui/translation/noto.fnt b/demos/gui/translation/noto.fnt
new file mode 100644
index 0000000000..e019615f41
--- /dev/null
+++ b/demos/gui/translation/noto.fnt
Binary files differ
diff --git a/demos/gui/translation/notosans.otf b/demos/gui/translation/notosans.otf
new file mode 100644
index 0000000000..6443f9023e
--- /dev/null
+++ b/demos/gui/translation/notosans.otf
Binary files differ
diff --git a/demos/gui/translation/text.csv b/demos/gui/translation/text.csv
new file mode 100644
index 0000000000..0f4c148b95
--- /dev/null
+++ b/demos/gui/translation/text.csv
@@ -0,0 +1,3 @@
+,en,es,ja
+KEY_HELLO,Hello!,Hola!,こんにちは
+KEY_PUSH,Push Me!,Aprétame!,私をプッシュ \ No newline at end of file
diff --git a/demos/gui/translation/translations/text.en.xl b/demos/gui/translation/translations/text.en.xl
new file mode 100644
index 0000000000..7bcba63e71
--- /dev/null
+++ b/demos/gui/translation/translations/text.en.xl
Binary files differ
diff --git a/demos/gui/translation/translations/text.es.xl b/demos/gui/translation/translations/text.es.xl
new file mode 100644
index 0000000000..4474d955d5
--- /dev/null
+++ b/demos/gui/translation/translations/text.es.xl
Binary files differ
diff --git a/demos/gui/translation/translations/text.ja.xl b/demos/gui/translation/translations/text.ja.xl
new file mode 100644
index 0000000000..b3d1f0bf60
--- /dev/null
+++ b/demos/gui/translation/translations/text.ja.xl
Binary files differ
diff --git a/demos/misc/window_management/control.gd b/demos/misc/window_management/control.gd
index 5eb5817619..1609dda699 100644
--- a/demos/misc/window_management/control.gd
+++ b/demos/misc/window_management/control.gd
@@ -1,6 +1,8 @@
extends Control
+var mousepos
+
func _fixed_process(delta):
var modetext = "Mode:\n"
@@ -31,7 +33,7 @@ func _fixed_process(delta):
get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) )
- get_node("Label_MousePosition").set_text(str("Mouse Position:\n", Input.get_mouse_pos() ) )
+ get_node("Label_MousePosition").set_text(str("Mouse Position:\n", mousepos ) )
get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) )
@@ -126,6 +128,12 @@ func check_wm_api():
func _ready():
if( check_wm_api() ):
set_fixed_process(true)
+ set_process_input(true)
+
+
+func _input(ev):
+ if (ev.type==InputEvent.MOUSE_MOTION):
+ mousepos = ev.pos
func _on_Button_MoveTo_pressed():
diff --git a/demos/misc/window_management/window_management.scn b/demos/misc/window_management/window_management.scn
index c7d6260df6..8db43b6638 100644
--- a/demos/misc/window_management/window_management.scn
+++ b/demos/misc/window_management/window_management.scn
Binary files differ
diff --git a/drivers/mpc/mpc_reader.c b/drivers/mpc/mpc_reader.c
index e1d151fe50..550c5ecb54 100644
--- a/drivers/mpc/mpc_reader.c
+++ b/drivers/mpc/mpc_reader.c
@@ -36,6 +36,7 @@
#include <mpc/reader.h>
#include "internal.h"
#include <stdio.h>
+#include <string.h> // memset()
#define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value...
typedef struct mpc_reader_stdio_t {
diff --git a/drivers/pvr/ColorRgba.h b/drivers/pvr/ColorRgba.h
index 6b46d65e3c..0701420566 100644
--- a/drivers/pvr/ColorRgba.h
+++ b/drivers/pvr/ColorRgba.h
@@ -11,21 +11,21 @@ public:
ColorRgb()
- : r(0)
+ : b(0)
, g(0)
- , b(0) {
+ , r(0) {
}
ColorRgb(T red, T green, T blue)
- : r(red)
+ : b(blue)
, g(green)
- , b(blue) {
+ , r(red) {
}
ColorRgb(const ColorRgb<T> &x)
- : r(x.r)
+ : b(x.b)
, g(x.g)
- , b(x.b) {
+ , r(x.r) {
}
ColorRgb<int> operator *(int x) {
diff --git a/drivers/rtaudio/RtAudio.cpp b/drivers/rtaudio/RtAudio.cpp
index 04e7b4422e..8876f72e21 100644
--- a/drivers/rtaudio/RtAudio.cpp
+++ b/drivers/rtaudio/RtAudio.cpp
@@ -46,6 +46,7 @@
#include <cstdlib>
#include <cstring>
#include <climits>
+#include <algorithm>
// Static variable definitions.
const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
@@ -63,6 +64,22 @@ const unsigned int RtApi::SAMPLE_RATES[] = {
#define MUTEX_DESTROY(A) DeleteCriticalSection(A)
#define MUTEX_LOCK(A) EnterCriticalSection(A)
#define MUTEX_UNLOCK(A) LeaveCriticalSection(A)
+
+ #include "tchar.h"
+
+ static std::string convertCharPointerToStdString(const char *text)
+ {
+ return std::string(text);
+ }
+
+ static std::string convertCharPointerToStdString(const wchar_t *text)
+ {
+ int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL);
+ std::string s( length-1, '\0' );
+ WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL);
+ return s;
+ }
+
#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
// pthread API
#define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
@@ -184,7 +201,7 @@ RtAudio :: RtAudio( RtAudio::Api api )
getCompiledApi( apis );
for ( unsigned int i=0; i<apis.size(); i++ ) {
openRtApi( apis[i] );
- if ( rtapi_->getDeviceCount() ) break;
+ if ( rtapi_ && rtapi_->getDeviceCount() ) break;
}
if ( rtapi_ ) return;
@@ -766,9 +783,14 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
bool haveValueRange = false;
info.sampleRates.clear();
for ( UInt32 i=0; i<nRanges; i++ ) {
- if ( rangeList[i].mMinimum == rangeList[i].mMaximum )
- info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum );
- else {
+ if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) {
+ unsigned int tmpSr = (unsigned int) rangeList[i].mMinimum;
+ info.sampleRates.push_back( tmpSr );
+
+ if ( !info.preferredSampleRate || ( tmpSr <= 48000 && tmpSr > info.preferredSampleRate ) )
+ info.preferredSampleRate = tmpSr;
+
+ } else {
haveValueRange = true;
if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
@@ -777,8 +799,12 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
if ( haveValueRange ) {
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
- if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )
+ if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+ }
}
}
@@ -1385,6 +1411,18 @@ void RtApiCore :: closeStream( void )
CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+ if (handle) {
+ AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster };
+
+ property.mSelector = kAudioDeviceProcessorOverload;
+ property.mScope = kAudioObjectPropertyScopeGlobal;
+ if (AudioObjectRemovePropertyListener( handle->id[0], &property, xrunListener, (void *) handle ) != noErr) {
+ errorText_ = "RtApiCore::closeStream(): error removing property listener!";
+ error( RtAudioError::WARNING );
+ }
+ }
if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[0], callbackHandler );
#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
@@ -1396,6 +1434,18 @@ void RtApiCore :: closeStream( void )
}
if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
+ if (handle) {
+ AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster };
+
+ property.mSelector = kAudioDeviceProcessorOverload;
+ property.mScope = kAudioObjectPropertyScopeGlobal;
+ if (AudioObjectRemovePropertyListener( handle->id[1], &property, xrunListener, (void *) handle ) != noErr) {
+ errorText_ = "RtApiCore::closeStream(): error removing property listener!";
+ error( RtAudioError::WARNING );
+ }
+ }
if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[1], callbackHandler );
#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
@@ -1989,7 +2039,9 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
// Get the current jack server sample rate.
info.sampleRates.clear();
- info.sampleRates.push_back( jack_get_sample_rate( client ) );
+
+ info.preferredSampleRate = jack_get_sample_rate( client );
+ info.sampleRates.push_back( info.preferredSampleRate );
// Count the available ports containing the client name as device
// channels. Jack "input ports" equal RtAudio output channels.
@@ -2769,8 +2821,12 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
- if ( result == ASE_OK )
+ if ( result == ASE_OK ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[i];
+ }
}
// Determine supported data types ... just check first channel and assume rest are the same.
@@ -2829,9 +2885,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options )
-{
+{////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ bool isDuplexInput = mode == INPUT && stream_.mode == OUTPUT;
+
// For ASIO, a duplex stream MUST use the same driver.
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] != device ) {
+ if ( isDuplexInput && stream_.device[0] != device ) {
errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!";
return FAILURE;
}
@@ -2845,7 +2904,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
// Only load the driver once for duplex stream.
- if ( mode != INPUT || stream_.mode != OUTPUT ) {
+ if ( !isDuplexInput ) {
// The getDeviceInfo() function will not work when a stream is open
// because ASIO does not allow multiple devices to run at the same
// time. Thus, we'll probe the system before opening a stream and
@@ -2866,22 +2925,26 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
}
+ // keep them before any "goto error", they are used for error cleanup + goto device boundary checks
+ bool buffersAllocated = false;
+ AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+ unsigned int nChannels;
+
+
// Check the device channel count.
long inputChannels, outputChannels;
result = ASIOGetChannels( &inputChannels, &outputChannels );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
stream_.nDeviceChannels[mode] = channels;
stream_.nUserChannels[mode] = channels;
@@ -2890,30 +2953,27 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
// Verify the sample rate is supported.
result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Get the current sample rate
ASIOSampleRate currentRate;
result = ASIOGetSampleRate( &currentRate );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Set the sample rate only if necessary
if ( currentRate != sampleRate ) {
result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
}
@@ -2924,10 +2984,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
else channelInfo.isInput = true;
result = ASIOGetChannelInfo( &channelInfo );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Assuming WINDOWS host is always little-endian.
@@ -2956,10 +3015,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
if ( stream_.deviceFormat[mode] == 0 ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Set the buffer size. For a duplex stream, this will end up
@@ -2968,49 +3026,63 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
long minSize, maxSize, preferSize, granularity;
result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
- if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
- else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
- else if ( granularity == -1 ) {
- // Make sure bufferSize is a power of two.
- int log2_of_min_size = 0;
- int log2_of_max_size = 0;
+ if ( isDuplexInput ) {
+ // When this is the duplex input (output was opened before), then we have to use the same
+ // buffersize as the output, because it might use the preferred buffer size, which most
+ // likely wasn't passed as input to this. The buffer sizes have to be identically anyway,
+ // So instead of throwing an error, make them equal. The caller uses the reference
+ // to the "bufferSize" param as usual to set up processing buffers.
- for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
- if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
- if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
- }
+ *bufferSize = stream_.bufferSize;
- long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
- int min_delta_num = log2_of_min_size;
+ } else {
+ if ( *bufferSize == 0 ) *bufferSize = preferSize;
+ else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
+ else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
+ else if ( granularity == -1 ) {
+ // Make sure bufferSize is a power of two.
+ int log2_of_min_size = 0;
+ int log2_of_max_size = 0;
- for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
- long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
- if (current_delta < min_delta) {
- min_delta = current_delta;
- min_delta_num = i;
+ for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
+ if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
+ if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
}
- }
- *bufferSize = ( (unsigned int)1 << min_delta_num );
- if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
- else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
- }
- else if ( granularity != 0 ) {
- // Set to an even multiple of granularity, rounding up.
- *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
+ long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
+ int min_delta_num = log2_of_min_size;
+
+ for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
+ long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
+ if (current_delta < min_delta) {
+ min_delta = current_delta;
+ min_delta_num = i;
+ }
+ }
+
+ *bufferSize = ( (unsigned int)1 << min_delta_num );
+ if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
+ else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
+ }
+ else if ( granularity != 0 ) {
+ // Set to an even multiple of granularity, rounding up.
+ *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
+ }
}
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.bufferSize != *bufferSize ) {
- drivers.removeCurrentDriver();
+ /*
+ // we don't use it anymore, see above!
+ // Just left it here for the case...
+ if ( isDuplexInput && stream_.bufferSize != *bufferSize ) {
errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
- return FAILURE;
+ goto error;
}
+ */
stream_.bufferSize = *bufferSize;
stream_.nBuffers = 2;
@@ -3022,16 +3094,13 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.deviceInterleaved[mode] = false;
// Allocate, if necessary, our AsioHandle structure for the stream.
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
if ( handle == 0 ) {
try {
handle = new AsioHandle;
}
catch ( std::bad_alloc& ) {
- //if ( handle == NULL ) {
- drivers.removeCurrentDriver();
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
- return FAILURE;
+ goto error;
}
handle->bufferInfos = 0;
@@ -3046,15 +3115,14 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
// Create the ASIO internal buffers. Since RtAudio sets up input
// and output separately, we'll have to dispose of previously
// created output buffers for a duplex stream.
- long inputLatency, outputLatency;
if ( mode == INPUT && stream_.mode == OUTPUT ) {
ASIODisposeBuffers();
if ( handle->bufferInfos ) free( handle->bufferInfos );
}
// Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
- bool buffersAllocated = false;
- unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
+ unsigned int i;
+ nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
if ( handle->bufferInfos == NULL ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
@@ -3075,6 +3143,15 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
infos->buffers[0] = infos->buffers[1] = 0;
}
+ // prepare for callbacks
+ stream_.sampleRate = sampleRate;
+ stream_.device[mode] = device;
+ stream_.mode = isDuplexInput ? DUPLEX : mode;
+
+ // store this class instance before registering callbacks, that are going to use it
+ asioCallbackInfo = &stream_.callbackInfo;
+ stream_.callbackInfo.object = (void *) this;
+
// Set up the ASIO callback structure and create the ASIO data buffers.
asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged;
@@ -3082,11 +3159,21 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
asioCallbacks.bufferSwitchTimeInfo = NULL;
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
if ( result != ASE_OK ) {
+ // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges
+ // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver
+ // in that case, let's be naïve and try that instead
+ *bufferSize = preferSize;
+ stream_.bufferSize = *bufferSize;
+ result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
+ }
+
+ if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
errorText_ = errorStream_.str();
goto error;
}
- buffersAllocated = true;
+ buffersAllocated = true;
+ stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion.
stream_.doConvertBuffer[mode] = false;
@@ -3109,11 +3196,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
bool makeBuffer = true;
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
+ if ( isDuplexInput && stream_.deviceBuffer ) {
+ unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+ if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
if ( makeBuffer ) {
@@ -3127,18 +3212,8 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
}
- stream_.sampleRate = sampleRate;
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
- asioCallbackInfo = &stream_.callbackInfo;
- stream_.callbackInfo.object = (void *) this;
- if ( stream_.mode == OUTPUT && mode == INPUT )
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- else
- stream_.mode = mode;
-
// Determine device latencies
+ long inputLatency, outputLatency;
result = ASIOGetLatencies( &inputLatency, &outputLatency );
if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency.";
@@ -3158,32 +3233,38 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
return SUCCESS;
error:
- if ( buffersAllocated )
- ASIODisposeBuffers();
- drivers.removeCurrentDriver();
+ if ( !isDuplexInput ) {
+ // the cleanup for error in the duplex input, is done by RtApi::openStream
+ // So we clean up for single channel only
- if ( handle ) {
- CloseHandle( handle->condition );
- if ( handle->bufferInfos )
- free( handle->bufferInfos );
- delete handle;
- stream_.apiHandle = 0;
- }
+ if ( buffersAllocated )
+ ASIODisposeBuffers();
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
+ drivers.removeCurrentDriver();
+
+ if ( handle ) {
+ CloseHandle( handle->condition );
+ if ( handle->bufferInfos )
+ free( handle->bufferInfos );
+
+ delete handle;
+ stream_.apiHandle = 0;
}
- }
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
+
+ if ( stream_.userBuffer[mode] ) {
+ free( stream_.userBuffer[mode] );
+ stream_.userBuffer[mode] = 0;
+ }
+
+ if ( stream_.deviceBuffer ) {
+ free( stream_.deviceBuffer );
+ stream_.deviceBuffer = 0;
+ }
}
return FAILURE;
-}
+}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RtApiAsio :: closeStream()
{
@@ -3635,12 +3716,12 @@ public:
outIndex_( 0 ) {}
~WasapiBuffer() {
- delete buffer_;
+ free( buffer_ );
}
// sets the length of the internal ring buffer
void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
- delete buffer_;
+ free( buffer_ );
buffer_ = ( char* ) calloc( bufferSize, formatBytes );
@@ -3799,7 +3880,7 @@ void convertBufferWasapi( char* outBuffer,
float sampleStep = 1.0f / sampleRatio;
float inSampleFraction = 0.0f;
- outSampleCount = ( unsigned int ) ( inSampleCount * sampleRatio );
+ outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio );
// frame-by-frame, copy each relative input sample into it's corresponding output sample
for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )
@@ -3945,7 +4026,6 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
RtAudio::DeviceInfo info;
unsigned int captureDeviceCount = 0;
unsigned int renderDeviceCount = 0;
- std::wstring deviceName;
std::string defaultDeviceName;
bool isCaptureDevice = false;
@@ -4048,8 +4128,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit;
}
- deviceName = defaultDeviceNameProp.pwszVal;
- defaultDeviceName = std::string( deviceName.begin(), deviceName.end() );
+ defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal);
// name
hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
@@ -4066,8 +4145,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit;
}
- deviceName = deviceNameProp.pwszVal;
- info.name = std::string( deviceName.begin(), deviceName.end() );
+ info.name =convertCharPointerToStdString(deviceNameProp.pwszVal);
// is default
if ( isCaptureDevice ) {
@@ -4110,6 +4188,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
}
+ info.preferredSampleRate = deviceFormat->nSamplesPerSec;
// native format
info.nativeFormats = 0;
@@ -5245,14 +5324,11 @@ unsigned int RtApiDs :: getDeviceCount( void )
error( RtAudioError::WARNING );
}
- // Clean out any devices that may have disappeared.
- std::vector< int > indices;
- for ( unsigned int i=0; i<dsDevices.size(); i++ )
- if ( dsDevices[i].found == false ) indices.push_back( i );
- //unsigned int nErased = 0;
- for ( unsigned int i=0; i<indices.size(); i++ )
- dsDevices.erase( dsDevices.begin()+indices[i] );
- //dsDevices.erase( dsDevices.begin()-nErased++ );
+ // Clean out any devices that may have disappeared (code update submitted by Eli Zehngut).
+ for ( unsigned int i=0; i<dsDevices.size(); ) {
+ if ( dsDevices[i].found == false ) dsDevices.erase( dsDevices.begin() + i );
+ else i++;
+ }
return static_cast<unsigned int>(dsDevices.size());
}
@@ -5308,8 +5384,12 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
info.sampleRates.clear();
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate &&
- SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate )
+ SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+ }
}
// Get format information.
@@ -6264,6 +6344,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6271,6 +6352,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6279,6 +6361,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6286,6 +6369,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6307,6 +6391,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6399,6 +6484,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6412,6 +6498,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6448,6 +6535,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6509,6 +6597,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6523,6 +6612,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6544,6 +6634,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6582,21 +6673,6 @@ static unsigned __stdcall callbackHandler( void *ptr )
return 0;
}
-#include "tchar.h"
-
-static std::string convertTChar( LPCTSTR name )
-{
-#if defined( UNICODE ) || defined( _UNICODE )
- int length = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
- std::string s( length-1, '\0' );
- WideCharToMultiByte(CP_UTF8, 0, name, -1, &s[0], length, NULL, NULL);
-#else
- std::string s( name );
-#endif
-
- return s;
-}
-
static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
LPCTSTR description,
LPCTSTR /*module*/,
@@ -6638,7 +6714,7 @@ static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
}
// If good device, then save its name and guid.
- std::string name = convertTChar( description );
+ std::string name = convertCharPointerToStdString( description );
//if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
if ( lpguid == NULL )
name = "Default Device";
@@ -6820,6 +6896,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Count cards and devices
card = -1;
+ subdevice = -1;
snd_card_next( &card );
while ( card >= 0 ) {
sprintf( name, "hw:%d", card );
@@ -7033,8 +7110,12 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Test our discrete set of sample rate values.
info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
- if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 )
+ if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[i];
+ }
}
if ( info.sampleRates.size() == 0 ) {
snd_pcm_close( phandle );
@@ -7959,6 +8040,8 @@ void RtApiAlsa :: callbackEvent()
errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
}
+ else
+ errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun.";
}
else {
errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
@@ -8067,6 +8150,7 @@ RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ )
for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
info.sampleRates.push_back( *sr );
+ info.preferredSampleRate = 48000;
info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
return info;
@@ -8429,7 +8513,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
int error;
- if ( !options->streamName.empty() ) streamName = options->streamName;
+ if ( options && !options->streamName.empty() ) streamName = options->streamName;
switch ( mode ) {
case INPUT:
pa_buffer_attr buffer_attr;
@@ -8635,6 +8719,10 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( ainfo.rates[i] == SAMPLE_RATES[k] ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+
break;
}
}
@@ -8643,8 +8731,12 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
else {
// Check min and max rate values;
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
- if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] )
+ if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+ }
}
}
diff --git a/drivers/rtaudio/RtAudio.h b/drivers/rtaudio/RtAudio.h
index 1f1b63072c..7d45d36529 100644
--- a/drivers/rtaudio/RtAudio.h
+++ b/drivers/rtaudio/RtAudio.h
@@ -310,12 +310,13 @@ class RtAudio
bool isDefaultOutput; /*!< true if this is the default output device. */
bool isDefaultInput; /*!< true if this is the default input device. */
std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
+ unsigned int preferredSampleRate; /*!< Preferred sample rate, eg. for WASAPI the system sample rate. */
RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
// Default constructor.
DeviceInfo()
:probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
- isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
+ isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {}
};
//! The structure for specifying input or ouput stream parameters.
diff --git a/drivers/vorbis/psy.c b/drivers/vorbis/psy.c
index 9a86151cec..29d2824372 100644
--- a/drivers/vorbis/psy.c
+++ b/drivers/vorbis/psy.c
@@ -1160,7 +1160,7 @@ void _vp_couple_quantize_normalize(int blobno,
However, this is a temporary patch.
by Aoyumi @ 2004/04/18
*/
- /*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit)));
+ /*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit))); */
/* elliptical
if(reM[j]+reA[j]<0){
reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index f548beaa38..7c81e8e051 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -191,9 +191,9 @@ Error DirAccessWindows::make_dir(String p_dir) {
#else
- //p_dir=fix_path(p_dir);
+ p_dir=fix_path(p_dir);
- p_dir.replace("/","\\");
+ //p_dir.replace("/","\\");
bool success;
int err;
@@ -250,14 +250,14 @@ bool DirAccessWindows::file_exists(String p_file) {
p_file=fix_path(p_file);
- p_file.replace("/","\\");
+ //p_file.replace("/","\\");
- WIN32_FILE_ATTRIBUTE_DATA fileInfo;
+ //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr;
- fileAttr = GetFileAttributesExW(p_file.c_str(), GetFileExInfoStandard, &fileInfo);
- if (0 == fileAttr)
+ fileAttr = GetFileAttributesW(p_file.c_str());
+ if (INVALID_FILE_ATTRIBUTES == fileAttr)
return false;
return !(fileAttr&FILE_ATTRIBUTE_DIRECTORY);
@@ -273,17 +273,16 @@ bool DirAccessWindows::dir_exists(String p_dir) {
else
p_dir=fix_path(p_dir);
- p_dir.replace("/","\\");
+ //p_dir.replace("/","\\");
- WIN32_FILE_ATTRIBUTE_DATA fileInfo;
+ //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
DWORD fileAttr;
- fileAttr = GetFileAttributesExW(p_dir.c_str(), GetFileExInfoStandard, &fileInfo);
- if (0 == fileAttr)
- return false;
-
+ fileAttr = GetFileAttributesW(p_dir.c_str());
+ if (INVALID_FILE_ATTRIBUTES == fileAttr)
+ return false;
return (fileAttr&FILE_ATTRIBUTE_DIRECTORY);
}
@@ -314,12 +313,15 @@ Error DirAccessWindows::remove(String p_path) {
p_path=fix_path(p_path);
printf("erasing %s\n",p_path.utf8().get_data());
- WIN32_FILE_ATTRIBUTE_DATA fileInfo;
- DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
- if (fileAttr == INVALID_FILE_ATTRIBUTES)
- return FAILED;
+ //WIN32_FILE_ATTRIBUTE_DATA fileInfo;
+ //DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo);
+
+ DWORD fileAttr;
- if (fileAttr & FILE_ATTRIBUTE_DIRECTORY)
+ fileAttr = GetFileAttributesW(p_path.c_str());
+ if (INVALID_FILE_ATTRIBUTES == fileAttr)
+ return FAILED;
+ if ((fileAttr&FILE_ATTRIBUTE_DIRECTORY))
return ::_wrmdir(p_path.c_str())==0?OK:FAILED;
else
return ::_wunlink(p_path.c_str())==0?OK:FAILED;
diff --git a/main/main.cpp b/main/main.cpp
index a822418eaa..1469ce4618 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -251,7 +251,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
packed_data = memnew(PackedData);
#ifdef MINIZIP_ENABLED
+
+ //XXX: always get_singleton() == 0x0
zip_packed_data = ZipArchive::get_singleton();
+ //TODO: remove this temporary fix
+ if (!zip_packed_data) {
+ zip_packed_data = memnew(ZipArchive);
+ }
+
packed_data->add_pack_source(zip_packed_data);
#endif
@@ -748,12 +755,12 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
if (file_access_network_client)
memdelete(file_access_network_client);
- if (packed_data)
- memdelete( packed_data );
-#ifdef MINIZIP_ENABLED
- if (zip_packed_data)
- memdelete( zip_packed_data );
-#endif
+// Note 1: *zip_packed_data live into *packed_data
+// Note 2: PackedData::~PackedData destroy this.
+//#ifdef MINIZIP_ENABLED
+// if (zip_packed_data)
+// memdelete( zip_packed_data );
+//#endif
unregister_core_types();
diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp
index e014921364..37ddb2bc41 100644
--- a/modules/gdscript/gd_functions.cpp
+++ b/modules/gdscript/gd_functions.cpp
@@ -88,6 +88,7 @@ const char *GDFunctions::get_func_name(Function p_func) {
"str",
"print",
"printt",
+ "prints",
"printerr",
"printraw",
"var2str",
@@ -562,6 +563,22 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
} break;
+ case TEXT_PRINT_SPACED: {
+
+ String str;
+ for(int i=0;i<p_arg_count;i++) {
+
+ if (i)
+ str+=" ";
+ str+=p_args[i]->operator String();
+ }
+
+ //str+="\n";
+ print_line(str);
+ r_ret=Variant();
+
+
+ } break;
case TEXT_PRINTERR: {
@@ -1252,6 +1269,13 @@ MethodInfo GDFunctions::get_info(Function p_func) {
return mi;
} break;
+ case TEXT_PRINT_SPACED: {
+
+ MethodInfo mi("prints",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
+ mi.return_val.type=Variant::NIL;
+ return mi;
+
+ } break;
case TEXT_PRINTERR: {
MethodInfo mi("printerr",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h
index ecd7d158be..ad35a628d5 100644
--- a/modules/gdscript/gd_functions.h
+++ b/modules/gdscript/gd_functions.h
@@ -84,6 +84,7 @@ public:
TEXT_STR,
TEXT_PRINT,
TEXT_PRINT_TABBED,
+ TEXT_PRINT_SPACED,
TEXT_PRINTERR,
TEXT_PRINTRAW,
VAR_TO_STR,
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 56b283aa32..0745baafe6 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -1036,7 +1036,7 @@ void GDTokenizerText::advance(int p_amount) {
//////////////////////////////////////////////////////////////////////////////////////////////////////
-#define BYTECODE_VERSION 3
+#define BYTECODE_VERSION 4
Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
diff --git a/platform/android/java/src/com/android/godot/Godot.java b/platform/android/java/src/com/android/godot/Godot.java
index e0ac6b0f12..4f42a1a82b 100644
--- a/platform/android/java/src/com/android/godot/Godot.java
+++ b/platform/android/java/src/com/android/godot/Godot.java
@@ -747,7 +747,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
//}
} break;
case MotionEvent.ACTION_POINTER_UP: {
- int pointer_idx = event.getActionIndex();
+ final int indexPointUp = event.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointer_idx = event.getPointerId(indexPointUp);
GodotLib.touch(4,pointer_idx,evcount,arr);
//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
} break;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index dd19dbbff6..eb2a12cdef 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -966,8 +966,10 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
[NSApp activateIgnoringOtherApps:YES];
- [window_object makeKeyAndOrderFront:nil];
+ [window_object makeKeyAndOrderFront:nil];
+ if (p_desired.fullscreen)
+ zoomed = true;
/*** END OSX INITIALIZATION ***/
/*** END OSX INITIALIZATION ***/
@@ -1310,14 +1312,22 @@ void OS_OSX::set_window_size(const Size2 p_size) {
void OS_OSX::set_window_fullscreen(bool p_enabled) {
- [window_object performZoom:nil];
+ if (zoomed != p_enabled) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+ [window_object toggleFullScreen:nil];
+#else
+ [window_object performZoom:nil];
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
+ }
zoomed = p_enabled;
};
bool OS_OSX::is_window_fullscreen() const {
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
if ( [window_object respondsToSelector:@selector(isZoomed)] )
return [window_object isZoomed];
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
return zoomed;
};
@@ -1509,6 +1519,11 @@ void OS_OSX::run() {
main_loop->init();
+ if (zoomed) {
+ zoomed = false;
+ set_window_fullscreen(true);
+ }
+
// uint64_t last_ticks=get_ticks_usec();
// int frames=0;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 9cdf04797c..298fa3bc78 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -204,7 +204,7 @@ def configure(env):
elif (env["target"]=="debug"):
- env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED','/DD3D_DEBUG_INFO','/O1'])
+ env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED','/DD3D_DEBUG_INFO','/Od'])
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
env.Append(LINKFLAGS=['/DEBUG'])
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 67ec33f3a3..28427fa2f0 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -317,8 +317,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
/* set the name and class hints for the window manager to use */
classHint = XAllocClassHint();
if (classHint) {
- classHint->res_name = "Godot";
- classHint->res_class = "Godot";
+ classHint->res_name = (char *)"Godot";
+ classHint->res_class = (char *)"Godot";
}
XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint);
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 27a512845c..70b88a6611 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -132,8 +132,7 @@ Matrix32 Camera2D::get_camera_transform() {
}
- Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());;
- screen_offset;
+ Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());
float angle = get_global_transform().get_rotation();
if(rotating){
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index fc5be255ce..99c33c787d 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -346,6 +346,17 @@ Matrix32 Node2D::get_relative_transform(const Node *p_parent) const {
return parent_2d->get_relative_transform(p_parent) * get_transform();
}
+
+void Node2D::look_at(const Vector2& p_pos) {
+
+ rotate(get_angle_to(p_pos));
+}
+
+float Node2D::get_angle_to(const Vector2& p_pos) const {
+
+ return (get_global_transform().affine_inverse().xform(p_pos)).atan2();
+}
+
void Node2D::_bind_methods() {
@@ -374,6 +385,9 @@ void Node2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform);
ObjectTypeDB::bind_method(_MD("set_global_transform","xform"),&Node2D::set_global_transform);
+ ObjectTypeDB::bind_method(_MD("look_at","point"),&Node2D::look_at);
+ ObjectTypeDB::bind_method(_MD("get_angle_to","point"),&Node2D::get_angle_to);
+
ObjectTypeDB::bind_method(_MD("set_z","z"),&Node2D::set_z);
ObjectTypeDB::bind_method(_MD("get_z"),&Node2D::get_z);
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index 74612b3c6d..8efce33cda 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -93,6 +93,9 @@ public:
void set_z(int p_z);
int get_z() const;
+ void look_at(const Vector2& p_pos);
+ float get_angle_to(const Vector2& p_pos) const;
+
void set_z_as_relative(bool p_enabled);
bool is_z_relative() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 9fd4a25e7f..3d2917d843 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -68,18 +68,32 @@ float PhysicsBody2D::get_one_way_collision_max_depth() const{
}
+void PhysicsBody2D::_set_layers(uint32_t p_mask) {
+
+ set_layer_mask(p_mask);
+ set_collision_mask(p_mask);
+}
+
+uint32_t PhysicsBody2D::_get_layers() const{
+
+ return get_layer_mask();
+}
+
void PhysicsBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody2D::set_collision_mask);
ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody2D::get_collision_mask);
+ ObjectTypeDB::bind_method(_MD("_set_layers","mask"),&PhysicsBody2D::_set_layers);
+ ObjectTypeDB::bind_method(_MD("_get_layers"),&PhysicsBody2D::_get_layers);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with);
ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with);
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS,"",0),_SCS("_set_layers"),_SCS("_get_layers")); //for backwards compat
ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction"));
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index b6be07500f..03f95959b6 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -42,6 +42,11 @@ class PhysicsBody2D : public CollisionObject2D {
uint32_t collision_mask;
Vector2 one_way_collision_direction;
float one_way_collision_max_depth;
+
+
+ void _set_layers(uint32_t p_mask);
+ uint32_t _get_layers() const;
+
protected:
void _notification(int p_what);
diff --git a/scene/animation/tween_interpolaters.cpp b/scene/animation/tween_interpolaters.cpp
index c052d752f8..9128d220de 100644
--- a/scene/animation/tween_interpolaters.cpp
+++ b/scene/animation/tween_interpolaters.cpp
@@ -285,18 +285,18 @@ namespace cubic {
namespace circ {
static real_t in(real_t t, real_t b, real_t c, real_t d)
{
- return -c * (sqrt(1 - (t /= d) * t) - 1) + b;
+ return -c * (sqrt(1 - (t /= d) * t) - 1) + b; // TODO: ehrich: operation with t is undefined
}
static real_t out(real_t t, real_t b, real_t c, real_t d)
{
- return c * sqrt(1 - (t = t / d - 1) * t) + b;
+ return c * sqrt(1 - (t = t / d - 1) * t) + b; // TODO: ehrich: operation with t is undefined
}
static real_t in_out(real_t t, real_t b, real_t c, real_t d)
{
if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b;
- return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b;
+ return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; // TODO: ehrich: operation with t is undefined
}
static real_t out_in(real_t t, real_t b, real_t c, real_t d)
@@ -364,15 +364,15 @@ namespace back {
static real_t out(real_t t, real_t b, real_t c, real_t d)
{
float s = 1.70158f;
- return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b;
+ return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; // TODO: ehrich: operation with t is undefined
}
static real_t in_out(real_t t, real_t b, real_t c, real_t d)
{
float s = 1.70158f;
- if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b;
+ if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; // TODO: ehrich: operation with s is undefined
float postFix = t -= 2;
- return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b;
+ return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; // TODO: ehrich: operation with s is undefined
}
static real_t out_in(real_t t, real_t b, real_t c, real_t d)
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 57dd29ad07..5b837d699c 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -115,6 +115,8 @@ void Button::_notification(int p_what) {
text_ofs.y+=style->get_offset().y;
} break;
case ALIGN_CENTER: {
+ if (text_ofs.x<0)
+ text_ofs.x=0;
text_ofs+=icon_ofs;
text_ofs+=style->get_offset();
} break;
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 309152ba8f..2aa82bc5f5 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -59,7 +59,7 @@ bool CheckBox::is_radio()
Node* parent = this;
do {
parent = parent->get_parent();
- if (dynamic_cast< ButtonGroup* >(parent))
+ if (parent->cast_to<ButtonGroup>())
break;
} while (parent);
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 1751d335ee..dac21275dc 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -433,7 +433,7 @@ void Label::regenerate_word_cache() {
}
- if ((autowrap && line_width>=width && (last && last->char_pos >= 0 || not_latin)) || insert_newline) {
+ if ((autowrap && (line_width >= width) && ((last && last->char_pos >= 0) || not_latin)) || insert_newline) {
if (not_latin) {
if (current_word_size>0) {
WordCache *wc = memnew( WordCache );
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 14aa3da85f..fec9e401f1 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -272,7 +272,7 @@ void LineEdit::_input_event(InputEvent p_event) {
if (editable) {
selection_delete();
- CharType ucodestr[2]={k.unicode,0};
+ CharType ucodestr[2]={(CharType)k.unicode,0};
append_at_cursor(ucodestr);
emit_signal("text_changed",text);
_change_notify("text");
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 3489b02598..6b2e5aea78 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -235,6 +235,9 @@ if (m_height > line_height) {\
while (c[end]!=0 && !(end && c[end-1]==' ' && c[end]!=' ')) {
int cw = font->get_char_size(c[end],c[end+1]).width;
+ if (c[end]=='\t') {
+ cw=tab_size*font->get_char_size(' ').width;
+ }
w+=cw;
if (c[end]==' ') {
@@ -292,6 +295,9 @@ if (m_height > line_height) {\
int cw=font->get_char_size(c[i],c[i+1]).x;
+ if (c[i]=='\t') {
+ cw=tab_size*font->get_char_size(' ').width;
+ }
if (p_click_pos.x-cw/2>pofs) {
@@ -332,6 +338,10 @@ if (m_height > line_height) {\
cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color);
}
+ if (c[i]=='\t') {
+ cw=tab_size*font->get_char_size(' ').width;
+ }
+
//print_line("draw char: "+String::chr(c[i]));
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 681c33652e..db8fbf7a63 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1440,7 +1440,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else {
//different char, go back
- const CharType chr[2] = {k.unicode, 0};
+ const CharType chr[2] = {(CharType)k.unicode, 0};
if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]);
} else {
@@ -2062,7 +2062,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (readonly)
break;
- const CharType chr[2] = {k.unicode, 0};
+ const CharType chr[2] = {(CharType)k.unicode, 0};
if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index e0181b9238..5c60b9fbff 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1417,6 +1417,41 @@ void Node::_duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_re
}
+
+void Node::_duplicate_signals(const Node* p_original,Node* p_copy) const {
+
+ if (this!=p_original && get_owner()!=p_original)
+ return;
+
+ List<Connection> conns;
+ get_all_signal_connections(&conns);
+
+ for (List<Connection>::Element *E=conns.front();E;E=E->next()) {
+
+ if (E->get().flags&CONNECT_PERSIST) {
+ //user connected
+ NodePath p = p_original->get_path_to(this);
+ Node *copy = p_copy->get_node(p);
+
+ Node *target = E->get().target->cast_to<Node>();
+ if (!target)
+ continue;
+ NodePath ptarget = p_original->get_path_to(target);
+ Node *copytarget = p_copy->get_node(ptarget);
+
+ if (copy && copytarget) {
+ copy->connect(E->get().signal,copytarget,E->get().method,E->get().binds,CONNECT_PERSIST);
+ }
+ }
+ }
+
+ for(int i=0;i<get_child_count();i++) {
+ get_child(i)->_duplicate_signals(p_original,p_copy);
+ }
+
+}
+
+
Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
@@ -1455,6 +1490,7 @@ Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
get_child(i)->_duplicate_and_reown(node,p_reown_map);
}
+ _duplicate_signals(this,node);
return node;
}
diff --git a/scene/main/node.h b/scene/main/node.h
index 4d0a84d347..be32c4e726 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -126,6 +126,7 @@ private:
void _propagate_pause_owner(Node*p_owner);
Array _get_node_and_resource(const NodePath& p_path);
+ void _duplicate_signals(const Node* p_original,Node* p_copy) const;
void _duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_reown_map) const;
Array _get_children() const;
Array _get_groups() const;
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 2e3e7db0ad..3a80382a40 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -45,14 +45,14 @@ void Timer::_notification(int p_what) {
}
} break;
case NOTIFICATION_PROCESS: {
-
- if (!is_processing())
+ if (timer_process_mode == TIMER_PROCESS_FIXED || !is_processing())
return;
time_left -= get_process_delta_time();
if (time_left<0) {
if (!one_shot)
- time_left=wait_time+time_left;
+ //time_left=wait_time+time_left;
+ time_left = wait_time;
else
stop();
@@ -60,13 +60,27 @@ void Timer::_notification(int p_what) {
}
} break;
+ case NOTIFICATION_FIXED_PROCESS: {
+ if (timer_process_mode == TIMER_PROCESS_IDLE || !is_fixed_processing())
+ return;
+ time_left -= get_fixed_process_delta_time();
+
+ if (time_left<0) {
+ if (!one_shot)
+ //time_left = wait_time + time_left;
+ time_left = wait_time;
+ else
+ stop();
+ emit_signal("timeout");
+ }
+
+ } break;
}
}
void Timer::set_wait_time(float p_time) {
-
ERR_EXPLAIN("time should be greater than zero.");
ERR_FAIL_COND(p_time<=0);
wait_time=p_time;
@@ -96,14 +110,13 @@ bool Timer::has_autostart() const {
}
void Timer::start() {
-
time_left=wait_time;
- set_process(true);
+ _set_process(true);
}
void Timer::stop() {
time_left=-1;
- set_process(false);
+ _set_process(false);
autostart=false;
}
@@ -112,6 +125,41 @@ float Timer::get_time_left() const {
return time_left >0 ? time_left : 0;
}
+void Timer::set_timer_process_mode(TimerProcessMode p_mode) {
+
+ if (timer_process_mode == p_mode)
+ return;
+
+ switch (timer_process_mode) {
+ case TIMER_PROCESS_FIXED:
+ if (is_fixed_processing()) {
+ set_fixed_process(false);
+ set_process(true);
+ }
+ break;
+ case TIMER_PROCESS_IDLE:
+ if (is_processing()) {
+ set_process(false);
+ set_fixed_process(true);
+ }
+ break;
+ }
+ timer_process_mode = p_mode;
+}
+
+Timer::TimerProcessMode Timer::get_timer_process_mode() const{
+
+ return timer_process_mode;
+}
+
+
+void Timer::_set_process(bool p_process, bool p_force)
+{
+ switch (timer_process_mode) {
+ case TIMER_PROCESS_FIXED: set_fixed_process(p_process); break;
+ case TIMER_PROCESS_IDLE: set_process(p_process); break;
+ }
+}
void Timer::_bind_methods() {
@@ -129,8 +177,12 @@ void Timer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_time_left"),&Timer::get_time_left);
+ ObjectTypeDB::bind_method(_MD("set_timer_process_mode", "mode"), &Timer::set_timer_process_mode);
+ ObjectTypeDB::bind_method(_MD("get_timer_process_mode"), &Timer::get_timer_process_mode);
+
ADD_SIGNAL( MethodInfo("timeout") );
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_timer_process_mode"), _SCS("get_timer_process_mode"));
ADD_PROPERTY( PropertyInfo(Variant::REAL, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.01,4096,0.01" ), _SCS("set_wait_time"), _SCS("get_wait_time") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "one_shot" ), _SCS("set_one_shot"), _SCS("is_one_shot") );
ADD_PROPERTY( PropertyInfo(Variant::BOOL, "autostart" ), _SCS("set_autostart"), _SCS("has_autostart") );
@@ -138,8 +190,7 @@ void Timer::_bind_methods() {
}
Timer::Timer() {
-
-
+ timer_process_mode = TIMER_PROCESS_IDLE;
autostart=false;
wait_time=1;
one_shot=false;
diff --git a/scene/main/timer.h b/scene/main/timer.h
index 021638ccfc..4b9cecba84 100644
--- a/scene/main/timer.h
+++ b/scene/main/timer.h
@@ -46,6 +46,11 @@ protected:
static void _bind_methods();
public:
+ enum TimerProcessMode {
+ TIMER_PROCESS_FIXED,
+ TIMER_PROCESS_IDLE,
+ };
+
void set_wait_time(float p_time);
float get_wait_time() const;
@@ -60,7 +65,16 @@ public:
float get_time_left() const;
+ void set_timer_process_mode(TimerProcessMode p_mode);
+ TimerProcessMode get_timer_process_mode() const;
Timer();
+
+private:
+ TimerProcessMode timer_process_mode;
+ void _set_process(bool p_process, bool p_force = false);
+
};
+VARIANT_ENUM_CAST(Timer::TimerProcessMode);
+
#endif // TIMER_H
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 4d9feb3af1..3bb64e54c6 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1177,6 +1177,11 @@ void Viewport::_vp_unhandled_input(const InputEvent& p_ev) {
}
+Vector2 Viewport::get_mouse_pos() const {
+
+ return (get_final_transform().affine_inverse() * _get_input_pre_xform()).xform(Input::get_singleton()->get_mouse_pos());
+}
+
void Viewport::warp_mouse(const Vector2& p_pos) {
Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos);
@@ -1377,6 +1382,7 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_audio_listener_2d","enable"), &Viewport::is_audio_listener_2d);
ObjectTypeDB::bind_method(_MD("set_render_target_to_screen_rect"), &Viewport::set_render_target_to_screen_rect);
+ ObjectTypeDB::bind_method(_MD("get_mouse_pos"), &Viewport::get_mouse_pos);
ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"), &Viewport::warp_mouse);
ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") );
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index fba6725610..c3c339ac5d 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -252,6 +252,7 @@ public:
void set_render_target_to_screen_rect(const Rect2& p_rect);
Rect2 get_render_target_to_screen_rect() const;
+ Vector2 get_mouse_pos() const;
void warp_mouse(const Vector2& p_pos);
void set_physics_object_picking(bool p_enable);
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index 70fc3e8fcb..c018ab6224 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -34,8 +34,10 @@
#include "self_list.h"
#include "broad_phase_sw.h"
-#define MAX_OBJECT_DISTANCE 10000000
+#ifdef DEBUG_ENABLED
+#define MAX_OBJECT_DISTANCE 10000000.0
#define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE*MAX_OBJECT_DISTANCE)
+#endif
class SpaceSW;
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 2b4a137e11..03d5b7afa1 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -551,7 +551,7 @@ bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx)
ERR_FAIL_COND_V(!body,false);
ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false);
- body->is_shape_set_as_trigger(p_shape_idx);
+ return body->is_shape_set_as_trigger(p_shape_idx);
}
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index e8d37d346a..6bfed134e6 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -265,7 +265,7 @@ bool BodyPair2DSW::setup(float p_step) {
}
//faster to set than to check..
- bool prev_collided=collided;
+ //bool prev_collided=collided;
collided = CollisionSolver2DSW::solve(shape_A_ptr,xform_A,motion_A,shape_B_ptr,xform_B,motion_B,_add_contact,this,&sep_axis);
if (!collided) {
@@ -282,12 +282,18 @@ bool BodyPair2DSW::setup(float p_step) {
collided=true;
}
- if (!collided)
+ if (!collided) {
+ oneway_disabled=false;
return false;
+ }
}
- if (!prev_collided) {
+ if (oneway_disabled)
+ return false;
+
+ //if (!prev_collided) {
+ {
if (A->is_using_one_way_collision()) {
Vector2 direction = A->get_one_way_collision_direction();
@@ -309,6 +315,7 @@ bool BodyPair2DSW::setup(float p_step) {
if (!valid) {
collided=false;
+ oneway_disabled=true;
return false;
}
}
@@ -333,6 +340,7 @@ bool BodyPair2DSW::setup(float p_step) {
}
if (!valid) {
collided=false;
+ oneway_disabled=true;
return false;
}
}
@@ -525,6 +533,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A,Body2DSW *p_B, int p_sha
B->add_constraint(this,1);
contact_count=0;
collided=false;
+ oneway_disabled=false;
}
diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/body_pair_2d_sw.h
index 2365512036..a7fa287be4 100644
--- a/servers/physics_2d/body_pair_2d_sw.h
+++ b/servers/physics_2d/body_pair_2d_sw.h
@@ -76,6 +76,7 @@ class BodyPair2DSW : public Constraint2DSW {
Contact contacts[MAX_CONTACTS];
int contact_count;
bool collided;
+ bool oneway_disabled;
int cc;
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index b38cf0c2df..9b69ab299d 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -655,7 +655,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
- cbk.valid_dir=body->get_one_way_collision_direction();
+
+ Vector2 cdir = body->get_one_way_collision_direction();
+ if (cdir!=Vector2() && p_motion.dot(cdir)<0)
+ continue;
+
+ cbk.valid_dir=cdir;
cbk.valid_depth=body->get_one_way_collision_max_depth();
} else {
cbk.valid_dir=Vector2();
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 81862fb3a6..79365f7db6 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -863,17 +863,17 @@ public:
if (polygon->indices != NULL) {
r.pos=polygon->points[polygon->indices[0]];
- for (int i=1; i<polygon->count; i++) {
+ for (int i=1; i<l; i++) {
r.expand_to(polygon->points[polygon->indices[i]]);
- };
+ }
} else {
r.pos=polygon->points[0];
- for (int i=1; i<polygon->count; i++) {
+ for (int i=1; i<l; i++) {
r.expand_to(polygon->points[i]);
- };
- };
+ }
+ }
} break;
case CanvasItem::Command::TYPE_CIRCLE: {
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 6556f8bc42..a547da9b61 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -7281,7 +7281,7 @@ void VisualServerRaster::_draw_viewports() {
if (r.size.width==0)
r.size.width=window_w;
if (r.size.height==0)
- r.size.height=window_w;
+ r.size.height=window_h;
_draw_viewport(vp,r.pos.x,r.pos.y,r.size.width,r.size.height);
diff --git a/tools/docdump/doc_dump.cpp b/tools/docdump/doc_dump.cpp
index d10f6c9ce3..17aff3dc74 100644
--- a/tools/docdump/doc_dump.cpp
+++ b/tools/docdump/doc_dump.cpp
@@ -65,7 +65,7 @@ static String _escape_string(const String& p_str) {
ret=ret.replace(">","&lt;");
ret=ret.replace("'","&apos;");
ret=ret.replace("\"","&quot;");
- for (int i=1;i<32;i++) {
+ for (char i=1;i<32;i++) {
char chr[2]={i,0};
ret=ret.replace(chr,"&#"+String::num(i)+";");
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index 39eec4e69b..63ab186a38 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -1375,7 +1375,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
if (p_input.is_action("ui_up"))
selected_track--;
if (v_scroll->is_visible() && p_input.is_action("ui_page_up"))
- selected_track--;;
+ selected_track--;
if (selected_track<0)
selected_track=0;
diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp
index 94e887c3e7..8e96123c36 100644
--- a/tools/editor/editor_file_system.cpp
+++ b/tools/editor/editor_file_system.cpp
@@ -940,19 +940,19 @@ String EditorFileSystem::get_file_type(const String& p_file) const {
EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) {
if (!filesystem || scanning)
- return false;
+ return NULL;
String f = Globals::get_singleton()->localize_path(p_path);
if (!f.begins_with("res://"))
- return false;
+ return NULL;
f=f.substr(6,f.length());
f=f.replace("\\","/");
if (f==String())
- return filesystem;
+ return filesystem;
if (f.ends_with("/"))
f=f.substr(0,f.length()-1);
@@ -960,7 +960,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) {
Vector<String> path = f.split("/");
if (path.size()==0)
- return false;
+ return NULL;
EditorFileSystemDirectory *fs=filesystem;
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index a6625d7204..5e5d2a5409 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -2122,7 +2122,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
}
editor_data.get_undo_redo().clear_history();
- if (editor_plugin_screen) { //reload editor plugin
+ if (editor_plugin_over) { //reload editor plugin
editor_plugin_over->edit(NULL);
editor_plugin_over->edit(current);
}
diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
index 64b5d5b337..3add30d81e 100644
--- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -51,6 +51,7 @@ static const char *flag_names[]={
NULL
};
+#if 0 // not used
static const char *flag_short_names[]={
"Stream",
"FixBorder",
@@ -65,6 +66,7 @@ static const char *flag_short_names[]={
"Anisoropic",
NULL
};
+#endif
void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) {
diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp
index 1db901e56b..03fcbffa24 100644
--- a/tools/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp
@@ -539,7 +539,6 @@ void GraphCurveMapEdit::_plot_curve(const Vector2& p_a,const Vector2& p_b,const
if ((lastx != newx) || (lasty != newy))
{
#if 0
- /*
if(fix255)
{
/* use fixed array size (for the curve graph) */
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index 4dae60399b..0b3f3e0626 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -3172,11 +3172,11 @@ void SpatialEditor::_init_indicators() {
int arrow_sides=6;
- for(int i = 0; i < 7 ; i++) {
+ for(int k = 0; k < 7 ; k++) {
- Matrix3 ma(ivec,Math_PI*2*float(i)/arrow_sides);
- Matrix3 mb(ivec,Math_PI*2*float(i+1)/arrow_sides);
+ Matrix3 ma(ivec,Math_PI*2*float(k)/arrow_sides);
+ Matrix3 mb(ivec,Math_PI*2*float(k+1)/arrow_sides);
for(int j=0;j<arrow_points-1;j++) {
@@ -3372,6 +3372,7 @@ void SpatialEditor::_notification(int p_what) {
tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon( get_icon("ToolRotate","EditorIcons") );
tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon( get_icon("ToolScale","EditorIcons") );
instance_button->set_icon( get_icon("SpatialAdd","EditorIcons") );
+ instance_button->hide();
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT),get_icon("Panels1","EditorIcons"));
diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp
index c54e036a85..00956919b7 100644
--- a/tools/editor/project_manager.cpp
+++ b/tools/editor/project_manager.cpp
@@ -940,7 +940,7 @@ ProjectManager::ProjectManager() {
String cp;
cp.push_back(0xA9);
cp.push_back(0);
- l->set_text(cp+" 2008-2014 Juan Linietsky, Ariel Manzur.");
+ l->set_text(cp+" 2008-2015 Juan Linietsky, Ariel Manzur.");
l->set_align(Label::ALIGN_CENTER);
vb->add_child(l);
diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp
index 85adbd3a3b..08a1191f41 100644
--- a/tools/editor/project_settings.cpp
+++ b/tools/editor/project_settings.cpp
@@ -916,8 +916,8 @@ void ProjectSettings::_translation_res_option_changed() {
ERR_FAIL_COND(!remaps.has(key));
- StringArray r = remaps[key];
- ERR_FAIL_INDEX(idx,remaps.size());
+ StringArray r = remaps[key];
+ ERR_FAIL_INDEX(idx,r.size());
r.set(idx,path+":"+langs[which]);
remaps[key]=r;
@@ -1095,6 +1095,7 @@ void ProjectSettings::_update_translations() {
t2->set_editable(1,true);
t2->set_metadata(1,path);
int idx = langs.find(locale);
+ print_line("find "+locale+" at "+itos(idx));
if (idx<0)
idx=0;
diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp
index f9d92c8d81..521a10bbd0 100644
--- a/tools/editor/spatial_editor_gizmos.cpp
+++ b/tools/editor/spatial_editor_gizmos.cpp
@@ -1257,7 +1257,8 @@ void SkeletonSpatialGizmo::redraw() {
//find closest axis
int closest=-1;
- float closest_d;
+ float closest_d = 0.0;
+
for(int j=0;j<3;j++) {
float dp = Math::abs(grests[parent].basis[j].normalized().dot(d));
if (j==0 || dp>closest_d)
diff --git a/tools/pck/pck_packer.cpp b/tools/pck/pck_packer.cpp
index 09611b3a93..d398fefb5f 100644
--- a/tools/pck/pck_packer.cpp
+++ b/tools/pck/pck_packer.cpp
@@ -136,7 +136,7 @@ Error PCKPacker::flush(bool p_verbose) {
count += 1;
if (p_verbose) {
if (count % 100 == 0) {
- printf("%i/%i (%.2f\%)\r", count, files.size(), float(count) / files.size() * 100);
+ printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100);
fflush(stdout);
};
};