瀏覽代碼

Merge remote-tracking branch 'upstream/master'

Kostadin Damyanov 10 年之前
父節點
當前提交
c5f574b914
共有 100 個文件被更改,包括 1824 次插入304 次删除
  1. 3 3
      SConstruct
  2. 1 0
      core/error_list.h
  3. 9 9
      core/error_macros.h
  4. 1 0
      core/global_constants.cpp
  5. 1 2
      core/globals.cpp
  6. 2 2
      core/io/compression.cpp
  7. 9 2
      core/io/image_loader.cpp
  8. 0 1
      core/io/ioapi.h
  9. 313 23
      core/io/resource_format_binary.cpp
  10. 9 5
      core/io/resource_format_binary.h
  11. 269 53
      core/io/resource_format_xml.cpp
  12. 18 7
      core/io/resource_format_xml.h
  13. 54 11
      core/io/resource_loader.cpp
  14. 16 6
      core/io/resource_loader.h
  15. 1 1
      core/io/resource_saver.h
  16. 8 1
      core/io/translation_loader_po.cpp
  17. 1 1
      core/io/translation_loader_po.h
  18. 2 0
      core/io/zip.h
  19. 1 0
      core/io/zip_io.h
  20. 19 0
      core/object_type_db.cpp
  21. 3 1
      core/object_type_db.h
  22. 43 0
      core/os/input.cpp
  23. 7 0
      core/os/input.h
  24. 2 2
      core/os/os.cpp
  25. 1 1
      core/os/os.h
  26. 2 2
      core/typedefs.h
  27. 31 0
      core/ustring.cpp
  28. 1 0
      core/ustring.h
  29. 10 2
      core/variant.cpp
  30. 6 3
      demos/2d/platformer/engine.cfg
  31. 12 1
      drivers/chibi/event_stream_chibi.cpp
  32. 1 1
      drivers/chibi/event_stream_chibi.h
  33. 9 1
      drivers/dds/texture_loader_dds.cpp
  34. 1 1
      drivers/dds/texture_loader_dds.h
  35. 11 11
      drivers/gles2/shader_compiler_gles2.cpp
  36. 3 2
      drivers/mpc/audio_stream_mpc.cpp
  37. 1 1
      drivers/mpc/audio_stream_mpc.h
  38. 8 1
      drivers/pvr/texture_loader_pvr.cpp
  39. 1 1
      drivers/pvr/texture_loader_pvr.h
  40. 4 1
      drivers/speex/audio_stream_speex.cpp
  41. 1 1
      drivers/speex/audio_stream_speex.h
  42. 1 1
      drivers/theora/video_stream_theora.h
  43. 1 1
      drivers/theoraplayer/src/YUV/libyuv/src/cpu_id.cc
  44. 3 1
      drivers/theoraplayer/video_stream_theoraplayer.cpp
  45. 1 1
      drivers/theoraplayer/video_stream_theoraplayer.h
  46. 3 1
      drivers/vorbis/audio_stream_ogg_vorbis.cpp
  47. 1 1
      drivers/vorbis/audio_stream_ogg_vorbis.h
  48. 74 11
      main/main.cpp
  49. 53 1
      modules/gdscript/gd_editor.cpp
  50. 79 13
      modules/gdscript/gd_parser.cpp
  51. 2 0
      modules/gdscript/gd_parser.h
  52. 6 1
      modules/gdscript/gd_script.cpp
  53. 1 1
      modules/gdscript/gd_script.h
  54. 1 2
      platform/android/detect.py
  55. 5 6
      platform/android/file_access_android.cpp
  56. 5 5
      platform/android/file_access_android.h
  57. 3 1
      platform/android/file_access_jandroid.cpp
  58. 1 1
      platform/android/java/src/com/android/godot/Godot.java
  59. 3 2
      platform/android/java/src/com/android/godot/GodotIO.java
  60. 1 1
      platform/android/java/src/com/android/godot/GodotLib.java
  61. 10 2
      platform/android/java_glue.cpp
  62. 1 1
      platform/android/java_glue.h
  63. 9 1
      platform/android/os_android.cpp
  64. 3 0
      platform/android/os_android.h
  65. 43 2
      platform/iphone/app_delegate.mm
  66. 2 2
      platform/iphone/detect.py
  67. 1 1
      platform/iphone/gl_view.h
  68. 9 0
      platform/iphone/in_app_store.mm
  69. 29 8
      platform/osx/detect.py
  70. 1 1
      platform/osx/os_osx.h
  71. 1 1
      platform/osx/os_osx.mm
  72. 3 1
      platform/x11/detect.py
  73. 65 4
      platform/x11/os_x11.cpp
  74. 1 0
      platform/x11/os_x11.h
  75. 2 2
      scene/2d/sprite.cpp
  76. 24 9
      scene/3d/area.cpp
  77. 7 3
      scene/3d/area.h
  78. 55 0
      scene/3d/physics_body.cpp
  79. 14 0
      scene/3d/physics_body.h
  80. 2 2
      scene/3d/sprite_3d.cpp
  81. 1 1
      scene/gui/dialogs.cpp
  82. 25 12
      scene/gui/item_list.cpp
  83. 2 0
      scene/gui/item_list.h
  84. 1 1
      scene/gui/menu_button.cpp
  85. 132 0
      scene/gui/patch_9_frame.cpp
  86. 40 0
      scene/gui/patch_9_frame.h
  87. 53 1
      scene/gui/spin_box.cpp
  88. 12 0
      scene/gui/spin_box.h
  89. 85 28
      scene/gui/tree.cpp
  90. 11 0
      scene/gui/tree.h
  91. 11 2
      scene/io/resource_format_image.cpp
  92. 1 1
      scene/io/resource_format_image.h
  93. 9 1
      scene/io/resource_format_wav.cpp
  94. 1 1
      scene/io/resource_format_wav.h
  95. 2 0
      scene/register_scene_types.cpp
  96. 6 1
      scene/resources/bit_mask.cpp
  97. 1 1
      scene/resources/bit_mask.h
  98. 1 1
      scene/resources/default_theme/default_theme.cpp
  99. 8 1
      scene/resources/shader.cpp
  100. 1 1
      scene/resources/shader.h

+ 3 - 3
SConstruct

@@ -220,14 +220,14 @@ if selected_platform in platform_list:
 
 	env.Append(LINKFLAGS=string.split(str(LINKFLAGS)))
 
-	detect.configure(env)
-
-
 	flag_list = platform_flags[selected_platform]
 	for f in flag_list:
 		if not (f[0] in ARGUMENTS): # allow command line to override platform flags
 			env[f[0]] = f[1]
 
+	#must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
+	detect.configure(env)
+
         #env['platform_libsuffix'] = env['LIBSUFFIX']
 
 	suffix="."+selected_platform

+ 1 - 0
core/error_list.h

@@ -54,6 +54,7 @@ enum Error {
 	ERR_FILE_CANT_READ,
 	ERR_FILE_UNRECOGNIZED, // (15)
 	ERR_FILE_CORRUPT,
+	ERR_FILE_MISSING_DEPENDENCIES,
 	ERR_FILE_EOF,
 	ERR_CANT_OPEN, ///< Can't open a resource/socket/file
 	ERR_CANT_CREATE,

+ 9 - 9
core/error_macros.h

@@ -104,7 +104,7 @@ extern bool _err_error_exists;
 
 #define ERR_FAIL_INDEX(m_index,m_size) \
 	 do {if ((m_index)<0 || (m_index)>=(m_size)) { \
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index "_STR(m_index)" out of size ("_STR(m_size)").");	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)").");	\
 		return;	\
 	} else _err_error_exists=false; } while(0);	\
 
@@ -115,7 +115,7 @@ extern bool _err_error_exists;
 
 #define ERR_FAIL_INDEX_V(m_index,m_size,m_retval) \
 	 do {if ((m_index)<0 || (m_index)>=(m_size)) { \
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index "_STR(m_index)" out of size ("_STR(m_size)").");	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Index " _STR(m_index)" out of size (" _STR(m_size)").");	\
 		return m_retval;	 \
 	} else _err_error_exists=false;} while (0);
 
@@ -125,14 +125,14 @@ extern bool _err_error_exists;
 
  #define ERR_FAIL_NULL(m_param) \
 	 { if ( !m_param ) {	\
-		 _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' "_STR(m_param)" ' is null.");	\
+         _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null.");	\
 		 return;	 \
 	 }else _err_error_exists=false; }	\
 
 
 #define ERR_FAIL_NULL_V(m_param,m_retval) \
 	{ if ( !m_param ) {	\
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' "_STR(m_param)" ' is null.");	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Parameter ' " _STR(m_param)" ' is null.");	\
 		return m_retval;	 \
 	}else _err_error_exists=false; }	\
 
@@ -142,7 +142,7 @@ extern bool _err_error_exists;
 
 #define ERR_FAIL_COND(m_cond) \
 	{ if ( m_cond ) {	\
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true.");	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true.");	\
 		return;	 \
 	}else _err_error_exists=false; }	\
 
@@ -154,7 +154,7 @@ extern bool _err_error_exists;
 
 #define ERR_FAIL_COND_V(m_cond,m_retval) \
 	{ if ( m_cond ) {	\
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true. returned: "_STR(m_retval));	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. returned: " _STR(m_retval));	\
 		return m_retval;	 \
 	}else _err_error_exists=false; }	\
 
@@ -164,7 +164,7 @@ extern bool _err_error_exists;
 
 #define ERR_CONTINUE(m_cond) \
 	{ if ( m_cond ) {	\
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true. Continuing..:");	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Continuing..:");	\
 		continue;\
 	} else _err_error_exists=false;}	\
 
@@ -174,7 +174,7 @@ extern bool _err_error_exists;
 
 #define ERR_BREAK(m_cond) \
 	{ if ( m_cond ) {	\
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' "_STR(m_cond)" ' is true. Breaking..:");	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Condition ' " _STR(m_cond)" ' is true. Breaking..:");	\
 		break;\
 	} else _err_error_exists=false;}	\
 
@@ -193,7 +193,7 @@ extern bool _err_error_exists;
 
 #define ERR_FAIL_V(m_value) \
 { \
-		_err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: "__STR(m_value));	\
+        _err_print_error(FUNCTION_STR,__FILE__,__LINE__,"Method/Function Failed, returning: " __STR(m_value));	\
 		_err_error_exists=false;	\
 		return m_value;\
 } \

+ 1 - 0
core/global_constants.cpp

@@ -422,6 +422,7 @@ static _GlobalConstant _global_constants[]={
 	BIND_GLOBAL_CONSTANT( ERR_FILE_CANT_READ ),
 	BIND_GLOBAL_CONSTANT( ERR_FILE_UNRECOGNIZED ),
 	BIND_GLOBAL_CONSTANT( ERR_FILE_CORRUPT ),
+	BIND_GLOBAL_CONSTANT( ERR_FILE_MISSING_DEPENDENCIES),
 	BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
 	BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
 	BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),

+ 1 - 2
core/globals.cpp

@@ -54,7 +54,7 @@ String Globals::localize_path(const String& p_path) const {
 	if (resource_path=="")
 		return p_path; //not initialied yet
 
-	if (p_path.begins_with("res://"))
+	if (p_path.find(":/") != -1)
 		return p_path.simplify_path();
 
 
@@ -1477,7 +1477,6 @@ Globals::Globals() {
 	custom_prop_info["render/mipmap_policy"]=PropertyInfo(Variant::INT,"render/mipmap_policy",PROPERTY_HINT_ENUM,"Allow,Allow For Po2,Disallow");
 	custom_prop_info["render/thread_model"]=PropertyInfo(Variant::INT,"render/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
 	custom_prop_info["physics_2d/thread_model"]=PropertyInfo(Variant::INT,"physics_2d/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
-	set("display/emulate_touchscreen",false);
 
 	using_datapack=false;
 }

+ 2 - 2
core/io/compression.cpp

@@ -26,12 +26,12 @@
 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
+#include "zlib.h"
+#include "os/copymem.h"
 #include "compression.h"
 
 #include "fastlz.h"
-#include "zlib.h"
 #include "zip_io.h"
-#include "os/copymem.h"
 
 int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode) {
 

+ 9 - 2
core/io/image_loader.cpp

@@ -50,8 +50,10 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
 	if (!f) {
 		Error err;
 		f=FileAccess::open(p_file,FileAccess::READ,&err);
-		if (!f)
+		if (!f) {
+			print_line("ERROR OPENING FILE: "+p_file);
 			return err;
+		}
 	}
 				
 	String extension = p_file.extension();
@@ -62,15 +64,20 @@ Error ImageLoader::load_image(String p_file,Image *p_image, FileAccess *p_custom
 		if (!loader[i]->recognize(extension))
 			continue;
 		Error err = loader[i]->load_image(p_image,f);
+
 		if (err!=ERR_FILE_UNRECOGNIZED) {
+
+
 			if (!p_custom)
 				memdelete(f);
+
 			return err;
 		}
 			
 		
 	}
-	
+	print_line("NO LOADER?");
+
 	if (!p_custom)
 		memdelete(f);	
 		

+ 0 - 1
core/io/ioapi.h

@@ -40,7 +40,6 @@
 #endif
 
 #include <stdio.h>
-#include <stdlib.h>
 #include "zlib.h"
 
 #if defined(USE_FILE32API)

+ 313 - 23
core/io/resource_format_binary.cpp

@@ -31,6 +31,7 @@
 #include "globals.h"
 #include "io/file_access_compressed.h"
 #include "io/marshalls.h"
+#include "os/dir_access.h"
 //#define print_bl(m_what) print_line(m_what)
 #define print_bl(m_what)
 
@@ -99,7 +100,9 @@ enum {
 	OBJECT_EMPTY=0,
 	OBJECT_EXTERNAL_RESOURCE=1,
 	OBJECT_INTERNAL_RESOURCE=2,
-	FORMAT_VERSION=0
+	OBJECT_EXTERNAL_RESOURCE_INDEX=3,
+	FORMAT_VERSION=1,
+	FORMAT_VERSION_CAN_RENAME_DEPS=1
 
 
 };
@@ -375,7 +378,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v)  {
 				} break;
 				case OBJECT_INTERNAL_RESOURCE: {
 					uint32_t index=f->get_32();
-					String path = res_path+"::"+itos(index);
+					String path = res_path+"::"+itos(index);					
 					RES res = ResourceLoader::load(path);
 					if (res.is_null()) {
 						WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
@@ -384,6 +387,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v)  {
 
 				} break;
 				case OBJECT_EXTERNAL_RESOURCE: {
+					//old file format, still around for compatibility
 
 					String type = get_unicode_string();
 					String path = get_unicode_string();
@@ -394,6 +398,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v)  {
 
 					}
 
+					if (remaps.find(path)) {
+						path=remaps[path];
+					}
+
 					RES res=ResourceLoader::load(path,type);
 
 					if (res.is_null()) {
@@ -401,6 +409,34 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v)  {
 					}
 					r_v=res;
 
+				} break;
+				case OBJECT_EXTERNAL_RESOURCE_INDEX: {
+					//new file format, just refers to an index in the external list
+					uint32_t erindex = f->get_32();
+
+					if (erindex>=external_resources.size()) {
+						WARN_PRINT("Broken external resource! (index out of size");
+						r_v=Variant();
+					} else {
+
+						String type = external_resources[erindex].type;
+						String path = external_resources[erindex].path;
+
+						if (path.find("://")==-1 && path.is_rel_path()) {
+							// path is relative to file being loaded, so convert to a resource path
+							path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
+
+						}
+
+						RES res=ResourceLoader::load(path,type);
+
+						if (res.is_null()) {
+							WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
+						}
+						r_v=res;
+					}
+
+
 				} break;
 				default: {
 
@@ -628,17 +664,20 @@ Error ResourceInteractiveLoaderBinary::poll(){
 
 	if (s<external_resources.size()) {
 
-		RES res = ResourceLoader::load(external_resources[s].path,external_resources[s].type);
+		String path = external_resources[s].path;
+		if (remaps.has(path)) {
+			path=remaps[path];
+		}
+		RES res = ResourceLoader::load(path,external_resources[s].type);
 		if (res.is_null()) {
 
 			if (!ResourceLoader::get_abort_on_missing_resources()) {
 
-				ResourceLoader::notify_load_error("Resource Not Found: "+external_resources[s].path);
+				ResourceLoader::notify_dependency_error(local_path,path,external_resources[s].type);
 			} else {
 
-
-				error=ERR_FILE_CORRUPT;
-				ERR_EXPLAIN("Can't load dependency: "+external_resources[s].path);
+				error=ERR_FILE_MISSING_DEPENDENCIES;
+				ERR_EXPLAIN("Can't load dependency: "+path);
 				ERR_FAIL_V(error);
 			}
 
@@ -787,6 +826,27 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const {
 	return external_resources.size()+internal_resources.size();
 }
 
+
+static void save_ustring(FileAccess* f,const String& p_string) {
+
+
+	CharString utf8 = p_string.utf8();
+	f->store_32(utf8.length()+1);
+	f->store_buffer((const uint8_t*)utf8.get_data(),utf8.length()+1);
+}
+
+
+static String get_ustring(FileAccess *f) {
+
+	int len = f->get_32();
+	Vector<char> str_buf;
+	str_buf.resize(len);
+	f->get_buffer((uint8_t*)&str_buf[0],len);
+	String s;
+	s.parse_utf8(&str_buf[0]);
+	return s;
+}
+
 String ResourceInteractiveLoaderBinary::get_unicode_string() {
 
 	int len = f->get_32();
@@ -801,7 +861,7 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
 
 
 
-void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies) {
+void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies,bool p_add_types) {
 
 	open(p_f);
 	if (error)
@@ -814,6 +874,10 @@ void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<Stri
 			dep=ResourceLoader::guess_full_filename(dep,external_resources[i].type);
 		}
 
+		if (p_add_types && external_resources[i].type!=String()) {
+			dep+="::"+external_resources[i].type;
+		}
+
 		p_dependencies->push_back(dep);
 	}
 
@@ -866,7 +930,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
 	print_bl("minor: "+itos(ver_minor));
 	print_bl("format: "+itos(ver_format));
 
-	if (ver_format<FORMAT_VERSION ||  ver_major>VERSION_MAJOR) {
+	if (ver_format>FORMAT_VERSION ||  ver_major>VERSION_MAJOR) {
 
 		f->close();
 		ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path);
@@ -903,6 +967,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
 	}
 
 	//see if the exporter has different set of external resources for more efficient loading
+	/*
 	String preload_depts = "deps/"+res_path.md5_text();
 	if (Globals::get_singleton()->has(preload_depts)) {
 		external_resources.clear();
@@ -913,7 +978,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
 			external_resources[i].path=depts.get_name(i);
 		}
 		print_line(res_path+" - EXTERNAL RESOURCES: "+itos(external_resources.size()));
-	}
+	}*/
 
 	print_bl("ext resources: "+itos(ext_resources_size));
 	uint32_t int_resources_size=f->get_32();
@@ -973,7 +1038,7 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
 	uint32_t ver_minor=f->get_32();
 	uint32_t ver_format=f->get_32();
 
-	if (ver_format<FORMAT_VERSION ||  ver_major>VERSION_MAJOR) {
+	if (ver_format>FORMAT_VERSION ||  ver_major>VERSION_MAJOR) {
 
 		f->close();
 		return "";
@@ -1000,8 +1065,10 @@ ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
 }
 
 
-Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path) {
+Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, Error *r_error) {
 
+	if (r_error)
+		*r_error=ERR_FILE_CANT_OPEN;
 
 	Error err;
 	FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@@ -1114,7 +1181,7 @@ Error ResourceFormatLoaderBinary::load_import_metadata(const String &p_path, Ref
 }
 
 
-void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies) {
+void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
 
 	FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
 	ERR_FAIL_COND(!f);
@@ -1123,7 +1190,217 @@ void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<Stri
 	ria->local_path=Globals::get_singleton()->localize_path(p_path);
 	ria->res_path=ria->local_path;
 //	ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
-	ria->get_dependencies(f,p_dependencies);
+	ria->get_dependencies(f,p_dependencies,p_add_types);
+}
+
+Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
+
+
+//	Error error=OK;
+
+
+	FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
+	ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);
+
+	FileAccess* fw=NULL;//=FileAccess::open(p_path+".depren");
+
+	String local_path=p_path.get_base_dir();
+
+	uint8_t header[4];
+	f->get_buffer(header,4);
+	if (header[0]=='R' && header[1]=='S' && header[2]=='C' && header[3]=='C') {
+		//compressed
+		FileAccessCompressed *fac = memnew( FileAccessCompressed );
+		fac->open_after_magic(f);
+		f=fac;
+
+		FileAccessCompressed *facw = memnew( FileAccessCompressed );
+		facw->configure("RSCC");
+		Error err = facw->_open(p_path+".depren",FileAccess::WRITE);
+		if (err) {
+			memdelete(fac);
+			memdelete(facw);
+			ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
+		}
+
+		fw=facw;
+
+
+	} else if (header[0]!='R' || header[1]!='S' || header[2]!='R' || header[3]!='C') {
+		//not normal
+
+		//error=ERR_FILE_UNRECOGNIZED;
+		memdelete(f);
+		ERR_EXPLAIN("Unrecognized binary resource file: "+local_path);
+		ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
+	} else {
+		fw = FileAccess::open(p_path+".depren",FileAccess::WRITE);
+		if (!fw) {
+			memdelete(f);
+		}
+		ERR_FAIL_COND_V(!fw,ERR_CANT_CREATE);
+	}
+
+	bool big_endian = f->get_32();
+#ifdef BIG_ENDIAN_ENABLED
+	endian_swap = !big_endian;
+#else
+	bool endian_swap = big_endian;
+#endif
+
+	bool use_real64 = f->get_32();
+
+	f->set_endian_swap(big_endian!=0); //read big endian if saved as big endian
+	fw->store_32(endian_swap);
+	fw->set_endian_swap(big_endian!=0);
+	fw->store_32(use_real64); //use real64
+
+	uint32_t ver_major=f->get_32();
+	uint32_t ver_minor=f->get_32();
+	uint32_t ver_format=f->get_32();
+
+	if (ver_format<FORMAT_VERSION_CAN_RENAME_DEPS) {
+
+		memdelete(f);
+		memdelete(fw);
+		DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+		da->remove(p_path+".depren");
+		memdelete(da);
+		//fuck it, use the old approach;
+
+		WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data());
+
+		Error err;
+		f = FileAccess::open(p_path,FileAccess::READ,&err);
+		if (err!=OK) {
+			ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN);
+		}
+
+		Ref<ResourceInteractiveLoaderBinary> ria = memnew( ResourceInteractiveLoaderBinary );
+		ria->local_path=Globals::get_singleton()->localize_path(p_path);
+		ria->res_path=ria->local_path;
+		ria->remaps=p_map;
+	//	ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
+		ria->open(f);
+
+		err = ria->poll();
+
+		while(err==OK) {
+			err=ria->poll();
+		}
+
+		ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT);
+		RES res = ria->get_resource();
+		ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT);
+
+		return ResourceFormatSaverBinary::singleton->save(p_path,res);
+	}
+
+	if (ver_format>FORMAT_VERSION ||  ver_major>VERSION_MAJOR) {
+
+		memdelete(f);
+		memdelete(fw);
+		ERR_EXPLAIN("File Format '"+itos(FORMAT_VERSION)+"."+itos(ver_major)+"."+itos(ver_minor)+"' is too new! Please upgrade to a a new engine version: "+local_path);
+		ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
+
+	}
+
+	fw->store_32( VERSION_MAJOR ); //current version
+	fw->store_32( VERSION_MINOR );
+	fw->store_32( FORMAT_VERSION );
+
+	save_ustring(fw,get_ustring(f)); //type
+
+
+	size_t md_ofs = f->get_pos();
+	size_t importmd_ofs = f->get_64();
+	fw->store_64(0); //metadata offset
+
+	for(int i=0;i<14;i++) {
+		fw->store_32(0);
+		f->get_32();
+	}
+
+	//string table
+	uint32_t string_table_size=f->get_32();
+
+	fw->store_32(string_table_size);
+
+	for(uint32_t i=0;i<string_table_size;i++) {
+
+		String s = get_ustring(f);
+		save_ustring(fw,s);
+	}
+
+	//external resources
+	uint32_t ext_resources_size=f->get_32();
+	fw->store_32(ext_resources_size);
+	for(uint32_t i=0;i<ext_resources_size;i++) {
+
+		String type = get_ustring(f);
+		String path = get_ustring(f);
+
+		bool relative=false;
+		if (!path.begins_with("res://")) {
+			path=local_path.plus_file(path).simplify_path();
+			relative=true;
+		}
+
+
+		if (p_map.has(path)) {
+			String np=p_map[path];
+			path=np;
+		}
+
+		if (relative) {
+			//restore relative
+			path=local_path.path_to_file(path);
+		}
+
+		save_ustring(fw,type);
+		save_ustring(fw,path);
+	}
+
+	int64_t size_diff = (int64_t)fw->get_pos() - (int64_t)f->get_pos();
+
+	//internal resources
+	uint32_t int_resources_size=f->get_32();
+	fw->store_32(int_resources_size);
+
+	for(uint32_t i=0;i<int_resources_size;i++) {
+
+
+		String path=get_ustring(f);
+		uint64_t offset=f->get_64();
+		save_ustring(fw,path);
+		fw->store_64(offset+size_diff);
+	}
+
+	//rest of file
+	uint8_t b = f->get_8();
+	while(!f->eof_reached()) {
+		fw->store_8(b);
+		b = f->get_8();
+	}
+
+	bool all_ok = fw->get_error()==OK;
+
+	fw->seek(md_ofs);
+	fw->store_64(importmd_ofs+size_diff);
+
+
+	memdelete(f);
+	memdelete(fw);
+
+	if (!all_ok) {
+		return ERR_CANT_CREATE;
+	}
+
+	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+	da->remove(p_path);
+	da->rename(p_path+".depren",p_path);
+	memdelete(da);
+	return OK;
 }
 
 
@@ -1433,10 +1710,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
 			}
 
 			if (res->get_path().length() && res->get_path().find("::")==-1) {
-				f->store_32(OBJECT_EXTERNAL_RESOURCE);
-				save_unicode_string(res->get_save_type());
-				String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
-				save_unicode_string(path);
+				f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX);
+				f->store_32(external_resources[res]);
 			} else {
 
 				if (!resource_set.has(res)) {
@@ -1594,11 +1869,12 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant
 
 			RES res = p_variant.operator RefPtr();
 
-			if (res.is_null())
+			if (res.is_null() || external_resources.has(res))
 				return;
 
 			if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
-				external_resources.insert(res);
+				int idx = external_resources.size();
+				external_resources[res]=idx;
 				return;
 			}
 
@@ -1842,10 +2118,18 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
 
 	// save external resource table
 	f->store_32(external_resources.size()); //amount of external resources
-	for(Set<RES>::Element *E=external_resources.front();E;E=E->next()) {
+	Vector<RES> save_order;
+	save_order.resize(external_resources.size());
+
+	for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
+		save_order[E->get()]=E->key();
+	}
 
-		save_unicode_string(E->get()->get_save_type());
-		String path = E->get()->get_path();
+	for(int i=0;i<save_order.size();i++) {
+
+		save_unicode_string(save_order[i]->get_save_type());
+		String path = save_order[i]->get_path();
+		path=relative_paths?local_path.path_to_file(path):path;
 		save_unicode_string(path);
 	}
 	// save internal resource table
@@ -1995,3 +2279,9 @@ void ResourceFormatSaverBinary::get_recognized_extensions(const RES& p_resource,
 
 }
 
+ResourceFormatSaverBinary* ResourceFormatSaverBinary::singleton=NULL;
+
+ResourceFormatSaverBinary::ResourceFormatSaverBinary() {
+
+	singleton=this;
+}

+ 9 - 5
core/io/resource_format_binary.h

@@ -71,6 +71,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
 	String get_unicode_string();
 	void _advance_padding(uint32_t p_len);
 
+	Map<String,String> remaps;
 	Error error;
 
 	int stage;
@@ -88,9 +89,10 @@ public:
 	virtual int get_stage() const;
 	virtual int get_stage_count() const;
 
+	void set_remaps(const Map<String,String>& p_remaps) { remaps=p_remaps; }
 	void open(FileAccess *p_f);
 	String recognize(FileAccess *p_f);
-	void get_dependencies(FileAccess *p_f,List<String> *p_dependencies);
+	void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
 
 
 	ResourceInteractiveLoaderBinary();
@@ -101,13 +103,14 @@ public:
 class ResourceFormatLoaderBinary : public ResourceFormatLoader {
 public:
 
-	virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
+	virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
 	virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;
-	virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
+	virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
 	virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const;
+	virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
 
 
 
@@ -134,7 +137,7 @@ class ResourceFormatSaverBinaryInstance  {
 	Vector<StringName> strings;
 
 
-	Set<RES> external_resources;
+	Map<RES,int> external_resources;
 	List<RES> saved_resources;
 
 
@@ -174,11 +177,12 @@ class ResourceFormatSaverBinary : public ResourceFormatSaver  {
 
 public:
 
+	static ResourceFormatSaverBinary* singleton;
 	virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
 	virtual bool recognize(const RES& p_resource) const;
 	virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
 
-
+	ResourceFormatSaverBinary();
 };
 
 

+ 269 - 53
core/io/resource_format_xml.cpp

@@ -29,10 +29,10 @@
 #include "resource_format_xml.h"
 #include "globals.h"
 #include "version.h"
+#include "os/dir_access.h"
 
 
-
-ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit,bool p_printerr) {
+ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool *r_exit, bool p_printerr, List<String> *r_order) {
 
 
 	while(get_char()!='<' && !f->eof_reached()) {}
@@ -107,7 +107,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool
 				if (r_value.size()) {
 
 					r_value.push_back(0);
-					tag.args[name].parse_utf8(r_value.get_data());
+					String str;
+					str.parse_utf8(r_value.get_data());
+					tag.args[name]=str;
+					if (r_order)
+						r_order->push_back(name);
 				}
 				break;
 
@@ -119,7 +123,11 @@ ResourceInteractiveLoaderXML::Tag* ResourceInteractiveLoaderXML::parse_tag(bool
 				} else if (reading_value && r_value.size()) {
 
 					r_value.push_back(0);
-					tag.args[name].parse_utf8(r_value.get_data());
+					String str;
+					str.parse_utf8(r_value.get_data());
+					tag.args[name]=str;
+					if (r_order)
+						r_order->push_back(name);
 					name="";
 					r_value.clear();
 					reading_value=false;
@@ -463,6 +471,10 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
 
 			}
 
+			if (remaps.has(path)) {
+				path=remaps[path];
+			}
+
 			//take advantage of the resource loader cache. The resource is cached on it, even if
 			RES res=ResourceLoader::load(path,hint);
 
@@ -473,10 +485,31 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
 			}
 
 			r_v=res.get_ref_ptr();
+		} else if (tag->args.has("external")) {
+
+			int index = tag->args["external"].to_int();
+			if (ext_resources.has(index)) {
+				String path=ext_resources[index].path;
+				String type=ext_resources[index].type;
+
+				//take advantage of the resource loader cache. The resource is cached on it, even if
+				RES res=ResourceLoader::load(path,type);
+
+				if (res.is_null()) {
+
+					WARN_PRINT(String("Couldn't load externalresource: "+path).ascii().get_data());
+				}
+
+				r_v=res.get_ref_ptr();
+			} else {
+				WARN_PRINT(String("Invalid external resource index: "+itos(index)).ascii().get_data());
+
+			}
 		}
 
 
 
+
 		Error err=goto_end_of_tag();
 		if (err) {
 			ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error closing <resource> tag.");
@@ -1364,32 +1397,6 @@ Error ResourceInteractiveLoaderXML::poll() {
 	if (error!=OK)
 		return error;
 
-	if (ext_resources.size()) {
-
-		error=ERR_FILE_CORRUPT;
-		String path=ext_resources.front()->get();
-
-		RES res = ResourceLoader::load(path);
-
-		if (res.is_null()) {
-
-			if (ResourceLoader::get_abort_on_missing_resources()) {
-				ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": editor exported nonexistent resource at: "+path);
-				ERR_FAIL_V(error);
-			} else {
-				ResourceLoader::notify_load_error("Resource Not Found: "+path);
-			}
-		} else {
-
-			resource_cache.push_back(res);
-		}
-
-		error=OK;
-		ext_resources.pop_front();
-		resource_current++;
-		return error;
-	}
-
 	bool exit;
 	Tag *tag = parse_tag(&exit);
 
@@ -1413,12 +1420,13 @@ Error ResourceInteractiveLoaderXML::poll() {
 		ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
 		ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT);
 
-		String type;
+		String type="Resource";
 		if (tag->args.has("type"))
 			type=tag->args["type"];
 
 		String path = tag->args["path"];
 
+
 		ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?.");
 		ERR_FAIL_COND_V(path.begins_with("local://"),ERR_FILE_CORRUPT);
 
@@ -1427,6 +1435,9 @@ Error ResourceInteractiveLoaderXML::poll() {
 			path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path));
 		}
 
+		if (remaps.has(path)) {
+			path=remaps[path];
+		}
 
 		RES res = ResourceLoader::load(path,type);
 
@@ -1436,13 +1447,21 @@ Error ResourceInteractiveLoaderXML::poll() {
 				ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path);
 				ERR_FAIL_V(error);
 			} else {
-				ResourceLoader::notify_load_error("Resource Not Found: "+path);
+				ResourceLoader::notify_dependency_error(local_path,path,type);
 			}
 		} else {
 
 			resource_cache.push_back(res);
 		}
 
+		if (tag->args.has("index")) {
+			ExtResource er;
+			er.path=path;
+			er.type=type;
+			ext_resources[tag->args["index"].to_int()]=er;
+		}
+
+
 		Error err = close_tag("ext_resource");
 		if (err)
 			return error;
@@ -1566,7 +1585,7 @@ int ResourceInteractiveLoaderXML::get_stage() const {
 }
 int ResourceInteractiveLoaderXML::get_stage_count() const {
 
-	return resources_total+ext_resources.size();
+	return resources_total;//+ext_resources;
 }
 
 ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
@@ -1574,7 +1593,7 @@ ResourceInteractiveLoaderXML::~ResourceInteractiveLoaderXML() {
 	memdelete(f);
 }
 
-void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies) {
+void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) {
 
 
 	open(f);
@@ -1617,6 +1636,10 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
 			path = ResourceLoader::guess_full_filename(path,type);
 		}
 
+		if (p_add_types && tag->args.has("type")) {
+			path+="::"+tag->args["type"];
+		}
+
 		p_dependencies->push_back(path);
 
 		Error err = close_tag("ext_resource");
@@ -1628,6 +1651,167 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
 
 }
 
+Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
+
+	open(p_f);
+	ERR_FAIL_COND_V(error!=OK,error);
+
+	//FileAccess
+
+	bool old_format=false;
+
+	FileAccess *fw = NULL;
+
+	String base_path=local_path.get_base_dir();
+
+	while(true) {
+		bool exit;
+		List<String> order;
+
+		Tag *tag = parse_tag(&exit,true,&order);
+
+		bool done=false;
+
+		if (!tag) {
+			if (fw) {
+				memdelete(fw);
+			}
+			error=ERR_FILE_CORRUPT;
+			ERR_FAIL_COND_V(!exit,error);
+			error=ERR_FILE_EOF;
+
+			return error;
+		}
+
+		if (tag->name=="ext_resource") {
+
+			if (!tag->args.has("index") || !tag->args.has("path") || !tag->args.has("type")) {
+				old_format=true;
+				break;
+			}
+
+			if (!fw) {
+
+				fw=FileAccess::open(p_path+".depren",FileAccess::WRITE);
+				fw->store_line("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); //no escape
+				fw->store_line("<resource_file type=\""+resource_type+"\" subresource_count=\""+itos(resources_total)+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\">");
+
+			}
+
+			String path = tag->args["path"];
+			String index = tag->args["index"];
+			String type = tag->args["type"];
+
+
+			bool relative=false;
+			if (!path.begins_with("res://")) {
+				path=base_path.plus_file(path).simplify_path();
+				relative=true;
+			}
+
+
+			if (p_map.has(path)) {
+				String np=p_map[path];
+				path=np;
+			}
+
+			if (relative) {
+				//restore relative
+				path=base_path.path_to_file(path);
+			}
+
+			tag->args["path"]=path;
+			tag->args["index"]=index;
+			tag->args["type"]=type;
+
+		} else {
+
+			done=true;
+		}
+
+		String tagt="\t<";
+		if (exit)
+			tagt+="/";
+		tagt+=tag->name;
+
+		for(List<String>::Element *E=order.front();E;E=E->next()) {
+			tagt+=" "+E->get()+"=\""+tag->args[E->get()]+"\"";
+		}
+		tagt+=">";
+		fw->store_line(tagt);
+		if (done)
+			break;
+		close_tag("ext_resource");
+		fw->store_line("\t</ext_resource>");
+
+	}
+
+
+	if (old_format) {
+		if (fw)
+			memdelete(fw);
+
+		DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+		da->remove(p_path+".depren");
+		memdelete(da);
+		//fuck it, use the old approach;
+
+		WARN_PRINT(("This file is old, so it can't refactor dependencies, opening and resaving: "+p_path).utf8().get_data());
+
+		Error err;
+		FileAccess *f2 = FileAccess::open(p_path,FileAccess::READ,&err);
+		if (err!=OK) {
+			ERR_FAIL_COND_V(err!=OK,ERR_FILE_CANT_OPEN);
+		}
+
+		Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
+		ria->local_path=Globals::get_singleton()->localize_path(p_path);
+		ria->res_path=ria->local_path;
+		ria->remaps=p_map;
+	//	ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
+		ria->open(f2);
+
+		err = ria->poll();
+
+		while(err==OK) {
+			err=ria->poll();
+		}
+
+		ERR_FAIL_COND_V(err!=ERR_FILE_EOF,ERR_FILE_CORRUPT);
+		RES res = ria->get_resource();
+		ERR_FAIL_COND_V(!res.is_valid(),ERR_FILE_CORRUPT);
+
+		return ResourceFormatSaverXML::singleton->save(p_path,res);
+	}
+
+	if (!fw) {
+
+		return OK; //nothing to rename, do nothing
+	}
+
+	uint8_t c=f->get_8();
+	while(!f->eof_reached()) {
+		fw->store_8(c);
+		c=f->get_8();
+	}
+
+	bool all_ok = fw->get_error()==OK;
+
+	memdelete(fw);
+
+	if (!all_ok) {
+		return ERR_CANT_CREATE;
+	}
+
+	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+	da->remove(p_path);
+	da->rename(p_path+".depren",p_path);
+	memdelete(da);
+
+	return OK;
+
+}
+
 
 void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
 
@@ -1686,6 +1870,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
 
 	}
 
+	/*
 	String preload_depts = "deps/"+local_path.md5_text();
 	if (Globals::get_singleton()->has(preload_depts)) {
 		ext_resources.clear();
@@ -1697,7 +1882,7 @@ void ResourceInteractiveLoaderXML::open(FileAccess *p_f) {
 		}
 		print_line(local_path+" - EXTERNAL RESOURCES: "+itos(ext_resources.size()));
 	}
-
+*/
 
 }
 
@@ -1730,7 +1915,10 @@ String ResourceInteractiveLoaderXML::recognize(FileAccess *p_f) {
 
 /////////////////////
 
-Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path) {
+Ref<ResourceInteractiveLoader> ResourceFormatLoaderXML::load_interactive(const String &p_path, Error *r_error) {
+
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
 
 	Error err;
 	FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@@ -1816,7 +2004,7 @@ String ResourceFormatLoaderXML::get_resource_type(const String &p_path) const{
 }
 
 
-void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies) {
+void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
 
 	FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
 	if (!f) {
@@ -1828,11 +2016,27 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String>
 	ria->local_path=Globals::get_singleton()->localize_path(p_path);
 	ria->res_path=ria->local_path;
 //	ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
-	ria->get_dependencies(f,p_dependencies);
+	ria->get_dependencies(f,p_dependencies,p_add_types);
+
 
+}
+
+Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
+
+	FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
+	if (!f) {
 
+		ERR_FAIL_V(ERR_CANT_OPEN);
+	}
+
+	Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
+	ria->local_path=Globals::get_singleton()->localize_path(p_path);
+	ria->res_path=ria->local_path;
+//	ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
+	return ria->rename_dependencies(f,p_path,p_map);
 }
 
+
 /****************************************************************************************/
 /****************************************************************************************/
 /****************************************************************************************/
@@ -2024,20 +2228,26 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
 				return; // don't save it
 			}
 
-			params="resource_type=\""+res->get_save_type()+"\"";
+			if (external_resources.has(res)) {
 
-			if (res->get_path().length() && res->get_path().find("::")==-1) {
-				//external resource
-				String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
-				escape(path);
-				params+=" path=\""+path+"\"";
+				params="external=\""+itos(external_resources[res])+"\"";
 			} else {
+				params="resource_type=\""+res->get_save_type()+"\"";
 
-				//internal resource
-				ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
-				ERR_FAIL_COND(!resource_set.has(res));
 
-				params+=" path=\"local://"+itos(res->get_subindex())+"\"";
+				if (res->get_path().length() && res->get_path().find("::")==-1) {
+					//external resource
+					String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path();
+					escape(path);
+					params+=" path=\""+path+"\"";
+				} else {
+
+					//internal resource
+					ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
+					ERR_FAIL_COND(!resource_set.has(res));
+
+					params+=" path=\"local://"+itos(res->get_subindex())+"\"";
+				}
 			}
 
 		} break;
@@ -2441,11 +2651,12 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo
 
 			RES res = p_variant.operator RefPtr();
 
-			if (res.is_null())
+			if (res.is_null() || external_resources.has(res))
 				return;
 
 			if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) {
-				external_resources.push_back(res);
+				int index = external_resources.size();
+				external_resources[res]=index;
 				return;
 			}
 
@@ -2533,12 +2744,12 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
 	enter_tag("resource_file","type=\""+p_resource->get_type()+"\" subresource_count=\""+itos(saved_resources.size()+external_resources.size())+"\" version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\" version_name=\""+VERSION_FULL_NAME+"\"");
 	write_string("\n",false);
 
-	for(List<RES>::Element *E=external_resources.front();E;E=E->next()) {
+	for(Map<RES,int>::Element *E=external_resources.front();E;E=E->next()) {
 
 		write_tabs();
-		String p = E->get()->get_path();
+		String p = E->key()->get_path();
 
-		enter_tag("ext_resource","path=\""+p+"\" type=\""+E->get()->get_save_type()+"\""); //bundled
+		enter_tag("ext_resource","path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" index=\""+itos(E->get())+"\""); //bundled
 		exit_tag("ext_resource"); //bundled
 		write_string("\n",false);
 	}
@@ -2667,3 +2878,8 @@ void ResourceFormatSaverXML::get_recognized_extensions(const RES& p_resource,Lis
 	}
 
 }
+
+ResourceFormatSaverXML* ResourceFormatSaverXML::singleton=NULL;
+ResourceFormatSaverXML::ResourceFormatSaverXML() {
+	singleton=this;
+}

+ 18 - 7
core/io/resource_format_xml.h

@@ -46,13 +46,21 @@ class ResourceInteractiveLoaderXML : public ResourceInteractiveLoader {
 
 		String name;
 		HashMap<String,String> args;
+
 	};
 
 	_FORCE_INLINE_ Error _parse_array_element(Vector<char> &buff,bool p_number_only,FileAccess *f,bool *end);
 
 
+	struct ExtResource {
+		String path;
+		String type;
+	};
+
 
-	List<StringName> ext_resources;
+	Map<String,String> remaps;
+
+	Map<int,ExtResource> ext_resources;
 
 	int resources_total;
 	int resource_current;
@@ -66,7 +74,7 @@ friend class ResourceFormatLoaderXML;
 	List<Tag> tag_stack;
 
 	List<RES> resource_cache;
-	Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true);
+	Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true,List<String> *r_order=NULL);
 	Error close_tag(const String& p_name);
 	_FORCE_INLINE_ void unquote(String& p_str);
 	Error goto_end_of_tag();
@@ -87,7 +95,8 @@ public:
 
 	void open(FileAccess *p_f);
 	String recognize(FileAccess *p_f);
-	void get_dependencies(FileAccess *p_f,List<String> *p_dependencies);
+	void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
+	Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
 
 
 	~ResourceInteractiveLoaderXML();
@@ -97,12 +106,13 @@ public:
 class ResourceFormatLoaderXML : public ResourceFormatLoader {
 public:
 
-	virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
+	virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
 	virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;
-	virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
+	virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
+	virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
 
 
 };
@@ -125,7 +135,7 @@ class ResourceFormatSaverXMLInstance  {
 	int depth;
 	Set<RES> resource_set;
 	List<RES> saved_resources;
-	List<RES> external_resources;
+	Map<RES,int> external_resources;
 
 	void enter_tag(const char* p_tag,const String& p_args=String());
 	void exit_tag(const char* p_tag);
@@ -148,11 +158,12 @@ public:
 
 class ResourceFormatSaverXML : public ResourceFormatSaver {
 public:
+	static ResourceFormatSaverXML* singleton;
 	virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0);
 	virtual bool recognize(const RES& p_resource) const;
 	virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const;
 
-
+	ResourceFormatSaverXML();
 };
 
 

+ 54 - 11
core/io/resource_loader.cpp

@@ -103,10 +103,10 @@ public:
 
 
 
-Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path) {
+Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, Error *r_error) {
 
 	//either this
-	Ref<Resource> res = load(p_path);
+	Ref<Resource> res = load(p_path,p_path,r_error);
 	if (res.is_null())
 		return Ref<ResourceInteractiveLoader>();
 
@@ -115,12 +115,13 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const Stri
 	return ril;
 }
 
-RES ResourceFormatLoader::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoader::load(const String &p_path, const String& p_original_path, Error *r_error) {
+
 
 	String path=p_path;
 
 	//or this must be implemented
-	Ref<ResourceInteractiveLoader> ril = load_interactive(p_path);
+	Ref<ResourceInteractiveLoader> ril = load_interactive(p_path,r_error);
 	if (!ril.is_valid())
 		return RES();
 	ril->set_local_path(p_original_path);
@@ -130,9 +131,14 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat
 		Error err = ril->poll();
 
 		if (err==ERR_FILE_EOF) {
+			if (r_error)
+				*r_error=OK;
 			return ril->get_resource();
 		}
 
+		if (r_error)
+			*r_error=err;
+
 		ERR_FAIL_COND_V(err!=OK,RES());
 	}
 
@@ -140,7 +146,7 @@ RES ResourceFormatLoader::load(const String &p_path,const String& p_original_pat
 
 }
 
-void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
+void ResourceFormatLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
 
 	//do nothing by default
 }
@@ -149,7 +155,10 @@ void ResourceFormatLoader::get_dependencies(const String& p_path,List<String> *p
 ///////////////////////////////////
 
 
-RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_no_cache) {
+RES ResourceLoader::load(const String &p_path, const String& p_type_hint, bool p_no_cache, Error *r_error) {
+
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
 
 	String local_path;
 	if (p_path.is_rel_path())
@@ -183,7 +192,7 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n
 		if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
 			continue;
 		found=true;
-		RES res = loader[i]->load(remapped_path,local_path);
+		RES res = loader[i]->load(remapped_path,local_path,r_error);
 		if (res.is_null())
 			continue;
 		if (!p_no_cache)
@@ -289,9 +298,11 @@ String ResourceLoader::find_complete_path(const String& p_path,const String& p_t
 	return local_path;
 }
 
-Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache) {
+Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path,const String& p_type_hint,bool p_no_cache,Error *r_error) {
 
 
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
 
 	String local_path;
 	if (p_path.is_rel_path())
@@ -327,7 +338,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
 		if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
 			continue;
 		found=true;
-		Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path);
+		Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(remapped_path,r_error);
 		if (ril.is_null())
 			continue;
 		if (!p_no_cache)
@@ -352,7 +363,32 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l
 	loader[loader_count++]=p_format_loader;
 }
 
-void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_dependencies) {
+void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) {
+
+
+	String local_path;
+	if (p_path.is_rel_path())
+		local_path="res://"+p_path;
+	else
+		local_path = Globals::get_singleton()->localize_path(p_path);
+
+	String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
+
+	String extension=remapped_path.extension();
+
+	for (int i=0;i<loader_count;i++) {
+
+		if (!loader[i]->recognize(extension))
+			continue;
+		//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
+		//	continue;
+
+		loader[i]->get_dependencies(remapped_path,p_dependencies,p_add_types);
+
+	}
+}
+
+Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
 
 
 	String local_path;
@@ -372,11 +408,15 @@ void ResourceLoader::get_dependencies(const String& p_path,List<String> *p_depen
 		//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
 		//	continue;
 
-		loader[i]->get_dependencies(remapped_path,p_dependencies);
+		return loader[i]->rename_dependencies(p_path,p_map);
 
 	}
+
+	return OK; // ??
+
 }
 
+
 String ResourceLoader::guess_full_filename(const String &p_path,const String& p_type) {
 
 	String local_path;
@@ -414,6 +454,9 @@ String ResourceLoader::get_resource_type(const String &p_path) {
 ResourceLoadErrorNotify ResourceLoader::err_notify=NULL;
 void *ResourceLoader::err_notify_ud=NULL;
 
+DependencyErrorNotify ResourceLoader::dep_err_notify=NULL;
+void *ResourceLoader::dep_err_notify_ud=NULL;
+
 bool ResourceLoader::abort_on_missing_resource=true;
 bool ResourceLoader::timestamp_on_load=false;
 

+ 16 - 6
core/io/resource_loader.h

@@ -57,21 +57,23 @@ public:
 class ResourceFormatLoader {
 public:
 
-	virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path);
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
 	virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
 	bool recognize(const String& p_extension) const;
 	virtual bool handles_type(const String& p_type) const=0;
 	virtual String get_resource_type(const String &p_path) const=0;
-	virtual void get_dependencies(const String& p_path,List<String> *p_dependencies);
+	virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
 	virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const { return ERR_UNAVAILABLE; }
+	virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map) { return OK; }
 
 	virtual ~ResourceFormatLoader() {}
 };
 
 
 typedef void (*ResourceLoadErrorNotify)(void *p_ud,const String& p_text);
+typedef void (*DependencyErrorNotify)(void *p_ud,const String& p_loading,const String& p_which,const String& p_type);
 
 
 class ResourceLoader {	
@@ -86,6 +88,8 @@ class ResourceLoader {
 
 	static void* err_notify_ud;
 	static ResourceLoadErrorNotify err_notify;
+	static void* dep_err_notify_ud;
+	static DependencyErrorNotify dep_err_notify;
 	static bool abort_on_missing_resource;
 
 	static String find_complete_path(const String& p_path,const String& p_type);
@@ -93,14 +97,15 @@ public:
 
 
 	
-	static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false);
-	static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false);
+	static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
+	static RES load(const String &p_path,const String& p_type_hint="",bool p_no_cache=false,Error *r_error=NULL);
 	static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path);
 
 	static void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions);
 	static void add_resource_format_loader(ResourceFormatLoader *p_format_loader);
 	static String get_resource_type(const String &p_path);
-	static void get_dependencies(const String& p_path,List<String> *p_dependencies);
+	static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
+	static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
 
 	static String guess_full_filename(const String &p_path,const String& p_type);
 
@@ -108,6 +113,11 @@ public:
 
 	static void notify_load_error(const String& p_err) { if (err_notify) err_notify(err_notify_ud,p_err); }
 	static void set_error_notify_func(void* p_ud,ResourceLoadErrorNotify p_err_notify) { err_notify=p_err_notify; err_notify_ud=p_ud;}
+
+	static void notify_dependency_error(const String& p_path,const String& p_dependency,const String& p_type) { if (dep_err_notify) dep_err_notify(dep_err_notify_ud,p_path,p_dependency,p_type); }
+	static void set_dependency_error_notify_func(void* p_ud,DependencyErrorNotify p_err_notify) { dep_err_notify=p_err_notify; dep_err_notify_ud=p_ud;}
+
+
 	static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource=p_abort; }
 	static bool get_abort_on_missing_resources() { return abort_on_missing_resource; }
 };

+ 1 - 1
core/io/resource_saver.h

@@ -46,7 +46,7 @@ public:
 	virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0)=0;
 	virtual bool recognize(const RES& p_resource) const=0;
 	virtual void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const=0;
-		
+
 	virtual ~ResourceFormatSaver() {}
 };
 

+ 8 - 1
core/io/translation_loader_po.cpp

@@ -30,7 +30,10 @@
 #include "os/file_access.h"
 #include "translation.h"
 
-RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path) {
+RES TranslationLoaderPO::load(const String &p_path, const String& p_original_path, Error *r_error) {
+
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
 
 	FileAccess *f=FileAccess::open(p_path,FileAccess::READ);
 	ERR_FAIL_COND_V(!f,RES());
@@ -49,6 +52,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path
 	String msg_id;
 	String msg_str;
 	String config;
+	if (r_error)
+		*r_error=ERR_FILE_CORRUPT;
 
 	Ref<Translation> translation = Ref<Translation>( memnew( Translation ));
 	int line = 1;
@@ -174,6 +179,8 @@ RES TranslationLoaderPO::load(const String &p_path,const String& p_original_path
 		}
 	}
 
+	if (r_error)
+		*r_error=OK;
 
 	return translation;
 

+ 1 - 1
core/io/translation_loader_po.h

@@ -34,7 +34,7 @@
 class TranslationLoaderPO : public ResourceFormatLoader {
 public:
 
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 2 - 0
core/io/zip.h

@@ -39,6 +39,8 @@
 #ifndef _zip12_H
 #define _zip12_H
 
+#include <stdlib.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif

+ 1 - 0
core/io/zip_io.h

@@ -34,6 +34,7 @@
 #include "os/file_access.h"
 #include "os/copymem.h"
 
+
 static void* zipio_open(void* data, const char* p_fname, int mode) {
 
 	FileAccess *&f = *(FileAccess**)data;

+ 19 - 0
core/object_type_db.cpp

@@ -746,6 +746,25 @@ bool ObjectTypeDB::has_method(StringName p_type,StringName p_method,bool p_no_in
 
 }
 
+bool ObjectTypeDB::get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter) {
+
+	TypeInfo *type=types.getptr(p_class);
+	TypeInfo *check=type;
+	while(check) {
+
+		if (check->property_setget.has(p_prop)) {
+			r_class=check->name;
+			r_setter=check->property_setget[p_prop].setter;
+			return true;
+		}
+
+		check=check->inherits_ptr;
+	}
+
+	return false;
+
+}
+
 #ifdef DEBUG_METHODS_ENABLED
 MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) {
 	StringName mdname=method_name.name;

+ 3 - 1
core/object_type_db.h

@@ -475,7 +475,9 @@ public:
 	static void get_integer_constant_list(const StringName& p_type, List<String> *p_constants, bool p_no_inheritance=false);
 	static int get_integer_constant(const StringName& p_type, const StringName &p_name, bool *p_success=NULL);
 	static StringName get_category(const StringName& p_node);
-	
+
+	static bool get_setter_and_type_for_property(const StringName& p_class, const StringName& p_prop, StringName& r_class, StringName& r_setter);
+
 	static void set_type_enabled(StringName p_type,bool p_enable);
 	static bool is_type_enabled(StringName p_type);
 

+ 43 - 0
core/os/input.cpp

@@ -271,6 +271,38 @@ void InputDefault::parse_input_event(const InputEvent& p_event) {
 				mouse_button_mask|=(1<<p_event.mouse_button.button_index);
 			else
 				mouse_button_mask&=~(1<<p_event.mouse_button.button_index);
+
+			if (main_loop && emulate_touch && p_event.mouse_button.button_index==1) {
+				InputEventScreenTouch touch_event;
+				touch_event.index=0;
+				touch_event.pressed=p_event.mouse_button.pressed;
+				touch_event.x=p_event.mouse_button.x;
+				touch_event.y=p_event.mouse_button.y;
+				InputEvent ev;
+				ev.type=InputEvent::SCREEN_TOUCH;
+				ev.screen_touch=touch_event;
+				main_loop->input_event(ev);
+			}
+		} break;
+		case InputEvent::MOUSE_MOTION: {
+
+			if (main_loop && emulate_touch && p_event.mouse_motion.button_mask&1) {
+				InputEventScreenDrag drag_event;
+				drag_event.index=0;
+				drag_event.x=p_event.mouse_motion.x;
+				drag_event.y=p_event.mouse_motion.y;
+				drag_event.relative_x=p_event.mouse_motion.relative_x;
+				drag_event.relative_y=p_event.mouse_motion.relative_y;
+				drag_event.speed_x=p_event.mouse_motion.speed_x;
+				drag_event.speed_y=p_event.mouse_motion.speed_y;
+
+				InputEvent ev;
+				ev.type=InputEvent::SCREEN_DRAG;
+				ev.screen_drag=drag_event;
+
+				main_loop->input_event(ev);
+			}
+
 		} break;
 		case InputEvent::JOYSTICK_BUTTON: {
 
@@ -362,8 +394,19 @@ void InputDefault::action_release(const StringName& p_action){
 	}
 }
 
+void InputDefault::set_emulate_touch(bool p_emulate) {
+
+	emulate_touch=p_emulate;
+}
+
+bool InputDefault::is_emulating_touchscreen() const {
+
+	return emulate_touch;
+}
+
 InputDefault::InputDefault() {
 
 	mouse_button_mask=0;
+	emulate_touch=false;
 	main_loop=NULL;
 }

+ 7 - 0
core/os/input.h

@@ -78,6 +78,8 @@ public:
 
 	void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
 
+	virtual bool is_emulating_touchscreen() const=0;
+
 
 	Input();
 };
@@ -99,6 +101,8 @@ class InputDefault : public Input {
 	Vector2 mouse_pos;
 	MainLoop *main_loop;
 
+	bool emulate_touch;
+
 	struct SpeedTrack {
 
 		uint64_t last_tick;
@@ -147,6 +151,9 @@ public:
 
 	void iteration(float p_step);
 
+	void set_emulate_touch(bool p_emulate);
+	virtual bool is_emulating_touchscreen() const;
+
 	InputDefault();
 
 };

+ 2 - 2
core/os/os.cpp

@@ -31,7 +31,7 @@
 #include <stdarg.h>
 #include "dir_access.h"
 #include "globals.h"
-
+#include "input.h"
 
 OS* OS::singleton=NULL;
 
@@ -363,7 +363,7 @@ Error OS::set_cwd(const String& p_cwd) {
 bool OS::has_touchscreen_ui_hint() const {
 
 	//return false;
-	return GLOBAL_DEF("display/emulate_touchscreen",false);
+	return Input::get_singleton() && Input::get_singleton()->is_emulating_touchscreen();
 }
 
 int OS::get_free_static_memory() const {

+ 1 - 1
core/os/os.h

@@ -155,7 +155,7 @@ public:
 	virtual int get_screen_count() const{ return 1; }
 	virtual int get_current_screen() const { return 0; }
 	virtual void set_current_screen(int p_screen) { }
-	virtual Point2 get_screen_position(int p_screen=0)  { return Point2(); }
+	virtual Point2 get_screen_position(int p_screen=0) const { return Point2(); }
 	virtual Size2 get_screen_size(int p_screen=0) const { return get_window_size(); }
 	virtual Point2 get_window_position() const { return Vector2(); }
 	virtual void set_window_position(const Point2& p_position) {}

+ 2 - 2
core/typedefs.h

@@ -41,8 +41,8 @@
 #define _MKSTR(m_x) _STR(m_x)
 #endif
 // have to include version.h for this to work, include it in the .cpp not the .h
-#define VERSION_MKSTRING _MKSTR(VERSION_MAJOR)"."_MKSTR(VERSION_MINOR)"."_MKSTR(VERSION_STATUS)"."_MKSTR(VERSION_REVISION)
-#define VERSION_FULL_NAME _MKSTR(VERSION_NAME)" v"VERSION_MKSTRING
+#define VERSION_MKSTRING _MKSTR(VERSION_MAJOR)"." _MKSTR(VERSION_MINOR)"." _MKSTR(VERSION_STATUS)"." _MKSTR(VERSION_REVISION)
+#define VERSION_FULL_NAME _MKSTR(VERSION_NAME)" v" VERSION_MKSTRING
 
 
 #ifndef _ALWAYS_INLINE_

+ 31 - 0
core/ustring.cpp

@@ -3048,6 +3048,37 @@ bool String::is_valid_identifier() const {
 
 //kind of poor should be rewritten properly
 
+String String::world_wrap(int p_chars_per_line) const {
+
+	int from=0;
+	int last_space=0;
+	String ret;
+	for(int i=0;i<length();i++) {
+		if (i-from>=p_chars_per_line) {
+			if (last_space==-1) {
+				ret+=substr(from,i-from+1)+"\n";
+			} else {
+				ret+=substr(from,last_space-from)+"\n";
+				i=last_space; //rewind
+			}
+			from=i+1;
+			last_space=-1;
+		} else if (operator[](i)==' ' || operator[](i)=='\t') {
+			last_space=i;
+		} else if (operator[](i)=='\n') {
+			ret+=substr(from,i-from);
+			from=i+1;
+			last_space=-1;
+		}
+	}
+
+	if (from<length()) {
+		ret+=substr(from,length());
+	}
+
+	return ret;
+}
+
 String String::c_unescape() const {
 
 	String escaped=*this;

+ 1 - 0
core/ustring.h

@@ -209,6 +209,7 @@ public:
 	String xml_unescape() const;
 	String c_escape() const;
 	String c_unescape() const;
+	String world_wrap(int p_chars_per_line) const;
 	
 	String percent_encode() const;
 	String percent_decode() const;

+ 10 - 2
core/variant.cpp

@@ -1592,9 +1592,17 @@ Variant::operator String() const {
 		} break;
 		case OBJECT: {
 
-			if (_get_obj().obj)
+			if (_get_obj().obj) {
+				#ifdef DEBUG_ENABLED
+					if (ScriptDebugger::get_singleton() && _get_obj().ref.is_null()) {
+						//only if debugging!
+						if (!ObjectDB::instance_validate(_get_obj().obj)) {
+							return "[Deleted Object]";
+						};
+					};
+				#endif
 				return "["+_get_obj().obj->get_type()+":"+itos(_get_obj().obj->get_instance_ID())+"]";
-			else
+			} else
 				return "[Object:null]";
 
 		} break;

+ 6 - 3
demos/2d/platformer/engine.cfg

@@ -4,14 +4,17 @@ name="Platformer"
 main_scene="res://stage.xml"
 icon="res://icon.png"
 name_es="Plataformero"
+target_fps="60"
 
 [display]
 
 width=800
 height=480
-stretch_2d=false
-stretch_mode="viewport"
-stretch_aspect="keep"
+#stretch_2d=false
+#stretch_mode="viewport"
+#stretch_aspect="keep"
+stretch_mode="2d"
+stretch_aspect="keep_height"
 
 [image_loader]
 

+ 12 - 1
drivers/chibi/event_stream_chibi.cpp

@@ -779,8 +779,10 @@ EventStreamChibi::EventStreamChibi() {
 
 
 
-RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderChibi::load(const String &p_path, const String& p_original_path, Error *r_error) {
 
+	if (r_error)
+		*r_error=ERR_FILE_CANT_OPEN;
 	String el = p_path.extension().to_lower();
 
 	CPFileAccessWrapperImpl f;
@@ -791,6 +793,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
 		CPLoader_IT loader(&f);
 		CPLoader::Error err = loader.load_song(p_path.utf8().get_data(),&esc->song,false);
 		ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
+		if (r_error)
+			*r_error=OK;
 
 		return esc;
 
@@ -800,6 +804,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
 		CPLoader_XM loader(&f);
 		CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
 		ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
+		if (r_error)
+			*r_error=OK;
 		return esc;
 
 	} else if (el=="s3m") {
@@ -808,6 +814,9 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
 		CPLoader_S3M loader(&f);
 		CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
 		ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
+		if (r_error)
+			*r_error=OK;
+
 		return esc;
 
 	} else if (el=="mod") {
@@ -816,6 +825,8 @@ RES ResourceFormatLoaderChibi::load(const String &p_path,const String& p_origina
 		CPLoader_MOD loader(&f);
 		CPLoader::Error err=loader.load_song(p_path.utf8().get_data(),&esc->song,false);
 		ERR_FAIL_COND_V(err!=CPLoader::FILE_OK,RES());
+		if (r_error)
+			*r_error=OK;
 		return esc;
 	}
 

+ 1 - 1
drivers/chibi/event_stream_chibi.h

@@ -301,7 +301,7 @@ public:
 class ResourceFormatLoaderChibi : public ResourceFormatLoader {
 
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 9 - 1
drivers/dds/texture_loader_dds.cpp

@@ -64,8 +64,10 @@ static const DDSFormatInfo dds_format_info[DDS_MAX]={
 };
 
 
-RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatDDS::load(const String &p_path, const String& p_original_path, Error *r_error) {
 
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
 
 	Error err;
 	FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@@ -73,6 +75,8 @@ RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path)
 		return RES();
 
 	FileAccessRef fref(f);
+	if (r_error)
+		*r_error=ERR_FILE_CORRUPT;
 
 	ERR_EXPLAIN("Unable to open DDS texture file: "+p_path);
 	ERR_FAIL_COND_V(err!=OK,RES());
@@ -427,6 +431,10 @@ RES ResourceFormatDDS::load(const String &p_path,const String& p_original_path)
 	Ref<ImageTexture> texture = memnew( ImageTexture );
 	texture->create_from_image(img);
 
+	if (r_error)
+		*r_error=OK;
+
+
 	return texture;
 
 }

+ 1 - 1
drivers/dds/texture_loader_dds.h

@@ -7,7 +7,7 @@
 class ResourceFormatDDS : public ResourceFormatLoader{
 public:
 
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 11 - 11
drivers/gles2/shader_compiler_gles2.cpp

@@ -132,18 +132,18 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 			SL::BlockNode *bnode=(SL::BlockNode*)p_node;
 
 			//variables
-			code+="{"ENDL;
+            code+="{" ENDL;
 			for(Map<StringName,SL::DataType>::Element *E=bnode->variables.front();E;E=E->next()) {
 
-				code+=_mktab(p_level)+_typestr(E->value())+" "+replace_string(E->key())+";"ENDL;
+                code+=_mktab(p_level)+_typestr(E->value())+" "+replace_string(E->key())+";" ENDL;
 			}
 
 			for(int i=0;i<bnode->statements.size();i++) {
 
-				code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";"ENDL;
+                code+=_mktab(p_level)+dump_node_code(bnode->statements[i],p_level)+";" ENDL;
 			}
 
-			code+="}"ENDL;
+            code+="}" ENDL;
 
 		} break;
 		case SL::Node::TYPE_VARIABLE: {
@@ -489,15 +489,15 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 			SL::ControlFlowNode *cfnode=(SL::ControlFlowNode*)p_node;
 			if (cfnode->flow_op==SL::FLOW_OP_IF) {
 
-				code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {"ENDL;
+                code+="if ("+dump_node_code(cfnode->statements[0],p_level)+") {" ENDL;
 				code+=dump_node_code(cfnode->statements[1],p_level+1);
 				if (cfnode->statements.size()==3) {
 
-					code+="} else {"ENDL;
+                    code+="} else {" ENDL;
 					code+=dump_node_code(cfnode->statements[2],p_level+1);
 				}
 
-				code+="}"ENDL;
+                code+="}" ENDL;
 
 			} else if (cfnode->flow_op==SL::FLOW_OP_RETURN) {
 
@@ -560,7 +560,7 @@ Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) {
 		ubase=uniforms->size();
 	for(Map<StringName,SL::Uniform>::Element *E=p_program->uniforms.front();E;E=E->next()) {
 
-		String uline="uniform "+_typestr(E->get().type)+" _"+E->key().operator String()+";"ENDL;
+        String uline="uniform "+_typestr(E->get().type)+" _"+E->key().operator String()+";" ENDL;
 
 		global_code+=uline;
 		if (uniforms) {
@@ -593,10 +593,10 @@ Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) {
 			header+=_typestr(fnode->arguments[i].type)+" "+replace_string(fnode->arguments[i].name);
 		}
 
-		header+=") {"ENDL;
+        header+=") {" ENDL;
 		String fcode=header;
 		fcode+=dump_node_code(fnode->body,1);
-		fcode+="}"ENDL;
+        fcode+="}" ENDL;
 		global_code+=fcode;
 
 	}
@@ -605,7 +605,7 @@ Error ShaderCompilerGLES2::compile_node(SL::ProgramNode *p_program) {
 
 		StringName varname=E->key();
 		String newvarname=replace_string(varname);
-		global_code+="uniform "+_typestr(E->get())+" "+newvarname+";"ENDL;
+        global_code+="uniform "+_typestr(E->get())+" "+newvarname+";" ENDL;
 	}*/
 
 	code=dump_node_code(p_program,0);

+ 3 - 2
drivers/mpc/audio_stream_mpc.cpp

@@ -366,8 +366,9 @@ AudioStreamMPC::~AudioStreamMPC() {
 
 
 
-RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path,const String& p_original_path) {
-
+RES ResourceFormatLoaderAudioStreamMPC::load(const String &p_path, const String& p_original_path, Error *r_error) {
+	if (r_error)
+		*r_error=OK; //streamed so it will always work..
 	AudioStreamMPC *mpc_stream = memnew(AudioStreamMPC);
 	mpc_stream->set_file(p_path);
 	return Ref<AudioStreamMPC>(mpc_stream);

+ 1 - 1
drivers/mpc/audio_stream_mpc.h

@@ -88,7 +88,7 @@ public:
 
 class ResourceFormatLoaderAudioStreamMPC : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 8 - 1
drivers/pvr/texture_loader_pvr.cpp

@@ -22,8 +22,10 @@ enum PVRFLags {
 
 
 
-RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path,Error *r_error) {
 
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
 
 	Error err;
 	FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
@@ -34,6 +36,8 @@ RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path)
 
 	ERR_FAIL_COND_V(err,RES());
 
+	if (r_error)
+		*r_error=ERR_FILE_CORRUPT;
 
 	uint32_t hsize = f->get_32();
 
@@ -135,6 +139,9 @@ RES ResourceFormatPVR::load(const String &p_path,const String& p_original_path)
 	Ref<ImageTexture> texture = memnew( ImageTexture );
 	texture->create_from_image(image,tex_flags);
 
+	if (r_error)
+		*r_error=OK;
+
 	return texture;
 
 }

+ 1 - 1
drivers/pvr/texture_loader_pvr.h

@@ -9,7 +9,7 @@
 class ResourceFormatPVR : public ResourceFormatLoader{
 public:
 
-	virtual RES load(const String &p_path,const String& p_original_path);
+	virtual RES load(const String &p_path,const String& p_original_path,Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 4 - 1
drivers/speex/audio_stream_speex.cpp

@@ -530,7 +530,10 @@ AudioStreamSpeex::~AudioStreamSpeex() {
 	unload();
 }
 
-RES ResourceFormatLoaderAudioStreamSpeex::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderAudioStreamSpeex::load(const String &p_path, const String& p_original_path, Error *r_error) {
+
+	if (r_error)
+		*r_error=OK;
 
 	AudioStreamSpeex *stream = memnew(AudioStreamSpeex);
 	stream->set_file(p_path);

+ 1 - 1
drivers/speex/audio_stream_speex.h

@@ -91,7 +91,7 @@ public:
 
 class ResourceFormatLoaderAudioStreamSpeex : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 1 - 1
drivers/theora/video_stream_theora.h

@@ -102,7 +102,7 @@ public:
 
 class ResourceFormatLoaderVideoStreamTheora : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 1 - 1
drivers/theoraplayer/src/YUV/libyuv/src/cpu_id.cc

@@ -174,7 +174,7 @@ int cpu_info_ = kCpuInit;  // cpu_info is not initialized yet.
 #if !defined(__native_client__) && !defined(_M_ARM)
 
 static LIBYUV_BOOL TestEnv(const char* name) {
-#ifndef _WINRT
+#if !defined(_WINRT) && !defined(ORBIS_ENABLED)
   const char* var = getenv(name);
   if (var) {
     if (var[0] != '0') {

+ 3 - 1
drivers/theoraplayer/video_stream_theoraplayer.cpp

@@ -525,7 +525,9 @@ VideoStreamTheoraplayer::VideoStreamTheoraplayer() {
 };
 
 
-RES ResourceFormatLoaderVideoStreamTheoraplayer::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderVideoStreamTheoraplayer::load(const String &p_path, const String& p_original_path, Error *r_error) {
+	if (r_error)
+		*r_error=OK;
 
 	VideoStreamTheoraplayer *stream = memnew(VideoStreamTheoraplayer);
 	stream->set_file(p_path);

+ 1 - 1
drivers/theoraplayer/video_stream_theoraplayer.h

@@ -54,7 +54,7 @@ public:
 
 class ResourceFormatLoaderVideoStreamTheoraplayer : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 3 - 1
drivers/vorbis/audio_stream_ogg_vorbis.cpp

@@ -385,7 +385,9 @@ AudioStreamOGGVorbis::~AudioStreamOGGVorbis() {
 
 
 
-RES ResourceFormatLoaderAudioStreamOGGVorbis::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderAudioStreamOGGVorbis::load(const String &p_path, const String& p_original_path, Error *r_error) {
+	if (r_error)
+		*r_error=OK;
 
 	AudioStreamOGGVorbis *ogg_stream = memnew(AudioStreamOGGVorbis);
 	ogg_stream->set_file(p_path);

+ 1 - 1
drivers/vorbis/audio_stream_ogg_vorbis.h

@@ -111,7 +111,7 @@ public:
 
 class ResourceFormatLoaderAudioStreamOGGVorbis : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 74 - 11
main/main.cpp

@@ -75,7 +75,7 @@
 #include "core/io/file_access_zip.h"
 #include "translation.h"
 #include "version.h"
-
+#include "os/input.h"
 #include "performance.h"
 
 static Globals *globals=NULL;
@@ -94,11 +94,15 @@ static FileAccessNetworkClient *file_access_network_client=NULL;
 static TranslationServer *translation_server = NULL;
 
 static OS::VideoMode video_mode;
+static bool init_maximized=false;
+static bool init_fullscreen=false;
+static bool init_use_custom_pos=false;
+static Vector2 init_custom_pos;
 static int video_driver_idx=-1;
 static int audio_driver_idx=-1;
 static String locale;
 
-static bool init_maximized=false;
+
 static int init_screen=-1;
 
 static String unescape_cmdline(const String& p_str) {
@@ -136,8 +140,10 @@ void Main::print_help(const char* p_binary) {
 	}
 	OS::get_singleton()->print(")\n");
 	
-	OS::get_singleton()->print("\t-r WIDTHxHEIGHT\t : Request Screen Resolution\n");
+	OS::get_singleton()->print("\t-r WIDTHxHEIGHT\t : Request Window Resolution\n");
+	OS::get_singleton()->print("\t-p XxY\t : Request Window Position\n");
 	OS::get_singleton()->print("\t-f\t\t : Request Fullscreen\n");
+	OS::get_singleton()->print("\t-mx\t\t Request Maximized\n");
 	OS::get_singleton()->print("\t-vd DRIVER\t : Video Driver (");
 	for (int i=0;i<OS::get_singleton()->get_video_driver_count();i++) {
 		
@@ -311,7 +317,37 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 				
 			
 			}
-			
+		} else if (I->get()=="-p") { // position
+
+			if (I->next()) {
+
+				String vm=I->next()->get();
+
+				if (vm.find("x")==-1) { // invalid parameter format
+
+					goto error;
+
+
+				}
+
+				int x=vm.get_slice("x",0).to_int();
+				int y=vm.get_slice("x",1).to_int();
+
+				init_custom_pos=Point2(x,y);
+				init_use_custom_pos=true;
+				force_res=true;
+
+				N=I->next()->next();
+			} else {
+				goto error;
+
+
+			}
+
+
+		} else if (I->get()=="-mx") { // video driver
+
+			init_maximized=true;
 		} else if (I->get()=="-vd") { // video driver
 		
 			if (I->next()) {
@@ -383,7 +419,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 			
 		} else if (I->get()=="-f") { // fullscreen
 		
-			video_mode.fullscreen=true;
+			//video_mode.fullscreen=false;
+			init_fullscreen=true;
 		} else if (I->get()=="-e" || I->get()=="-editor") { // fonud editor
 
 			editor=true;
@@ -785,6 +822,14 @@ Error Main::setup2() {
 
 
 	OS::get_singleton()->initialize(video_mode,video_driver_idx,audio_driver_idx);
+	if (init_use_custom_pos) {
+		OS::get_singleton()->set_window_position(init_custom_pos);
+	}
+	if (init_maximized) {
+		OS::get_singleton()->set_window_maximized(true);
+	} else if (init_fullscreen) {
+		OS::get_singleton()->set_window_fullscreen(true);
+	}
 
 	register_core_singletons();
 
@@ -801,17 +846,29 @@ Error Main::setup2() {
 	if (init_maximized) {
 		OS::get_singleton()->set_window_maximized(true);
 	}
+	MAIN_PRINT("Main: Load Remaps");
+
+	path_remap->load_remaps();
 
 	if (show_logo) { //boot logo!
 		String boot_logo_path=GLOBAL_DEF("application/boot_splash",String());
 		bool boot_logo_scale=GLOBAL_DEF("application/boot_splash_fullsize",true);
 		Globals::get_singleton()->set_custom_property_info("application/boot_splash",PropertyInfo(Variant::STRING,"application/boot_splash",PROPERTY_HINT_FILE,"*.png"));
-
+		print_line("BOOT SPLASH: "+boot_logo_path);
 
 		Image boot_logo;
 
-		if (boot_logo_path.strip_edges()!="" && FileAccess::exists(boot_logo_path)) {
-			boot_logo.load(boot_logo_path);
+		boot_logo_path = boot_logo_path.strip_edges();
+		print_line("BOOT SPLASH IS : "+boot_logo_path);
+
+		if (boot_logo_path!=String() /*&& FileAccess::exists(boot_logo_path)*/) {
+			Error err = boot_logo.load(boot_logo_path);
+			if (err!=OK) {
+				print_line("ËRROR LOADING BOOT LOGO SPLASH :"+boot_logo_path);
+			} else {
+				print_line("BOOT SPLASH OK!");
+
+			}
 		}
 
 		if (!boot_logo.empty()) {
@@ -822,7 +879,7 @@ Error Main::setup2() {
 			VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg,boot_logo_scale);
 #ifndef TOOLS_ENABLED
 			//no tools, so free the boot logo (no longer needed)
-			Globals::get_singleton()->set("application/boot_logo",Image());
+		//	Globals::get_singleton()->set("application/boot_logo",Image());
 #endif
 
 		} else {
@@ -847,10 +904,16 @@ Error Main::setup2() {
 	GLOBAL_DEF("application/icon",String());
 	Globals::get_singleton()->set_custom_property_info("application/icon",PropertyInfo(Variant::STRING,"application/icon",PROPERTY_HINT_FILE,"*.png,*.webp"));
 
+	if (bool(GLOBAL_DEF("display/emulate_touchscreen",false))) {
+		if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
+			//only if no touchscreen ui hint, set emulation
+			InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
+			if (id)
+				id->set_emulate_touch(true);
+		}
+	}
 	MAIN_PRINT("Main: Load Remaps");
 
-	path_remap->load_remaps();
-
 	MAIN_PRINT("Main: Load Scene Types");
 
 	register_scene_types();

+ 53 - 1
modules/gdscript/gd_editor.cpp

@@ -998,6 +998,44 @@ static bool _guess_identifier_type_in_block(GDCompletionContext& context,int p_l
 	return false;
 }
 
+
+static bool _guess_identifier_from_assignment_in_function(GDCompletionContext& context,const StringName& p_identifier, const StringName& p_function,GDCompletionIdentifier &r_type) {
+
+	const GDParser::FunctionNode* func=NULL;
+	for(int i=0;i<context._class->functions.size();i++) {
+		if (context._class->functions[i]->name==p_function) {
+			func=context._class->functions[i];
+			break;
+		}
+	}
+
+	if (!func)
+		return false;
+
+	for(int i=0;i<func->body->statements.size();i++) {
+
+
+
+		if (func->body->statements[i]->type==GDParser::BlockNode::TYPE_OPERATOR) {
+			const GDParser::OperatorNode *op = static_cast<const GDParser::OperatorNode *>(func->body->statements[i]);
+			if (op->op==GDParser::OperatorNode::OP_ASSIGN) {
+
+				if (op->arguments.size() && op->arguments[0]->type==GDParser::Node::TYPE_IDENTIFIER) {
+
+					const GDParser::IdentifierNode *id = static_cast<const GDParser::IdentifierNode *>(op->arguments[0]);
+
+					if (id->name==p_identifier) {
+
+						return _guess_expression_type(context,op->arguments[1],func->body->statements[i]->line,r_type);
+					}
+				}
+			}
+		}
+	}
+
+	return false;
+}
+
 static bool _guess_identifier_type(GDCompletionContext& context,int p_line,const StringName& p_identifier,GDCompletionIdentifier &r_type) {
 
 	//go to block first
@@ -1089,8 +1127,22 @@ static bool _guess_identifier_type(GDCompletionContext& context,int p_line,const
 					r_type=_get_type_from_pinfo(context._class->variables[i]._export);
 					return true;
 				} else if (context._class->variables[i].expression) {
-					return _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type);
+
+					bool rtype = _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type);
+					if (rtype && r_type.type!=Variant::NIL)
+						return true;
+					//return _guess_expression_type(context,context._class->variables[i].expression,context._class->variables[i].line,r_type);
 				}
+
+				//try to guess from assignment in construtor or _ready
+				if (_guess_identifier_from_assignment_in_function(context,p_identifier,"_ready",r_type))
+					return true;
+				if (_guess_identifier_from_assignment_in_function(context,p_identifier,"_enter_tree",r_type))
+					return true;
+				if (_guess_identifier_from_assignment_in_function(context,p_identifier,"_init",r_type))
+					return true;
+
+				return false;
 			}
 		}
 	}

+ 79 - 13
modules/gdscript/gd_parser.cpp

@@ -170,6 +170,7 @@ void GDParser::_make_completable_call(int p_arg) {
 	completion_line=tokenizer->get_token_line();
 	completion_argument=p_arg;
 	completion_block=current_block;
+	completion_found=true;
 	tokenizer->advance();
 
 }
@@ -190,6 +191,7 @@ bool GDParser::_get_completable_identifier(CompletionType p_type,StringName& ide
 		completion_function=current_function;
 		completion_line=tokenizer->get_token_line();
 		completion_block=current_block;
+		completion_found=true;
 		tokenizer->advance();
 
 		if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
@@ -1414,6 +1416,24 @@ GDParser::Node* GDParser::_parse_and_reduce_expression(Node *p_parent,bool p_sta
 	return expr;
 }
 
+bool GDParser::_recover_from_completion() {
+
+	if (!completion_found) {
+		return false; //can't recover if no completion
+	}
+	//skip stuff until newline
+	while(tokenizer->get_token()!=GDTokenizer::TK_NEWLINE && tokenizer->get_token()!=GDTokenizer::TK_EOF && tokenizer->get_token()!=GDTokenizer::TK_ERROR) {
+		tokenizer->advance();
+	}
+	completion_found=false;
+	error_set=false;
+	if(tokenizer->get_token() == GDTokenizer::TK_ERROR){
+		error_set = true;
+	}
+
+	return true;
+}
+
 void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 
 	int indent_level = tab_level.back()->get();
@@ -1511,8 +1531,14 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 					Node *subexpr=NULL;
 
 					subexpr = _parse_and_reduce_expression(p_block,p_static);
-					if (!subexpr)
+					if (!subexpr) {
+						if (_recover_from_completion()) {
+							break;
+						}
 						return;
+					}
+
+
 
 					lv->assign=subexpr;
 					assigned=subexpr;
@@ -1543,8 +1569,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 
 				tokenizer->advance();
 				Node *condition = _parse_and_reduce_expression(p_block,p_static);
-				if (!condition)
+				if (!condition) {
+					if (_recover_from_completion()) {
+						break;
+					}
 					return;
+				}
 
 				ControlFlowNode *cf_if = alloc_node<ControlFlowNode>();
 
@@ -1598,8 +1628,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 
 						//condition
 						Node *condition = _parse_and_reduce_expression(p_block,p_static);
-						if (!condition)
+						if (!condition) {
+							if (_recover_from_completion()) {
+								break;
+							}
 							return;
+						}
 						cf_else->arguments.push_back(condition);
 						cf_else->cf_type=ControlFlowNode::CF_IF;
 
@@ -1660,8 +1694,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 
 				tokenizer->advance();
 				Node *condition = _parse_and_reduce_expression(p_block,p_static);
-				if (!condition)
+				if (!condition) {
+					if (_recover_from_completion()) {
+						break;
+					}
 					return;
+				}
 
 				ControlFlowNode *cf_while = alloc_node<ControlFlowNode>();
 
@@ -1706,8 +1744,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 				tokenizer->advance();
 
 				Node *container = _parse_and_reduce_expression(p_block,p_static);
-				if (!container)
+				if (!container) {
+					if (_recover_from_completion()) {
+						break;
+					}
 					return;
+				}
 
 				ControlFlowNode *cf_for = alloc_node<ControlFlowNode>();
 
@@ -1771,8 +1813,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 				} else {
 					//expect expression
 					Node *retexpr = _parse_and_reduce_expression(p_block,p_static);
-					if (!retexpr)
+					if (!retexpr) {
+						if (_recover_from_completion()) {
+							break;
+						}
 						return;
+					}
 					cf_return->arguments.push_back(retexpr);
 					p_block->statements.push_back(cf_return);
 					if (!_end_statement()) {
@@ -1787,8 +1833,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 
 				tokenizer->advance();
 				Node *condition = _parse_and_reduce_expression(p_block,p_static);
-				if (!condition)
+				if (!condition) {
+					if (_recover_from_completion()) {
+						break;
+					}
 					return;
+				}
 				AssertNode *an = alloc_node<AssertNode>();
 				an->condition=condition;
 				p_block->statements.push_back(an);
@@ -1801,8 +1851,12 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
 			default: {
 
 				Node *expression = _parse_and_reduce_expression(p_block,p_static,false,true);
-				if (!expression)
+				if (!expression) {
+					if (_recover_from_completion()) {
+						break;
+					}
 					return;
+				}
 				p_block->statements.push_back(expression);
 				if (!_end_statement()) {
 					_set_error("Expected end of statement after expression.");
@@ -2625,14 +2679,18 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 					Node *subexpr=NULL;
 
-					subexpr = _parse_and_reduce_expression(p_class,false);
-					if (!subexpr)
+					subexpr = _parse_and_reduce_expression(p_class,false,autoexport);
+					if (!subexpr) {
+						if (_recover_from_completion()) {
+							break;
+						}
 						return;
+					}
 
 					member.expression=subexpr;
 
 					if (autoexport) {
-						if (subexpr->type==Node::TYPE_ARRAY) {
+						if (1)/*(subexpr->type==Node::TYPE_ARRAY) {
 
 							member._export.type=Variant::ARRAY;
 
@@ -2640,7 +2698,7 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 							member._export.type=Variant::DICTIONARY;
 
-						} else {
+						} else*/ {
 
 							if (subexpr->type!=Node::TYPE_CONSTANT) {
 
@@ -2756,8 +2814,12 @@ void GDParser::_parse_class(ClassNode *p_class) {
 				Node *subexpr=NULL;
 
 				subexpr = _parse_and_reduce_expression(p_class,true,true);
-				if (!subexpr)
+				if (!subexpr) {
+					if (_recover_from_completion()) {
+						break;
+					}
 					return;
+				}
 
 				if (subexpr->type!=Node::TYPE_CONSTANT) {
 					_set_error("Expected constant expression");
@@ -2852,6 +2914,7 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p
 	completion_class=NULL;
 	completion_function=NULL;
 	completion_block=NULL;
+	completion_found=false;
 	current_block=NULL;
 	current_class=NULL;
 	current_function=NULL;
@@ -2874,6 +2937,7 @@ Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_ju
 	completion_class=NULL;
 	completion_function=NULL;
 	completion_block=NULL;
+	completion_found=false;
 	current_block=NULL;
 	current_class=NULL;
 
@@ -2917,6 +2981,8 @@ void GDParser::clear() {
 	current_block=NULL;
 	current_class=NULL;
 
+	completion_found=false;
+
 	current_function=NULL;
 
 	validating=false;

+ 2 - 0
modules/gdscript/gd_parser.h

@@ -419,10 +419,12 @@ private:
 	BlockNode *completion_block;
 	int completion_line;
 	int completion_argument;
+	bool completion_found;
 
 	PropertyInfo current_export;
 
 	void _set_error(const String& p_error, int p_line=-1, int p_column=-1);
+	bool _recover_from_completion();
 
 
 	bool _parse_arguments(Node* p_parent, Vector<Node*>& p_args, bool p_static, bool p_can_codecomplete=false);

+ 6 - 1
modules/gdscript/gd_script.cpp

@@ -2710,7 +2710,10 @@ GDScriptLanguage::~GDScriptLanguage() {
 
 /*************** RESOURCE ***************/
 
-RES ResourceFormatLoaderGDScript::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderGDScript::load(const String &p_path, const String& p_original_path, Error *r_error) {
+
+	if (r_error)
+		*r_error=ERR_FILE_CANT_OPEN;
 
 	GDScript *script = memnew( GDScript );
 
@@ -2742,6 +2745,8 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path,const String& p_orig
 
 		script->reload();
 	}
+	if (r_error)
+		*r_error=OK;
 
 	return scriptres;
 }

+ 1 - 1
modules/gdscript/gd_script.h

@@ -557,7 +557,7 @@ public:
 class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
 public:
 
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 1 - 2
platform/android/detect.py

@@ -173,8 +173,7 @@ def configure(env):
 	env.Append(LDPATH=[ld_path])
 	env.Append(LIBS=['OpenSLES'])
 #	env.Append(LIBS=['c','m','stdc++','log','EGL','GLESv1_CM','GLESv2','OpenSLES','supc++','android'])
-	if (env["ndk_platform"]!="2.2"):
-		env.Append(LIBS=['EGL','OpenSLES','android'])
+	env.Append(LIBS=['EGL','OpenSLES','android'])
 	env.Append(LIBS=['c','m','stdc++','log','GLESv1_CM','GLESv2', 'z'])
 
 	env["LINKFLAGS"]= string.split(" -g --sysroot="+ld_sysroot+" -Wl,--no-undefined -Wl,-z,noexecstack ")

+ 5 - 6
platform/android/file_access_android.cpp

@@ -29,16 +29,16 @@
 #include "file_access_android.h"
 #include "print_string.h"
 
-#ifdef ANDROID_NATIVE_ACTIVITY
+
 
 
 AAssetManager *FileAccessAndroid::asset_manager=NULL;
 
 
-void FileAccessAndroid::make_default() {
+/*void FileAccessAndroid::make_default() {
 
 	create_func=create_android;
-}
+}*/
 
 FileAccess* FileAccessAndroid::create_android() {
 
@@ -46,7 +46,7 @@ FileAccess* FileAccessAndroid::create_android() {
 }
 
 
-Error FileAccessAndroid::open(const String& p_path, int p_mode_flags) {
+Error FileAccessAndroid::_open(const String& p_path, int p_mode_flags) {
 
 	String path=fix_path(p_path).simplify_path();
 	if (path.begins_with("/"))
@@ -55,7 +55,6 @@ Error FileAccessAndroid::open(const String& p_path, int p_mode_flags) {
 		path=path.substr(6,path.length());
 
 
-
 	ERR_FAIL_COND_V(p_mode_flags&FileAccess::WRITE,ERR_UNAVAILABLE); //can't write on android..
 	a=AAssetManager_open(asset_manager,path.utf8().get_data(),AASSET_MODE_STREAMING);
 	if (!a)
@@ -184,4 +183,4 @@ FileAccessAndroid::~FileAccessAndroid()
 {
 	close();
 }
-#endif
+

+ 5 - 5
platform/android/file_access_android.h

@@ -29,14 +29,13 @@
 #ifndef FILE_ACCESS_ANDROID_H
 #define FILE_ACCESS_ANDROID_H
 
-#ifdef ANDROID_NATIVE_ACTIVITY
 
 
 #include "os/file_access.h"
 #include <stdio.h>
 #include <android/asset_manager.h>
 #include <android/log.h>
-#include <android_native_app_glue.h>
+//#include <android_native_app_glue.h>
 
 
 class FileAccessAndroid : public FileAccess {
@@ -51,7 +50,7 @@ public:
 
 	static AAssetManager *asset_manager;
 
-	virtual Error open(const String& p_path, int p_mode_flags); ///< open a file
+	virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
 	virtual void close(); ///< close a file
 	virtual bool is_open() const; ///< true when file is open
 
@@ -71,12 +70,13 @@ public:
 
 	virtual bool file_exists(const String& p_path); ///< return true if a file exists
 
+	virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
 
-	static void make_default();
+	//static void make_default();
 
 	FileAccessAndroid();
 	~FileAccessAndroid();
 };
 
 #endif // FILE_ACCESS_ANDROID_H
-#endif
+

+ 3 - 1
platform/android/file_access_jandroid.cpp

@@ -62,13 +62,15 @@ Error FileAccessJAndroid::_open(const String& p_path, int p_mode_flags) {
 
 	JNIEnv *env = ThreadAndroid::get_env();
 
-	//OS::get_singleton()->print("env: %p, io %p, fo: %p\n",env,io,_file_open);
 
 
 	jstring js = env->NewStringUTF(path.utf8().get_data());
 	int res = env->CallIntMethod(io,_file_open,js,p_mode_flags&WRITE?true:false);
 	env->DeleteLocalRef(js);
 
+	OS::get_singleton()->print("fopen: '%s' ret %i\n",path.utf8().get_data(),res);
+
+
 	if (res<=0)
 		return ERR_FILE_CANT_OPEN;
 	id=res;

+ 1 - 1
platform/android/java/src/com/android/godot/Godot.java

@@ -357,7 +357,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
 		        Log.d("GODOT","   " + command_line[w]);
 		    }
 		}*/
-		GodotLib.initialize(this,io.needsReloadHooks(),command_line);
+		GodotLib.initialize(this,io.needsReloadHooks(),command_line,getAssets());
 		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
 		mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
 		mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);

+ 3 - 2
platform/android/java/src/com/android/godot/GodotIO.java

@@ -94,6 +94,7 @@ public class GodotIO {
 
 		//System.out.printf("file_open: Attempt to Open %s\n",path);
 
+		//Log.v("MyApp", "TRYING TO OPEN FILE: " + path);
 		if (write)
 			return -1;
 
@@ -105,7 +106,7 @@ public class GodotIO {
 
 		} catch (Exception e) {
 
-			//System.out.printf("Exception on file_open: %s\n",e);
+			//System.out.printf("Exception on file_open: %s\n",path);
 			return -1;
 		}
 
@@ -113,7 +114,7 @@ public class GodotIO {
 			ad.len=ad.is.available();
 		} catch (Exception e) {
 
-			System.out.printf("Exception availabling on file_open: %s\n",e);
+			System.out.printf("Exception availabling on file_open: %s\n",path);
 			return -1;
 		}
 

+ 1 - 1
platform/android/java/src/com/android/godot/GodotLib.java

@@ -44,7 +44,7 @@ public class GodotLib {
      * @param height the current view height
      */
 
-     public static native void initialize(Godot p_instance,boolean need_reload_hook,String[] p_cmdline);
+     public static native void initialize(Godot p_instance,boolean need_reload_hook,String[] p_cmdline,Object p_asset_manager);
      public static native void resize(int width, int height,boolean reload);
      public static native void newcontext();
      public static native void quit();

+ 10 - 2
platform/android/java_glue.cpp

@@ -33,13 +33,14 @@
 #include "main/main.h"
 #include <unistd.h>
 #include "file_access_jandroid.h"
+#include "file_access_android.h"
 #include "dir_access_jandroid.h"
 #include "audio_driver_jandroid.h"
 #include "globals.h"
 #include "thread_jandroid.h"
 #include "core/os/keyboard.h"
 #include "java_class_wrapper.h"
-
+#include "android/asset_manager_jni.h"
 
 static JavaClassWrapper *java_class_wrapper=NULL;
 static OS_Android *os_android=NULL;
@@ -764,7 +765,7 @@ static void _stop_video() {
 	env->CallVoidMethod(godot_io, _stopVideo);
 }
 
-JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook, jobjectArray p_cmdline) {
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook, jobjectArray p_cmdline,jobject p_asset_manager) {
 
 	__android_log_print(ANDROID_LOG_INFO,"godot","**INIT EVENT! - %p\n",env);
 
@@ -820,7 +821,14 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
 		}
 
 		ThreadAndroid::make_default(jvm);
+#ifdef USE_JAVA_FILE_ACCESS
 		FileAccessJAndroid::setup(gob);
+#else
+
+		jobject amgr = env->NewGlobalRef(p_asset_manager);
+
+		FileAccessAndroid::asset_manager=AAssetManager_fromJava(env,amgr);
+#endif
 		DirAccessJAndroid::setup(gob);
 		AudioDriverAndroid::setup(gob);
 	}

+ 1 - 1
platform/android/java_glue.h

@@ -36,7 +36,7 @@
 
 
 extern "C" {
-    JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook, jobjectArray p_cmdline);
+    JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook, jobjectArray p_cmdline,jobject p_asset_manager);
     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_resize(JNIEnv * env, jobject obj,  jint width, jint height, jboolean reload);
     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_newcontext(JNIEnv * env, jobject obj);
     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_step(JNIEnv * env, jobject obj);

+ 9 - 1
platform/android/os_android.cpp

@@ -37,6 +37,8 @@
 #include "servers/visual/visual_server_wrap_mt.h"
 #include "main/main.h"
 
+#include "file_access_android.h"
+
 #include "core/globals.h"
 
 #ifdef ANDROID_NATIVE_ACTIVITY
@@ -89,8 +91,14 @@ void OS_Android::initialize_core() {
 
 	if (use_apk_expansion)
 		FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
-	else
+	else {
+#ifdef USE_JAVA_FILE_ACCESS
 		FileAccess::make_default<FileAccessBufferedFA<FileAccessJAndroid> >(FileAccess::ACCESS_RESOURCES);
+#else
+		//FileAccess::make_default<FileAccessBufferedFA<FileAccessAndroid> >(FileAccess::ACCESS_RESOURCES);
+		FileAccess::make_default<FileAccessAndroid>(FileAccess::ACCESS_RESOURCES);
+#endif
+	}
 	FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
 	FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
 	//FileAccessBufferedFA<FileAccessUnix>::make_default();

+ 3 - 0
platform/android/os_android.h

@@ -41,6 +41,9 @@
 #include "servers/visual/rasterizer.h"
 
 
+//#ifdef USE_JAVA_FILE_ACCESS
+
+
 #ifdef ANDROID_NATIVE_ACTIVITY
 
 #include <android/sensor.h>

+ 43 - 2
platform/iphone/app_delegate.mm

@@ -43,6 +43,11 @@
 #import <AdSupport/AdSupport.h>
 #endif
 
+#ifdef MODULE_PARSE_ENABLED
+#import <Parse/Parse.h>
+#import "FBSDKCoreKit/FBSDKCoreKit.h"
+#endif
+
 #define kFilteringFactor                        0.1
 #define kRenderingFrequency						60
 #define kAccelerometerFrequency         100.0 // Hz
@@ -139,8 +144,9 @@ static int frame_count = 0;
 		++frame_count;
 
 		// this might be necessary before here
-		for (NSString* key in [[NSBundle mainBundle] infoDictionary]) {
-			NSObject* value = [[[NSBundle mainBundle] infoDictionary] objectForKey:key];
+		NSDictionary* dict = [[NSBundle mainBundle] infoDictionary];
+		for (NSString* key in dict) {
+			NSObject* value = [dict objectForKey:key];
 			String ukey = String::utf8([key UTF8String]);
 
 			// we need a NSObject to Variant conversor
@@ -341,6 +347,15 @@ static int frame_count = 0;
 
 // For 4.2+ support
 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
+#ifdef MODULE_PARSE_ENABLED
+	NSLog(@"Handling application openURL");
+	return [[FBSDKApplicationDelegate sharedInstance] application:application
+														  openURL:url
+												sourceApplication:sourceApplication
+													   annotation:annotation];
+#endif
+
+
 #ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
 	return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
 #else
@@ -348,6 +363,32 @@ static int frame_count = 0;
 #endif
 }
 
+- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+#ifdef MODULE_PARSE_ENABLED
+	// Store the deviceToken in the current installation and save it to Parse.
+	PFInstallation *currentInstallation = [PFInstallation currentInstallation];
+	//NSString* token = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding];
+	NSLog(@"Device Token : %@ ", deviceToken);
+	[currentInstallation setDeviceTokenFromData:deviceToken];
+	[currentInstallation saveInBackground];
+#endif
+}
+
+- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
+#ifdef MODULE_PARSE_ENABLED
+	[PFPush handlePush:userInfo];
+	NSDictionary *aps = [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
+	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+	
+	NSLog(@"Push Notification Payload (app active) %@", aps);
+	[defaults setObject:aps forKey:@"notificationInfo"];
+	[defaults synchronize];
+	if (application.applicationState == UIApplicationStateInactive) {
+		[PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
+	}
+#endif
+}
+
 - (void)dealloc
 {
 	[window release];

+ 2 - 2
platform/iphone/detect.py

@@ -59,7 +59,7 @@ def configure(env):
 		env.Append(CPPFLAGS=['-DNEED_LONG_INT'])
 		env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON'])
 	else:
-		env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -gdwarf-2 -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=4.3 -MMD -MT dependencies -isysroot $IPHONESDK')
+		env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -gdwarf-2 -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=5.1.1 -MMD -MT dependencies -isysroot $IPHONESDK')
 
 	if (env["bits"]=="64"):
 		env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=5.1.1',
@@ -80,7 +80,7 @@ def configure(env):
 							'-framework', 'CoreMedia',
 							])
 	else:
-		env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=4.3',
+		env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=5.1.1',
 							'-isysroot', '$IPHONESDK',
 							'-framework', 'Foundation',
 							'-framework', 'UIKit',

+ 1 - 1
platform/iphone/gl_view.h

@@ -34,7 +34,7 @@
 #import <MediaPlayer/MediaPlayer.h>
 #import <AVFoundation/AVFoundation.h>
 
-#define USE_CADISPLAYLINK      1   //iOS version 3.1+ is required
+#define USE_CADISPLAYLINK      0   //iOS version 3.1+ is required
 
 @protocol GLViewDelegate;
 

+ 9 - 0
platform/iphone/in_app_store.mm

@@ -28,6 +28,10 @@
 /*************************************************************************/
 #ifdef STOREKIT_ENABLED
 
+#ifdef MODULE_FUSEBOXX_ENABLED
+#import "modules/fuseboxx/ios/FuseSDK.h"
+#endif
+
 #include "in_app_store.h"
 
 extern "C" {
@@ -222,6 +226,11 @@ Error InAppStore::request_product_info(Variant p_params) {
             else{
                 [pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier];
             }
+			
+			#ifdef MODULE_FUSEBOXX_ENABLED
+			printf("Registering transaction on Fuseboxx!\n");
+			[FuseSDK registerInAppPurchase: transaction];
+			#endif
 		} break;
 		case SKPaymentTransactionStateFailed: {
             printf("status transaction failed!\n");

+ 29 - 8
platform/osx/detect.py

@@ -11,15 +11,17 @@ def get_name():
 
 def can_build():
 
-	if (sys.platform != "darwin"):
-		return False
+	if (sys.platform == "darwin" or os.environ.has_key("OSXCROSS_ROOT")):
+		return True
 
-	return True # osx enabled
+
+	return False
 
 def get_opts():
 
 	return [
 	    ('force_64_bits','Force 64 bits binary','no'),
+	    ('osxcross_sdk','OSXCross SDK version','darwin14'),
 
 	 ]
 
@@ -59,12 +61,31 @@ def configure(env):
 		env.Append(CPPPATH=['#tools/freetype'])
 		env.Append(CPPPATH=['#tools/freetype/freetype/include'])
 
-	if (env["bits"]=="64"):
-		env.Append(CCFLAGS=['-arch', 'x86_64'])
-		env.Append(LINKFLAGS=['-arch', 'x86_64'])
+
+
+	if (not os.environ.has_key("OSXCROSS_ROOT")):
+		#regular native build
+		if (env["bits"]=="64"):
+		    env.Append(CCFLAGS=['-arch', 'x86_64'])
+		    env.Append(LINKFLAGS=['-arch', 'x86_64'])
+		else:
+		    env.Append(CCFLAGS=['-arch', 'i386'])
+		    env.Append(LINKFLAGS=['-arch', 'i386'])
 	else:
-		env.Append(CCFLAGS=['-arch', 'i386'])
-		env.Append(LINKFLAGS=['-arch', 'i386'])
+		#osxcross build
+		root=os.environ.get("OSXCROSS_ROOT",0)
+		if env["bits"]=="64":
+			basecmd=root+"/target/bin/x86_64-apple-"+env["osxcross_sdk"]+"-"
+		else:
+			basecmd=root+"/target/bin/i386-apple-"+env["osxcross_sdk"]+"-"
+
+
+		env['CC'] = basecmd+"cc"
+		env['CXX'] = basecmd+"c++"
+		env['AR'] = basecmd+"ar"
+		env['RANLIB'] = basecmd+"ranlib"
+		env['AS'] = basecmd+"as"
+
 
 #	env.Append(CPPPATH=['#platform/osx/include/freetype2', '#platform/osx/include'])
 #	env.Append(LIBPATH=['#platform/osx/lib'])

+ 1 - 1
platform/osx/os_osx.h

@@ -170,7 +170,7 @@ public:
 	virtual int get_screen_count() const;
 	virtual int get_current_screen() const;
 	virtual void set_current_screen(int p_screen);
-	virtual Point2 get_screen_position(int p_screen=0);
+	virtual Point2 get_screen_position(int p_screen=0) const;
 	virtual Point2 get_window_position() const;
 	virtual void set_window_position(const Point2& p_position);
 	virtual void set_window_size(const Size2 p_size);

+ 1 - 1
platform/osx/os_osx.mm

@@ -1279,7 +1279,7 @@ void OS_OSX::set_current_screen(int p_screen) {
 	current_screen = p_screen;
 };
 
-Point2 OS_OSX::get_screen_position(int p_screen) {
+Point2 OS_OSX::get_screen_position(int p_screen) const {
 
 	ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2());
 	return screens[p_screen].pos;

+ 3 - 1
platform/x11/detect.py

@@ -126,7 +126,9 @@ def configure(env):
 	env.ParseConfig('pkg-config x11 --cflags --libs')
 	env.ParseConfig('pkg-config xinerama --cflags --libs')
 	env.ParseConfig('pkg-config xcursor --cflags --libs')
-	env.ParseConfig('pkg-config openssl --cflags --libs')
+
+	if (env["openssl"]=="yes"):
+		env.ParseConfig('pkg-config openssl --cflags --libs')
 
 
 	env.ParseConfig('pkg-config freetype2 --cflags --libs')

+ 65 - 4
platform/x11/os_x11.cpp

@@ -441,6 +441,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
 	net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
 
 
+
 	//printf("got map notify\n");
 		
 }
@@ -504,6 +505,23 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
 	mouse_mode=p_mode;
 
 	if (mouse_mode==MOUSE_MODE_CAPTURED) {
+
+		while(true) {
+			//flush pending motion events
+
+			if (XPending(x11_display) > 0) {
+				XEvent event;
+				XPeekEvent(x11_display, &event);
+				if (event.type==MotionNotify) {
+					XNextEvent(x11_display,&event);
+				} else {
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+
 		if (XGrabPointer(x11_display, x11_window, True,
 				    ButtonPressMask | ButtonReleaseMask |
 				    PointerMotionMask, GrabModeAsync, GrabModeAsync,
@@ -518,6 +536,8 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
 			      0,0,0,0, (int)center.x, (int)center.y);
 
 		input->set_mouse_pos(center);
+	} else {
+		do_mouse_warp=false;
 	}
 }
 
@@ -652,17 +672,24 @@ void OS_X11::set_current_screen(int p_screen) {
 }
 
 Point2 OS_X11::get_screen_position(int p_screen) const {
+
 	// Using Xinerama Extension
 	int event_base, error_base;
 	const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
-	if( !ext_okay ) return Point2i(0,0);
+	if( !ext_okay ) {
+		return Point2i(0,0);
+	}
 	
 	int count;
 	XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
-	if( p_screen >= count ) return Point2i(0,0);
+	if( p_screen >= count ) {
+		return Point2i(0,0);
+	}
 	
 	Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org);
+
 	XFree(xsi);
+
 	return position;
 }
 
@@ -696,6 +723,7 @@ Point2 OS_X11::get_window_position() const {
 void OS_X11::set_window_position(const Point2& p_position) {
 	// Using EWMH -- Extended Window Manager Hints
 	// to get the size of the decoration 
+#if 0
 	Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True);
 	Atom type;
 	int format;
@@ -738,6 +766,9 @@ void OS_X11::set_window_position(const Point2& p_position) {
 	top -= screen_position.y;
 
 	XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top);
+#else
+	XMoveWindow(x11_display,x11_window,p_position.x,p_position.y);
+#endif
 }
 
 Size2 OS_X11::get_window_size() const {
@@ -1131,7 +1162,7 @@ void OS_X11::process_xevents() {
 
 	//printf("checking events %i\n", XPending(x11_display));
 
-	bool do_mouse_warp=false;
+	do_mouse_warp=false;
 
 	while (XPending(x11_display) > 0) {
 		XEvent event;
@@ -1244,8 +1275,38 @@ void OS_X11::process_xevents() {
 			
 		} break;	
 		case MotionNotify: {
-						
+
+			// FUCK YOU X11 API YOU SERIOUSLY GROSS ME OUT
+			// YOU ARE AS GROSS AS LOOKING AT A PUTRID PILE
+			// OF POOP STICKING OUT OF A CLOGGED TOILET
+			// HOW THE FUCK I AM SUPPOSED TO KNOW WHICH ONE
+			// OF THE MOTION NOTIFY EVENTS IS THE ONE GENERATED
+			// BY WARPING THE MOUSE POINTER?
+			// YOU ARE FORCING ME TO FILTER ONE BY ONE TO FIND IT
+			// PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL
+			// MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG.
+
 			
+			while(true) {
+				if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) {
+					//this is likely the warp event since it was warped here
+					center=Vector2(event.xmotion.x,event.xmotion.y);
+					break;
+				}
+
+				if (XPending(x11_display) > 0) {
+					XEvent tevent;
+					XPeekEvent(x11_display, &tevent);
+					if (tevent.type==MotionNotify) {
+						XNextEvent(x11_display,&event);
+					} else {
+						break;
+					}
+				} else {
+					break;
+				}
+			}
+
 			last_timestamp=event.xmotion.time;
 		
 			// Motion is also simple.

+ 1 - 0
platform/x11/os_x11.h

@@ -114,6 +114,7 @@ class OS_X11 : public OS_Unix {
 	bool minimized;
 	int dpad_last[2];
 
+	bool do_mouse_warp;
 
 	const char *cursor_theme;
 	int cursor_size;

+ 2 - 2
scene/2d/sprite.cpp

@@ -322,8 +322,8 @@ void Sprite::_bind_methods() {
 	ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset"));
 	ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h"));
 	ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v"));
-	ADD_PROPERTYNO( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes"));
-	ADD_PROPERTYNO( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes"));
+	ADD_PROPERTYNO( PropertyInfo( Variant::INT, "vframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_vframes"),_SCS("get_vframes"));
+	ADD_PROPERTYNO( PropertyInfo( Variant::INT, "hframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_hframes"),_SCS("get_hframes"));
 	ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame"));
 	ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate"));
 	ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region"));

+ 24 - 9
scene/3d/area.cpp

@@ -83,15 +83,25 @@ real_t Area::get_gravity() const{
 
 	return gravity;
 }
+void Area::set_linear_damp(real_t p_linear_damp){
 
-void Area::set_density(real_t p_density){
+	linear_damp=p_linear_damp;
+	PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_LINEAR_DAMP,p_linear_damp);
+}
+real_t Area::get_linear_damp() const{
+
+	return linear_damp;
+}
 
-	density=p_density;
-	PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_DENSITY,p_density);
+void Area::set_angular_damp(real_t p_angular_damp){
+
+	angular_damp=p_angular_damp;
+	PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_ANGULAR_DAMP,p_angular_damp);
 }
-real_t Area::get_density() const{
 
-	return density;
+real_t Area::get_angular_damp() const{
+
+	return angular_damp;
 }
 
 void Area::set_priority(real_t p_priority){
@@ -533,8 +543,11 @@ void Area::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_gravity","gravity"),&Area::set_gravity);
 	ObjectTypeDB::bind_method(_MD("get_gravity"),&Area::get_gravity);
 
-	ObjectTypeDB::bind_method(_MD("set_density","density"),&Area::set_density);
-	ObjectTypeDB::bind_method(_MD("get_density"),&Area::get_density);
+	ObjectTypeDB::bind_method(_MD("set_angular_damp","angular_damp"),&Area::set_angular_damp);
+	ObjectTypeDB::bind_method(_MD("get_angular_damp"),&Area::get_angular_damp);
+
+	ObjectTypeDB::bind_method(_MD("set_linear_damp","linear_damp"),&Area::set_linear_damp);
+	ObjectTypeDB::bind_method(_MD("get_linear_damp"),&Area::get_linear_damp);
 
 	ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
 	ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
@@ -571,7 +584,8 @@ void Area::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
 	ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector"));
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity"));
-	ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density"));
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"linear_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_linear_damp"),_SCS("get_linear_damp"));
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"angular_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_angular_damp"),_SCS("get_angular_damp"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
@@ -586,7 +600,8 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
 	set_gravity_vector(Vector3(0,-1,0));
 	gravity_is_point=false;
 	gravity_distance_scale=0;
-	density=0.1;
+	linear_damp=0.1;
+	angular_damp=1;
 	priority=0;
 	monitoring=false;
 	set_ray_pickable(false);

+ 7 - 3
scene/3d/area.h

@@ -50,7 +50,8 @@ private:
 	real_t gravity;
 	bool gravity_is_point;
 	real_t gravity_distance_scale;
-	real_t density;
+	real_t angular_damp;
+	real_t linear_damp;
 	int priority;
 	bool monitoring;
 	bool monitorable;
@@ -139,8 +140,11 @@ public:
 	void set_gravity(real_t p_gravity);
 	real_t get_gravity() const;
 
-	void set_density(real_t p_density);
-	real_t get_density() const;
+	void set_angular_damp(real_t p_angular_damp);
+	real_t get_angular_damp() const;
+
+	void set_linear_damp(real_t p_linear_damp);
+	real_t get_linear_damp() const;
 
 	void set_priority(real_t p_priority);
 	real_t get_priority() const;

+ 55 - 0
scene/3d/physics_body.cpp

@@ -133,6 +133,8 @@ real_t StaticBody::get_bounce() const{
 	return bounce;
 }
 
+
+
 void StaticBody::set_constant_linear_velocity(const Vector3& p_vel) {
 
 	constant_linear_velocity=p_vel;
@@ -494,6 +496,42 @@ real_t RigidBody::get_bounce() const{
 	return bounce;
 }
 
+
+void RigidBody::set_gravity_scale(real_t p_gravity_scale){
+
+	gravity_scale=p_gravity_scale;
+	PhysicsServer::get_singleton()->body_set_param(get_rid(),PhysicsServer::BODY_PARAM_GRAVITY_SCALE,gravity_scale);
+
+}
+real_t RigidBody::get_gravity_scale() const{
+
+	return gravity_scale;
+}
+
+void RigidBody::set_linear_damp(real_t p_linear_damp){
+
+	ERR_FAIL_COND(p_linear_damp<-1);
+	linear_damp=p_linear_damp;
+	PhysicsServer::get_singleton()->body_set_param(get_rid(),PhysicsServer::BODY_PARAM_LINEAR_DAMP,linear_damp);
+
+}
+real_t RigidBody::get_linear_damp() const{
+
+	return linear_damp;
+}
+
+void RigidBody::set_angular_damp(real_t p_angular_damp){
+
+	ERR_FAIL_COND(p_angular_damp<-1);
+	angular_damp=p_angular_damp;
+	PhysicsServer::get_singleton()->body_set_param(get_rid(),PhysicsServer::BODY_PARAM_ANGULAR_DAMP,angular_damp);
+
+}
+real_t RigidBody::get_angular_damp() const{
+
+	return angular_damp;
+}
+
 void RigidBody::set_axis_velocity(const Vector3& p_axis) {
 
 	Vector3 v = state? state->get_linear_velocity() : linear_velocity;
@@ -685,6 +723,16 @@ void RigidBody::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_angular_velocity","angular_velocity"),&RigidBody::set_angular_velocity);
 	ObjectTypeDB::bind_method(_MD("get_angular_velocity"),&RigidBody::get_angular_velocity);
 
+	ObjectTypeDB::bind_method(_MD("set_gravity_scale","gravity_scale"),&RigidBody::set_gravity_scale);
+	ObjectTypeDB::bind_method(_MD("get_gravity_scale"),&RigidBody::get_gravity_scale);
+
+	ObjectTypeDB::bind_method(_MD("set_linear_damp","linear_damp"),&RigidBody::set_linear_damp);
+	ObjectTypeDB::bind_method(_MD("get_linear_damp"),&RigidBody::get_linear_damp);
+
+	ObjectTypeDB::bind_method(_MD("set_angular_damp","angular_damp"),&RigidBody::set_angular_damp);
+	ObjectTypeDB::bind_method(_MD("get_angular_damp"),&RigidBody::get_angular_damp);
+
+
 	ObjectTypeDB::bind_method(_MD("set_max_contacts_reported","amount"),&RigidBody::set_max_contacts_reported);
 	ObjectTypeDB::bind_method(_MD("get_max_contacts_reported"),&RigidBody::get_max_contacts_reported);
 
@@ -722,6 +770,7 @@ void RigidBody::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"weight",PROPERTY_HINT_EXP_RANGE,"0.01,65535,0.01",PROPERTY_USAGE_EDITOR),_SCS("set_weight"),_SCS("get_weight"));
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_friction"),_SCS("get_friction"));
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_bounce"),_SCS("get_bounce"));
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_scale",PROPERTY_HINT_RANGE,"-128,128,0.01"),_SCS("set_gravity_scale"),_SCS("get_gravity_scale"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"custom_integrator"),_SCS("set_use_custom_integrator"),_SCS("is_using_custom_integrator"));
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"continuous_cd"),_SCS("set_use_continuous_collision_detection"),_SCS("is_using_continuous_collision_detection"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"contacts_reported"),_SCS("set_max_contacts_reported"),_SCS("get_max_contacts_reported"));
@@ -731,6 +780,8 @@ void RigidBody::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"axis_lock",PROPERTY_HINT_ENUM,"Disabled,Lock X,Lock Y,Lock Z"),_SCS("set_axis_lock"),_SCS("get_axis_lock"));
 	ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity"));
 	ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/angular"),_SCS("set_angular_velocity"),_SCS("get_angular_velocity"));
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"damp_override/linear",PROPERTY_HINT_RANGE,"-1,128,0.01"),_SCS("set_linear_damp"),_SCS("get_linear_damp"));
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"damp_override/angular",PROPERTY_HINT_RANGE,"-1,128,0.01"),_SCS("set_angular_damp"),_SCS("get_angular_damp"));
 
 	ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape")));
 	ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape")));
@@ -753,6 +804,10 @@ RigidBody::RigidBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
 	max_contacts_reported=0;
 	state=NULL;
 
+	gravity_scale=1;
+	linear_damp=-1;
+	angular_damp=-1;
+
 	//angular_velocity=0;
 	sleeping=false;
 	ccd=false;

+ 14 - 0
scene/3d/physics_body.h

@@ -129,6 +129,10 @@ private:
 
 	Vector3 linear_velocity;
 	Vector3  angular_velocity;
+	real_t gravity_scale;
+	real_t linear_damp;
+	real_t angular_damp;
+
 	bool sleeping;
 	bool ccd;
 
@@ -217,6 +221,16 @@ public:
 	void set_angular_velocity(const Vector3&p_velocity);
 	Vector3  get_angular_velocity() const;
 
+	void set_gravity_scale(real_t p_gravity_scale);
+	real_t get_gravity_scale() const;
+
+	void set_linear_damp(real_t p_linear_damp);
+	real_t get_linear_damp() const;
+
+	void set_angular_damp(real_t p_angular_damp);
+	real_t get_angular_damp() const;
+
+
 	void set_use_custom_integrator(bool p_enable);
 	bool is_using_custom_integrator();
 

+ 2 - 2
scene/3d/sprite_3d.cpp

@@ -578,8 +578,8 @@ void Sprite3D::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_hframes"),&Sprite3D::get_hframes);
 
 	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture"));
-	ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes"));
-	ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes"));
+	ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_vframes"),_SCS("get_vframes"));
+	ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes",PROPERTY_HINT_RANGE,"1,16384,1"), _SCS("set_hframes"),_SCS("get_hframes"));
 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame"));
 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region"));
 	ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect"));

+ 1 - 1
scene/gui/dialogs.cpp

@@ -274,7 +274,7 @@ Button* AcceptDialog::add_button(const String& p_text,bool p_right,const String&
 	}
 
 	if (p_action!="") {
-		button->connect("pressed",this,"_custom_action",make_binds(p_action));
+		button->connect("pressed",this,"_custom_action",varray(p_action));
 	}
 
 	return button;

+ 25 - 12
scene/gui/item_list.cpp

@@ -187,6 +187,7 @@ void ItemList::select(int p_idx,bool p_single){
 		}
 
 		current=p_idx;
+		ensure_selected_visible=false;
 	} else {
 
 		if (items[p_idx].selectable) {
@@ -195,6 +196,7 @@ void ItemList::select(int p_idx,bool p_single){
 	}
 	update();
 
+
 }
 void ItemList::unselect(int p_idx){
 
@@ -246,12 +248,14 @@ void ItemList::remove_item(int p_idx){
 	update();
 	shape_changed=true;
 
+
 }
 
 void ItemList::clear(){
 
 	items.clear();
 	current=-1;
+	ensure_selected_visible=false;
 	update();
 
 }
@@ -602,18 +606,8 @@ void ItemList::_input_event(const InputEvent& p_event) {
 
 void ItemList::ensure_current_is_visible() {
 
-	if (current>=0 && current <=items.size()) {
-
-		Rect2 r = items[current].rect_cache;
-		int from = scroll_bar->get_val();
-		int to = from + scroll_bar->get_page();
-
-		if (r.pos.y < from) {
-			scroll_bar->set_val(r.pos.y);
-		} else if (r.pos.y+r.size.y > to) {
-			scroll_bar->set_val(r.pos.y+r.size.y - (to-from));
-		}
-	}
+	ensure_selected_visible=true;
+	update();
 }
 
 void ItemList::_notification(int p_what) {
@@ -928,6 +922,24 @@ void ItemList::_notification(int p_what) {
 			draw_line(Vector2(bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),Vector2(size.width-bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),guide_color);
 		}
 
+
+		if (ensure_selected_visible && current>=0 && current <=items.size()) {
+
+			Rect2 r = items[current].rect_cache;
+			int from = scroll_bar->get_val();
+			int to = from + scroll_bar->get_page();
+
+			if (r.pos.y < from) {
+				scroll_bar->set_val(r.pos.y);
+			} else if (r.pos.y+r.size.y > to) {
+				scroll_bar->set_val(r.pos.y+r.size.y - (to-from));
+			}
+
+
+		}
+
+		ensure_selected_visible=false;
+
 	}
 }
 
@@ -1095,6 +1107,7 @@ ItemList::ItemList() {
 	set_focus_mode(FOCUS_ALL);
 	current_columns=1;
 	search_time_msec=0;
+	ensure_selected_visible=false;
 
 }
 

+ 2 - 0
scene/gui/item_list.h

@@ -41,6 +41,8 @@ private:
 
 	bool shape_changed;
 
+	bool ensure_selected_visible;
+
 	Vector<Item> items;
 	Vector<int> separators;
 

+ 1 - 1
scene/gui/menu_button.cpp

@@ -124,7 +124,7 @@ void MenuButton::_set_items(const Array& p_items) {
 
 void MenuButton::_bind_methods() {
 
-	ObjectTypeDB::bind_method(_MD("get_popup"),&MenuButton::get_popup);		
+	ObjectTypeDB::bind_method(_MD("get_popup:PopupMenu"),&MenuButton::get_popup);
 	ObjectTypeDB::bind_method(_MD("_unhandled_key_input"),&MenuButton::_unhandled_key_input);
 	ObjectTypeDB::bind_method(_MD("_set_items"),&MenuButton::_set_items);
 	ObjectTypeDB::bind_method(_MD("_get_items"),&MenuButton::_get_items);

+ 132 - 0
scene/gui/patch_9_frame.cpp

@@ -0,0 +1,132 @@
+#include "patch_9_frame.h"
+
+#include "servers/visual_server.h"
+
+void Patch9Frame::_notification(int p_what) {
+
+	if (p_what==NOTIFICATION_DRAW) {
+
+		if (texture.is_null())
+			return;
+
+
+		Size2 s=get_size();
+		RID ci = get_canvas_item();
+		VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate);
+//		draw_texture_rect(texture,Rect2(Point2(),s),false,modulate);
+
+/*
+		Vector<Point2> points;
+		points.resize(4);
+		points[0]=Point2(0,0);
+		points[1]=Point2(s.x,0);
+		points[2]=Point2(s.x,s.y);
+		points[3]=Point2(0,s.y);
+		Vector<Point2> uvs;
+		uvs.resize(4);
+		uvs[0]=Point2(0,0);
+		uvs[1]=Point2(1,0);
+		uvs[2]=Point2(1,1);
+		uvs[3]=Point2(0,1);
+
+		VisualServer::get_singleton()->canvas_item_add_primitive(ci,points,Vector<Color>(),uvs,texture->get_rid());
+*/
+	}
+}
+
+Size2 Patch9Frame::get_minimum_size() const {
+
+	return Size2(margin[MARGIN_LEFT]+margin[MARGIN_RIGHT],margin[MARGIN_TOP]+margin[MARGIN_BOTTOM]);
+}
+void Patch9Frame::_bind_methods() {
+
+
+	ObjectTypeDB::bind_method(_MD("set_texture","texture"), & Patch9Frame::set_texture );
+	ObjectTypeDB::bind_method(_MD("get_texture"), & Patch9Frame::get_texture );
+	ObjectTypeDB::bind_method(_MD("set_modulate","modulate"), & Patch9Frame::set_modulate );
+	ObjectTypeDB::bind_method(_MD("get_modulate"), & Patch9Frame::get_modulate );
+	ObjectTypeDB::bind_method(_MD("set_patch_margin","margin","value"), & Patch9Frame::set_patch_margin );
+	ObjectTypeDB::bind_method(_MD("get_patch_margin","margin"), & Patch9Frame::get_patch_margin );
+	ObjectTypeDB::bind_method(_MD("set_draw_center","draw_center"), & Patch9Frame::set_draw_center );
+	ObjectTypeDB::bind_method(_MD("get_draw_center"), & Patch9Frame::get_draw_center );
+
+	ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"),_SCS("get_texture") );
+	ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate") );
+	ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "draw_center"), _SCS("set_draw_center"),_SCS("get_draw_center") );
+	ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/left",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_LEFT );
+	ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/top",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_TOP );
+	ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/right",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_RIGHT );
+	ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/bottom",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_BOTTOM );
+
+}
+
+
+void Patch9Frame::set_texture(const Ref<Texture>& p_tex) {
+
+	texture=p_tex;
+	update();
+	//if (texture.is_valid())
+	//	texture->set_flags(texture->get_flags()&(~Texture::FLAG_REPEAT)); //remove repeat from texture, it looks bad in sprites
+	minimum_size_changed();
+}
+
+Ref<Texture> Patch9Frame::get_texture() const {
+
+	return texture;
+}
+
+void Patch9Frame::set_modulate(const Color& p_tex) {
+
+	modulate=p_tex;
+	update();
+}
+
+Color Patch9Frame::get_modulate() const{
+
+	return modulate;
+}
+
+
+void Patch9Frame::set_patch_margin(Margin p_margin,int p_size) {
+
+	ERR_FAIL_INDEX(p_margin,4);
+	margin[p_margin]=p_size;
+	update();
+	minimum_size_changed();
+}
+
+int Patch9Frame::get_patch_margin(Margin p_margin) const{
+
+	ERR_FAIL_INDEX_V(p_margin,4,0);
+	return margin[p_margin];
+}
+
+void Patch9Frame::set_draw_center(bool p_draw) {
+
+	draw_center=p_draw;
+	update();
+}
+
+bool Patch9Frame::get_draw_center() const{
+
+	return draw_center;
+}
+
+Patch9Frame::Patch9Frame() {
+
+
+	margin[MARGIN_LEFT]=0;
+	margin[MARGIN_RIGHT]=0;
+	margin[MARGIN_BOTTOM]=0;
+	margin[MARGIN_TOP]=0;
+	modulate=Color(1,1,1,1);
+	set_ignore_mouse(true);
+	draw_center=true;
+}
+
+
+Patch9Frame::~Patch9Frame()
+{
+}
+
+

+ 40 - 0
scene/gui/patch_9_frame.h

@@ -0,0 +1,40 @@
+#ifndef PATCH_9_FRAME_H
+#define PATCH_9_FRAME_H
+
+#include "scene/gui/control.h"
+/**
+	@author Juan Linietsky <[email protected]>
+*/
+class Patch9Frame : public Control {
+
+	OBJ_TYPE(Patch9Frame,Control);
+
+	bool draw_center;
+	int margin[4];
+	Color modulate;
+	Ref<Texture> texture;
+protected:
+
+	void _notification(int p_what);
+	virtual Size2 get_minimum_size() const;
+	static void _bind_methods();
+
+public:
+
+	void set_texture(const Ref<Texture>& p_tex);
+	Ref<Texture> get_texture() const;
+
+	void set_modulate(const Color& p_tex);
+	Color get_modulate() const;
+
+	void set_patch_margin(Margin p_margin,int p_size);
+	int get_patch_margin(Margin p_margin) const;
+
+	void set_draw_center(bool p_enable);
+	bool get_draw_center() const;
+
+	Patch9Frame();
+	~Patch9Frame();
+
+};
+#endif // PATCH_9_FRAME_H

+ 53 - 1
scene/gui/spin_box.cpp

@@ -27,7 +27,7 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
 #include "spin_box.h"
-
+#include "os/input.h"
 
 Size2 SpinBox::get_minimum_size() const {
 
@@ -62,6 +62,13 @@ LineEdit *SpinBox::get_line_edit() {
 }
 
 
+void SpinBox::_line_edit_input(const InputEvent& p_event) {
+
+
+
+}
+
+
 void SpinBox::_input_event(const InputEvent& p_event) {
 
 	if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed) {
@@ -94,6 +101,48 @@ void SpinBox::_input_event(const InputEvent& p_event) {
 			} break;
 		}
 	}
+
+	if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
+
+		//set_default_cursor_shape(CURSOR_VSIZE);
+		Vector2 cpos = Vector2(p_event.mouse_button.x,p_event.mouse_button.y);
+		drag.mouse_pos=cpos;
+	}
+
+	if (p_event.type==InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index==1) {
+
+		//set_default_cursor_shape(CURSOR_ARROW);
+		if (drag.enabled) {
+			drag.enabled=false;
+			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+			warp_mouse(drag.capture_pos);
+		}
+	}
+
+	if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_button.button_mask&1) {
+
+		Vector2 cpos = Vector2(p_event.mouse_motion.x,p_event.mouse_motion.y);
+		if (drag.enabled) {
+
+			float diff_y = drag.mouse_pos.y - cpos.y;
+			diff_y=Math::pow(ABS(diff_y),1.8)*SGN(diff_y);
+			diff_y*=0.1;
+
+			drag.mouse_pos=cpos;
+			drag.base_val=CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max());
+
+			set_val( drag.base_val);
+
+		} else if (drag.mouse_pos.distance_to(cpos)>2) {
+
+			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+			drag.enabled=true;
+			drag.base_val=get_val();
+			drag.mouse_pos=cpos;
+			drag.capture_pos=cpos;
+
+		}
+	}
 }
 
 
@@ -177,6 +226,7 @@ void SpinBox::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("is_editable"),&SpinBox::is_editable);
 	ObjectTypeDB::bind_method(_MD("_line_edit_focus_exit"),&SpinBox::_line_edit_focus_exit);
 	ObjectTypeDB::bind_method(_MD("get_line_edit"),&SpinBox::get_line_edit);
+	ObjectTypeDB::bind_method(_MD("_line_edit_input"),&SpinBox::_line_edit_input);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL,"editable"),_SCS("set_editable"),_SCS("is_editable"));
@@ -196,4 +246,6 @@ SpinBox::SpinBox() {
 	//connect("value_changed",this,"_value_changed");
 	line_edit->connect("text_entered",this,"_text_entered",Vector<Variant>(),CONNECT_DEFERRED);
 	line_edit->connect("focus_exit",this,"_line_edit_focus_exit",Vector<Variant>(),CONNECT_DEFERRED);
+	line_edit->connect("input_event",this,"_line_edit_input");
+	drag.enabled=false;
 }

+ 12 - 0
scene/gui/spin_box.h

@@ -44,6 +44,18 @@ class SpinBox : public Range {
 	String prefix;
 	String suffix;
 
+	void _line_edit_input(const InputEvent& p_event);
+
+
+	struct Drag {
+		float base_val;
+		bool enabled;
+		Vector2 from;
+		Vector2	mouse_pos;
+		Vector2 capture_pos;
+	} drag;
+
+
 	void _line_edit_focus_exit();
 
 protected:

+ 85 - 28
scene/gui/tree.cpp

@@ -31,7 +31,7 @@
 #include "os/os.h"
 #include "os/keyboard.h"
 #include "globals.h"
-
+#include "os/input.h"
 
 
 
@@ -70,6 +70,7 @@ Size2 TreeItem::Cell::get_icon_size() const {
 	else
 		return icon_region.size;
 }
+
 void TreeItem::Cell::draw_icon(const RID& p_where, const Point2& p_pos, const Size2& p_size) const{
 
 	if (icon.is_null())
@@ -728,14 +729,20 @@ TreeItem::~TreeItem() {
 		tree->root=0;
 	}
 
-	if (tree && tree->popup_edited_item==this)
+	if (tree && tree->popup_edited_item==this) {
 		tree->popup_edited_item=NULL;
+		tree->pressing_for_editor=false;
+
+	}
 
 	if (tree && tree->selected_item==this)
 		tree->selected_item=NULL;
 
-	if (tree && tree->edited_item==this)
+	if (tree && tree->edited_item==this) {
 		tree->edited_item=NULL;
+		tree->pressing_for_editor=false;
+	}
+
 
 }
 
@@ -1292,7 +1299,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col
 	
 		} else if (select_mode==SELECT_SINGLE || select_mode==SELECT_MULTI) {
 	
-			if (&selected_cell==&c) {
+			if (!r_in_range && &selected_cell==&c) {
 		
 
 				if (!selected_cell.selected) {
@@ -1301,6 +1308,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col
 					
 					selected_item=p_selected;
 					selected_col=i;
+
 					emit_signal("cell_selected");
 					if (select_mode==SELECT_MULTI)
 						emit_signal("multi_selected",p_current,i,true);
@@ -1317,6 +1325,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col
 
 				if (r_in_range && *r_in_range) {
 
+
 					if (!c.selected && c.selectable) {
 						c.selected=true;
 						emit_signal("multi_selected",p_current,i,true);
@@ -1467,7 +1476,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
 					if (select_mode==SELECT_MULTI && p_mod.shift && selected_item && selected_item!=p_item) {
 
 						bool inrange=false;
-						print_line("SELECT MULTI AND SHIFT AND ALL");
+
 						select_single_item( p_item, root, col,selected_item,&inrange );
 					} else {
 						select_single_item( p_item, root, col );
@@ -1490,7 +1499,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
 
 		/* editing */
 
-		bool bring_up_editor=c.selected && already_selected;
+		bool bring_up_editor=c.selected;// && already_selected;
 		bool bring_up_value_editor=false;
 		String editor_text=c.text;
 
@@ -1605,31 +1614,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_
 			return -1;
 
 
-		click_handled=true;
+
+		click_handled=true;		
 		popup_edited_item=p_item;
 		popup_edited_item_col=col;
-		text_editor->set_pos(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset );
-		text_editor->set_size( Size2(col_width,item_h));
-		text_editor->clear();
-		text_editor->set_text( editor_text );
-		text_editor->select_all();
 
-		if (bring_up_value_editor) {
-
-			value_editor->set_pos(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset+Point2i(0,text_editor->get_size().height) );
-			value_editor->set_size( Size2(col_width,1));
-			value_editor->show_modal();
-			updating_value_editor=true;
-			value_editor->set_min( c.min );
-			value_editor->set_max( c.max );
-			value_editor->set_step( c.step );
-			value_editor->set_val( c.val );
-			value_editor->set_exp_unit_value( c.expr );
-			updating_value_editor=false;
-		}
-
-		text_editor->show_modal();
-		text_editor->grab_focus();
+		pressing_item_rect=Rect2(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs)-cache.offset,Size2(col_width,item_h));
+		pressing_for_editor_text=editor_text;
+		pressing_for_editor=true;
 
 		return -1; //select
 	} else {
@@ -2062,6 +2054,33 @@ void Tree::_input_event(InputEvent p_event) {
 				update();
 			}
 
+			if (pressing_for_editor && popup_edited_item && popup_edited_item->get_cell_mode(popup_edited_item_col)==TreeItem::CELL_MODE_RANGE) {
+				//range drag
+
+				if (!range_drag_enabled) {
+
+					Vector2 cpos = Vector2(b.x,b.y);
+					if (cpos.distance_to(pressing_pos)>2) {
+						range_drag_enabled=true;
+						range_drag_capture_pos=cpos;
+						range_drag_base=popup_edited_item->get_range(popup_edited_item_col);
+						Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+					}
+				} else {
+
+					TreeItem::Cell &c=popup_edited_item->cells[popup_edited_item_col];
+					float diff_y = -b.relative_y;
+					diff_y=Math::pow(ABS(diff_y),1.8)*SGN(diff_y);
+					diff_y*=0.1;
+					range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
+
+					popup_edited_item->set_range(popup_edited_item_col,range_drag_base);
+					item_edited(popup_edited_item_col,popup_edited_item);
+
+				}
+
+			}
+
 			if (drag_touching && ! drag_touching_deaccel) {
 
 
@@ -2084,6 +2103,31 @@ void Tree::_input_event(InputEvent p_event) {
 
 				if (b.button_index==BUTTON_LEFT) {
 
+					if (pressing_for_editor) {
+
+						if (range_drag_enabled) {
+
+							range_drag_enabled=false;
+							Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+							warp_mouse(range_drag_capture_pos);
+						} else {
+							text_editor->set_pos(pressing_item_rect.pos);
+							text_editor->set_size(pressing_item_rect.size);
+
+							text_editor->clear();
+							text_editor->set_text( pressing_for_editor_text );
+							text_editor->select_all();
+
+							text_editor->show_modal();
+							text_editor->grab_focus();
+
+						}
+						pressing_for_editor=false;
+
+					}
+
+
+
 					if (cache.click_type==Cache::CLICK_BUTTON) {
 						emit_signal("button_pressed",cache.click_item,cache.click_column,cache.click_id);
 
@@ -2145,11 +2189,15 @@ void Tree::_input_event(InputEvent p_event) {
 						break;
 
 					click_handled=false;
+					pressing_for_editor=false;
 
 					blocked++;
 					bool handled = propagate_mouse_event(pos+cache.offset,0,0,b.doubleclick,root,b.button_index,b.mod);
 					blocked--;
 
+					if (pressing_for_editor) {
+						pressing_pos=Point2(b.x,b.y);
+					}
 
 
 					if (drag_touching) {
@@ -2360,6 +2408,11 @@ void Tree::_notification(int p_what) {
 		}
 	}
 
+	if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
+
+		drag_touching=false;
+	}
+
 	if (p_what==NOTIFICATION_ENTER_TREE) {
 
 		update_cache();;
@@ -2610,6 +2663,8 @@ void Tree::clear() {
 	selected_item=NULL;
 	edited_item=NULL;
 	popup_edited_item=NULL;
+	selected_item=NULL;
+	pressing_for_editor=false;
 
 	update();
 };
@@ -3184,6 +3239,8 @@ Tree::Tree() {
 	drag_speed=0;
 	drag_touching=false;
 	drag_touching_deaccel=false;
+	pressing_for_editor=false;
+	range_drag_enabled=false;
 
 }
 

+ 11 - 0
scene/gui/tree.h

@@ -258,7 +258,18 @@ friend class TreeItem;
 	TreeItem *popup_edited_item;
 	TreeItem *selected_item;
 	TreeItem *edited_item;
+
+
 	int pressed_button;
+	bool pressing_for_editor;
+	String pressing_for_editor_text;
+	Vector2 pressing_pos;
+	Rect2 pressing_item_rect;
+
+	float range_drag_base;
+	bool range_drag_enabled;
+	Vector2 range_drag_capture_pos;
+
 
 	//TreeItem *cursor_item;
 	//int cursor_column;

+ 11 - 2
scene/io/resource_format_image.cpp

@@ -31,9 +31,11 @@
 #include "io/image_loader.h"
 #include "globals.h"
 #include "os/os.h"
-RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_original_path) {
-	
+RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_original_path, Error *r_error) {
 	
+	if (r_error)
+		*r_error=ERR_CANT_OPEN;
+
 	if (p_path.extension()=="cube") {
 		// open as cubemap txture
 
@@ -83,6 +85,8 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
 		memdelete(f);
 
 		cubemap->set_name(p_path.get_file());
+		if (r_error)
+			*r_error=OK;
 
 		return cubemap;
 	
@@ -112,6 +116,8 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
 
 		ERR_EXPLAIN("Failed loading image: "+p_path);
 		ERR_FAIL_COND_V(err, RES());		
+		if (r_error)
+			*r_error=ERR_FILE_CORRUPT;
 
 #ifdef DEBUG_ENABLED
 #ifdef TOOLS_ENABLED
@@ -199,6 +205,9 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
 			print_line("  -make texture: "+rtos(total));
 		}
 
+		if (r_error)
+			*r_error=OK;
+
 		return RES( texture );
 	}
 	

+ 1 - 1
scene/io/resource_format_image.h

@@ -40,7 +40,7 @@ class ResourceFormatLoaderImage : public ResourceFormatLoader {
 	int max_texture_size;
 public:
 
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 9 - 1
scene/io/resource_format_wav.cpp

@@ -31,13 +31,18 @@
 #include "scene/resources/sample.h"
 
 
-RES ResourceFormatLoaderWAV::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderWAV::load(const String &p_path, const String& p_original_path, Error *r_error) {
+	if (r_error)
+		*r_error=ERR_FILE_CANT_OPEN;
 
 	Error err;
 	FileAccess *file=FileAccess::open(p_path, FileAccess::READ,&err);
 
 	ERR_FAIL_COND_V( err!=OK, RES() );
 
+	if (r_error)
+		*r_error=ERR_FILE_CORRUPT;
+
 	/* CHECK RIFF */
 	char riff[5];
 	riff[4]=0;
@@ -244,6 +249,9 @@ RES ResourceFormatLoaderWAV::load(const String &p_path,const String& p_original_
 	file->close();
 	memdelete(file);
 
+	if (r_error)
+		*r_error=OK;
+
 	return sample;
 
 }

+ 1 - 1
scene/io/resource_format_wav.h

@@ -33,7 +33,7 @@
 
 class ResourceFormatLoaderWAV : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 2 - 0
scene/register_scene_types.cpp

@@ -52,6 +52,7 @@
 #include "scene/gui/option_button.h"
 #include "scene/gui/color_picker.h"
 #include "scene/gui/texture_frame.h"
+#include "scene/gui/patch_9_frame.h"
 #include "scene/gui/menu_button.h"
 #include "scene/gui/check_box.h"
 #include "scene/gui/check_button.h"
@@ -302,6 +303,7 @@ void register_scene_types() {
 	OS::get_singleton()->yield(); //may take time to init
 
 	ObjectTypeDB::register_type<TextureFrame>();
+	ObjectTypeDB::register_type<Patch9Frame>();
 	ObjectTypeDB::register_type<TabContainer>();
 	ObjectTypeDB::register_type<Tabs>();
 	ObjectTypeDB::register_virtual_type<Separator>();

+ 6 - 1
scene/resources/bit_mask.cpp

@@ -205,7 +205,10 @@ BitMap::BitMap() {
 //////////////////////////////////////
 
 
-RES ResourceFormatLoaderBitMap::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderBitMap::load(const String &p_path, const String& p_original_path, Error *r_error) {
+
+	if (r_error)
+		*r_error=ERR_FILE_CANT_OPEN;
 
 	BitMap* ptr = memnew(BitMap);
 	Ref<BitMap> bitmap( ptr );
@@ -219,6 +222,8 @@ RES ResourceFormatLoaderBitMap::load(const String &p_path,const String& p_origin
 	ERR_FAIL_COND_V(err, RES());
 
 	bitmap->create_from_image_alpha(image);
+	if (r_error)
+		*r_error=OK;
 
 	return bitmap;
 

+ 1 - 1
scene/resources/bit_mask.h

@@ -66,7 +66,7 @@ class ResourceFormatLoaderBitMap : public ResourceFormatLoader {
 
 public:
 
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

+ 1 - 1
scene/resources/default_theme/default_theme.cpp

@@ -297,7 +297,7 @@ void make_default_theme() {
 	t->set_color("font_color_hover","MenuButton", control_font_color_hover );
 	t->set_color("font_color_disabled","MenuButton", Color(1,1,1,0.3) );
 
-	t->set_constant("hseparation","MenuButton", 0 );
+	t->set_constant("hseparation","MenuButton", 3 );
 
     // CheckBox
 

+ 8 - 1
scene/resources/shader.cpp

@@ -219,7 +219,10 @@ Shader::~Shader() {
 
 
 
-RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_original_path) {
+RES ResourceFormatLoaderShader::load(const String &p_path, const String& p_original_path, Error *r_error) {
+
+	if (r_error)
+		*r_error=ERR_FILE_CANT_OPEN;
 
 	String fragment_code;
 	String vertex_code;
@@ -235,6 +238,8 @@ RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_origin
 	ERR_FAIL_COND_V(err,RES());
 	String base_path = p_path.get_base_dir();
 
+	if (r_error)
+		*r_error=ERR_FILE_CORRUPT;
 
 	Ref<Shader> shader;//( memnew( Shader ) );
 
@@ -435,6 +440,8 @@ RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_origin
 
 	f->close();
 	memdelete(f);
+	if (r_error)
+		*r_error=OK;
 
 	return shader;
 }

+ 1 - 1
scene/resources/shader.h

@@ -126,7 +126,7 @@ public:
 
 class ResourceFormatLoaderShader : public ResourceFormatLoader {
 public:
-	virtual RES load(const String &p_path,const String& p_original_path="");
+	virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual bool handles_type(const String& p_type) const;
 	virtual String get_resource_type(const String &p_path) const;

部分文件因文件數量過多而無法顯示