Browse Source

Merge branch 'master' into BBCodeDocs

Ovnuniarchos 9 years ago
parent
commit
a9a330645b
100 changed files with 1480 additions and 577 deletions
  1. 1 2
      README.md
  2. 26 25
      SConstruct
  3. 0 2
      bin/tests/SCsub
  4. 0 2
      core/SCsub
  5. 0 2
      core/bind/SCsub
  6. 33 0
      core/image.cpp
  7. 3 0
      core/image.h
  8. 0 2
      core/io/SCsub
  9. 6 6
      core/io/json.cpp
  10. 4 1
      core/io/marshalls.cpp
  11. 1 2
      core/io/packet_peer.cpp
  12. 3 2
      core/io/resource_format_binary.cpp
  13. 2 2
      core/io/resource_format_xml.cpp
  14. 0 2
      core/math/SCsub
  15. 1 1
      core/math/quat.h
  16. 0 2
      core/os/SCsub
  17. 9 2
      core/os/os.cpp
  18. 4 4
      core/ring_buffer.h
  19. 30 0
      core/script_debugger_remote.cpp
  20. 18 0
      core/script_debugger_remote.h
  21. 2 0
      core/variant_call.cpp
  22. 16 2
      core/variant_op.cpp
  23. 1 0
      demos/2d/area_input/engine.cfg
  24. BIN
      demos/2d/area_input/icon.png
  25. 1 0
      demos/2d/dynamic_collision_shapes/engine.cfg
  26. BIN
      demos/2d/dynamic_collision_shapes/icon.png
  27. 1 1
      demos/2d/fog_of_war/engine.cfg
  28. 1 0
      demos/2d/hdr/engine.cfg
  29. BIN
      demos/2d/hdr/icon.png
  30. 1 0
      demos/2d/isometric_light/engine.cfg
  31. BIN
      demos/2d/isometric_light/icon.png
  32. 1 0
      demos/2d/light_mask/engine.cfg
  33. BIN
      demos/2d/light_mask/icon.png
  34. 1 0
      demos/2d/lights_shadows/engine.cfg
  35. BIN
      demos/2d/lights_shadows/icon.png
  36. 1 0
      demos/2d/navpoly/engine.cfg
  37. BIN
      demos/2d/navpoly/icon.png
  38. 1 0
      demos/2d/normalmaps/engine.cfg
  39. BIN
      demos/2d/normalmaps/icon.png
  40. 1 1
      demos/2d/polygon_path_finder_demo/engine.cfg
  41. 1 0
      demos/2d/screen_space_shaders/engine.cfg
  42. BIN
      demos/2d/screen_space_shaders/icon.png
  43. 1 0
      demos/2d/sdf_font/engine.cfg
  44. BIN
      demos/2d/sdf_font/icon.png
  45. 1 0
      demos/2d/splash/engine.cfg
  46. BIN
      demos/2d/splash/icon.png
  47. 1 0
      demos/2d/sprite_shaders/engine.cfg
  48. BIN
      demos/2d/sprite_shaders/icon.png
  49. BIN
      demos/3d/navmesh/icon.png
  50. 1 0
      demos/3d/sat_test/engine.cfg
  51. BIN
      demos/3d/sat_test/icon.png
  52. 0 1
      demos/gui/input_mapping/engine.cfg
  53. 1 0
      demos/gui/rich_text_bbcode/engine.cfg
  54. BIN
      demos/gui/rich_text_bbcode/icon.png
  55. 1 0
      demos/misc/instancing/engine.cfg
  56. BIN
      demos/misc/instancing/icon.png
  57. 10 8
      demos/misc/regex/regex.gd
  58. BIN
      demos/misc/regex/regex.scn
  59. 1 1
      demos/misc/tween/engine.cfg
  60. 1 1
      demos/misc/window_management/engine.cfg
  61. 256 57
      doc/base/classes.xml
  62. 13 8
      drivers/SCsub
  63. 0 2
      drivers/alsa/SCsub
  64. 1 1
      drivers/builtin_zlib/SCsub
  65. 0 2
      drivers/chibi/SCsub
  66. 0 1
      drivers/dds/SCsub
  67. 0 1
      drivers/etc1/SCsub
  68. 0 1
      drivers/gl_context/SCsub
  69. 100 50
      drivers/gles2/rasterizer_gles2.cpp
  70. 8 3
      drivers/gles2/rasterizer_gles2.h
  71. 123 115
      drivers/gles2/shader_compiler_gles2.cpp
  72. 4 1
      drivers/gles2/shader_compiler_gles2.h
  73. 0 2
      drivers/gles2/shaders/SCsub
  74. 0 1
      drivers/jpg/SCsub
  75. 0 1
      drivers/mpc/SCsub
  76. 0 1
      drivers/nedmalloc/SCsub
  77. 26 31
      drivers/nrex/README.md
  78. 0 2
      drivers/nrex/SCsub
  79. 618 140
      drivers/nrex/nrex.cpp
  80. 7 3
      drivers/nrex/nrex.hpp
  81. 6 4
      drivers/nrex/regex.cpp
  82. 1 1
      drivers/nrex/regex.h
  83. 0 1
      drivers/ogg/SCsub
  84. 0 2
      drivers/openssl/SCsub
  85. 8 0
      drivers/opus/opus_config.h
  86. 0 1
      drivers/png/SCsub
  87. 0 1
      drivers/squish/SCsub
  88. 0 3
      drivers/theora/SCsub
  89. 30 16
      drivers/theora/decode.c
  90. 45 13
      drivers/theora/video_stream_theora.cpp
  91. 2 1
      drivers/theora/video_stream_theora.h
  92. 0 2
      drivers/unix/SCsub
  93. 19 9
      drivers/unix/os_unix.cpp
  94. 0 2
      drivers/vorbis/SCsub
  95. 1 2
      drivers/vorbis/audio_stream_ogg_vorbis.cpp
  96. 1 1
      drivers/vorbis/audio_stream_ogg_vorbis.h
  97. 0 1
      drivers/webp/SCsub
  98. 0 2
      drivers/windows/SCsub
  99. 0 2
      main/SCsub
  100. 23 16
      main/main.cpp

+ 1 - 2
README.md

@@ -7,8 +7,7 @@ The editor, language and APIs are feature rich, yet simple to learn, allowing yo
 
 ### About
 
-Godot has been developed by Juan Linietsky and Ariel Manzur for several years, and was born as an in-house engine, used to publish several work-for-hire titles.
-Development is sponsored by OKAM Studio (http://www.okamstudio.com).
+Godot has been developed by Juan Linietsky and Ariel Manzur for several years, and was born as an in-house engine, used to publish several work-for-hire titles. Godot is a member project of the [Software Freedom Conservancy](https://sfconservancy.org)
 
 ### Documentation
 

+ 26 - 25
SConstruct

@@ -59,7 +59,7 @@ platform_arg = ARGUMENTS.get("platform", False)
 if (os.name=="posix"):
 	pass
 elif (os.name=="nt"):
-    if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
+	if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
 		custom_tools=['mingw']
 
 env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
@@ -185,7 +185,7 @@ if selected_platform in platform_list:
 	if env['vsproj']=="yes":
 		env.vs_incs = []
 		env.vs_srcs = []
-		
+
 		def AddToVSProject( sources ):
 			for x in sources:
 				if type(x) == type(""):
@@ -197,12 +197,12 @@ if selected_platform in platform_list:
 					basename = pieces[0]
 					basename = basename.replace('\\\\','/')
 					env.vs_srcs = env.vs_srcs + [basename + ".cpp"]
-					env.vs_incs = env.vs_incs + [basename + ".h"]					
-					#print basename	
-		env.AddToVSProject = AddToVSProject				
-		
+					env.vs_incs = env.vs_incs + [basename + ".h"]
+					#print basename
+		env.AddToVSProject = AddToVSProject
+
 	env.extra_suffix=""
-	
+
 	if env["extra_suffix"] != '' :
 		env.extra_suffix += '.'+env["extra_suffix"]
 
@@ -229,7 +229,7 @@ if selected_platform in platform_list:
 	#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']
+	#env['platform_libsuffix'] = env['LIBSUFFIX']
 
 	suffix="."+selected_platform
 
@@ -284,10 +284,11 @@ if selected_platform in platform_list:
 
 	if (env['musepack']=='yes'):
 		env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
-        if (env['openssl']!='no'):
-            env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
-            if (env['openssl']=="builtin"):
-                env.Append(CPPPATH=['#drivers/builtin_openssl2'])
+
+	if (env['openssl']!='no'):
+		env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
+		if (env['openssl']=="builtin"):
+			env.Append(CPPPATH=['#drivers/builtin_openssl2'])
 
 	if (env["builtin_zlib"]=='yes'):
 		env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
@@ -337,7 +338,7 @@ if selected_platform in platform_list:
 
 	if (env['colored']=='yes'):
 		methods.colored(sys,env)
-		
+
 	if (env['etc1']=='yes'):
 		env.Append(CPPFLAGS=['-DETC1_ENABLED'])
 
@@ -356,22 +357,22 @@ if selected_platform in platform_list:
 	SConscript("main/SCsub")
 
 	SConscript("platform/"+selected_platform+"/SCsub"); # build selected platform
-	
-	# Microsoft Visual Studio Project Generation			
-	if (env['vsproj'])=="yes":		
-	
+
+	# Microsoft Visual Studio Project Generation
+	if (env['vsproj'])=="yes":
+
 		AddToVSProject(env.core_sources)
 		AddToVSProject(env.main_sources)
-		AddToVSProject(env.modules_sources)	
+		AddToVSProject(env.modules_sources)
 		AddToVSProject(env.scene_sources)
 		AddToVSProject(env.servers_sources)
 		AddToVSProject(env.tool_sources)
-		
+
 		#env['MSVS_VERSION']='9.0'
 		env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
 		env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes vsproj=true"
 		env['MSVSCLEANCOM'] = "scons --clean platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
-			
+
 		debug_variants = ['Debug|Win32']+['Debug|x64']
 		release_variants = ['Release|Win32']+['Release|x64']
 		release_debug_variants = ['Release_Debug|Win32']+['Release_Debug|x64']
@@ -382,11 +383,11 @@ if selected_platform in platform_list:
 		targets = debug_targets + release_targets + release_debug_targets
 		msvproj = env.MSVSProject(target = ['#godot' + env['MSVSPROJECTSUFFIX'] ],
 								incs = env.vs_incs,
-								srcs = env.vs_srcs, 
-								runfile = targets, 
-								buildtarget = targets, 
-								auto_build_solution=1, 
-								variant = variants) 		
+								srcs = env.vs_srcs,
+								runfile = targets,
+								buildtarget = targets,
+								auto_build_solution=1,
+								variant = variants)
 
 else:
 

+ 0 - 2
bin/tests/SCsub

@@ -10,5 +10,3 @@ Export('env')
 lib = env.Library("tests",env.tests_sources)
 
 env.Prepend(LIBS=[lib])
-
-

+ 0 - 2
core/SCsub

@@ -63,5 +63,3 @@ SConscript('bind/SCsub');
 lib = env.Library("core",env.core_sources)
 
 env.Prepend(LIBS=[lib])
-
-

+ 0 - 2
core/bind/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.core_sources,"*.cpp")
 
 Export('env')
-
-

+ 33 - 0
core/image.cpp

@@ -34,6 +34,33 @@
 #include "print_string.h"
 #include <stdio.h>
 
+
+const char* Image::format_names[Image::FORMAT_MAX]={
+	"Grayscale",
+	"Intensity",
+	"GrayscaleAlpha",
+	"RGB",
+	"RGBA",
+	"Indexed",
+	"IndexedAlpha",
+	"YUV422",
+	"YUV444",
+	"BC1",
+	"BC2",
+	"BC3",
+	"BC4",
+	"BC5",
+	"PVRTC2",
+	"PVRTC2Alpha",
+	"PVRTC4",
+	"PVRTC4Alpha",
+	"ETC",
+	"ATC",
+	"ATCAlphaExp",
+	"ATCAlphaInterp",
+
+};
+
 SavePNGFunc Image::save_png_func = NULL;
 
 void Image::_put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data) {
@@ -2355,6 +2382,12 @@ void Image::fix_alpha_edges() {
 
 }
 
+String Image::get_format_name(Format p_format) {
+
+	ERR_FAIL_INDEX_V(p_format,FORMAT_MAX,String());
+	return format_names[p_format];
+}
+
 Image::Image(const uint8_t* p_png,int p_len) {
 
 	width=0;

+ 3 - 0
core/image.h

@@ -87,6 +87,7 @@ public:
 		FORMAT_MAX
 	};
 
+	static const char* format_names[FORMAT_MAX];
 	enum Interpolation {
 	
 		INTERPOLATE_NEAREST,
@@ -352,6 +353,8 @@ public:
 	Image get_rect(const Rect2& p_area) const;
 
 	static void set_compress_bc_func(void (*p_compress_func)(Image *));
+	static String get_format_name(Format p_format);
+
 	Image(const uint8_t* p_mem_png, int p_len=-1);
 	Image(const char **p_xpm);
 	~Image();

+ 0 - 2
core/io/SCsub

@@ -5,5 +5,3 @@ env.add_source_files(env.core_sources,"*.c")
 #env.core_sources.append("io/fastlz.c")
 
 Export('env')
-
-

+ 6 - 6
core/io/json.cpp

@@ -177,9 +177,6 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
 							case 'n': res=10; break;
 							case 'f': res=12; break;
 							case 'r': res=13; break;
-							case '\"': res='\"'; break;
-							case '\\': res='\\'; break;
-							case '/': res='/'; break; //wtf
 							case 'u': {
 								//hexnumbarh - oct is deprecated
 
@@ -218,10 +215,13 @@ Error JSON::_get_token(const CharType *p_str, int &idx, int p_len, Token& r_toke
 
 
 							} break;
+							//case '\"': res='\"'; break;
+							//case '\\': res='\\'; break;
+							//case '/': res='/'; break;
 							default: {
-
-								r_err_str="Invalid escape sequence";
-								return ERR_PARSE_ERROR;
+								res = next;
+								//r_err_str="Invalid escape sequence";
+								//return ERR_PARSE_ERROR;
 							} break;
 						}
 

+ 4 - 1
core/io/marshalls.cpp

@@ -36,7 +36,10 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *
 	const uint8_t * buf=p_buffer;
 	int len=p_len;
 
-	ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
+	if (len<4) {
+
+		ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA);
+	}
 
 
 	uint32_t type=decode_uint32(buf);

+ 1 - 2
core/io/packet_peer.cpp

@@ -156,7 +156,6 @@ Error PacketPeerStream::_poll_buffer() const {
 	Error err = peer->get_partial_data(&temp_buffer[0], ring_buffer.space_left(), read);
 	if (err)
 		return err;
-
 	if (read==0)
 		return OK;
 
@@ -202,7 +201,7 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer,int &r_buffer_size)
 	uint8_t lbuf[4];
 	ring_buffer.copy(lbuf,0,4);
 	remaining-=4;
-	uint32_t len = decode_uint32(lbuf);
+	uint32_t len = decode_uint32(lbuf);	
 	ERR_FAIL_COND_V(remaining<(int)len,ERR_UNAVAILABLE);
 
 	ring_buffer.read(lbuf,4); //get rid of first 4 bytes

+ 3 - 2
core/io/resource_format_binary.cpp

@@ -2172,10 +2172,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
 
 			save_unicode_string("local://"+itos(r->get_subindex()));
 			if (takeover_paths) {
-				r->set_path(p_path+"::"+itos(ofs_pos.size()),true);
+				r->set_path(p_path+"::"+itos(r->get_subindex()),true);
 			}
-		} else
+		} else {
 			save_unicode_string(r->get_path()); //actual external
+		}
 		ofs_pos.push_back(f->get_pos());
 		f->store_64(0); //offset in 64 bits
 	}

+ 2 - 2
core/io/resource_format_xml.cpp

@@ -2056,8 +2056,8 @@ Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Ma
 void ResourceFormatSaverXMLInstance::escape(String& p_str) {
 
 	p_str=p_str.replace("&","&amp;");
-	p_str=p_str.replace("<","&gt;");
-	p_str=p_str.replace(">","&lt;");
+	p_str=p_str.replace("<","&lt;");
+	p_str=p_str.replace(">","&gt;");
 	p_str=p_str.replace("'","&apos;");
 	p_str=p_str.replace("\"","&quot;");
 	for (char i=1;i<32;i++) {

+ 0 - 2
core/math/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.core_sources,"*.cpp")
 
 Export('env')
-
-

+ 1 - 1
core/math/quat.h

@@ -73,7 +73,7 @@ public:
 			-x * v.x - y * v.y - z * v.z);
 	}
 
-	_FORCE_INLINE_ Vector3 xform(const Vector3& v) {
+	_FORCE_INLINE_ Vector3 xform(const Vector3& v) const {
 
 		Quat q = *this * v;
 		q *= this->inverse();

+ 0 - 2
core/os/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.core_sources,"*.cpp")
 
 Export('env')
-
-

+ 9 - 2
core/os/os.cpp

@@ -61,9 +61,16 @@ void OS::debug_break() {
 
 void OS::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) {
 
+	const char* err_type;
+	switch(p_type) {
+		case ERR_ERROR: err_type="**ERROR**"; break;
+		case ERR_WARNING: err_type="**WARNING**"; break;
+		case ERR_SCRIPT: err_type="**SCRIPT ERROR**"; break;
+	}
+
 	if (p_rationale && *p_rationale)
-		print("**ERROR**: %s\n ",p_rationale);
-	print("**ERROR**: At: %s:%i:%s() - %s\n",p_file,p_line,p_function,p_code);
+		print("%s: %s\n ",err_type,p_rationale);
+	print("%s: At: %s:%i:%s() - %s\n",err_type,p_file,p_line,p_function,p_code);
 }
 
 void OS::print(const char* p_format, ...) {

+ 4 - 4
core/ring_buffer.h

@@ -141,15 +141,15 @@ public:
 	inline int space_left() {
 		int left = read_pos - write_pos;
 		if (left < 0) {
-			return size() + left;
+			return size() + left - 1;
 		};
 		if (left == 0) {
-			return size();
+			return size()-1;
 		};
-		return left;
+		return left -1;
 	};
 	inline int data_left() {
-		return size() - space_left();
+		return size() - space_left() - 1;
 	};
 	
 	inline int size() {

+ 30 - 0
core/script_debugger_remote.cpp

@@ -31,6 +31,28 @@
 #include "io/ip.h"
 #include "globals.h"
 
+void ScriptDebuggerRemote::_send_video_memory() {
+
+	List<ResourceUsage> usage;
+	if (resource_usage_func)
+		resource_usage_func(&usage);
+
+	usage.sort();
+
+	packet_peer_stream->put_var("message:video_mem");
+	packet_peer_stream->put_var(usage.size()*4);
+
+
+	for(List<ResourceUsage>::Element *E=usage.front();E;E=E->next()) {
+
+		packet_peer_stream->put_var(E->get().path);
+		packet_peer_stream->put_var(E->get().type);
+		packet_peer_stream->put_var(E->get().format);
+		packet_peer_stream->put_var(E->get().vram);
+	}
+
+}
+
 Error ScriptDebuggerRemote::connect_to_host(const String& p_host,uint16_t p_port) {
 
 
@@ -248,6 +270,9 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
 				if (request_scene_tree)
 					request_scene_tree(request_scene_tree_ud);
 
+			} else if (command=="request_video_mem") {
+
+				_send_video_memory();
 			} else if (command=="breakpoint") {
 
 				bool set = cmd[3];
@@ -531,6 +556,9 @@ void ScriptDebuggerRemote::_poll_events() {
 
 			if (request_scene_tree)
 				request_scene_tree(request_scene_tree_ud);
+		} else if (command=="request_video_mem") {
+
+			_send_video_memory();
 		} else if (command=="breakpoint") {
 
 			bool set = cmd[3];
@@ -652,6 +680,8 @@ void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
 	live_edit_funcs=p_funcs;
 }
 
+ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func=NULL;
+
 ScriptDebuggerRemote::ScriptDebuggerRemote() {
 
 	tcp_client  = StreamPeerTCP::create_ref();

+ 18 - 0
core/script_debugger_remote.h

@@ -34,6 +34,7 @@
 #include "io/stream_peer_tcp.h"
 #include "io/packet_peer.h"
 #include "list.h"
+
 class ScriptDebuggerRemote : public ScriptDebugger {
 
 	struct Message {
@@ -42,6 +43,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 		Array data;
 	};
 
+
+
 	Ref<StreamPeerTCP> tcp_client;
 	Ref<PacketPeerStream> packet_peer_stream;
 
@@ -90,6 +93,7 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 	RequestSceneTreeMessageFunc request_scene_tree;
 	void *request_scene_tree_ud;
 
+	void _send_video_memory();
 	LiveEditFuncs *live_edit_funcs;
 
 	ErrorHandlerList eh;
@@ -98,6 +102,20 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 
 public:
 
+	struct ResourceUsage {
+
+		String path;
+		String format;
+		String type;
+		RID id;
+		int vram;
+		bool operator<(const ResourceUsage& p_img) const { return vram==p_img.vram ? id<p_img.id : vram > p_img.vram; }
+	};
+
+	typedef void (*ResourceUsageFunc)(List<ResourceUsage>*);
+
+	static ResourceUsageFunc resource_usage_func;
+
 	Error connect_to_host(const String& p_host,uint16_t p_port);
 	virtual void debug(ScriptLanguage *p_script,bool p_can_continue=true);
 	virtual void idle_poll();

+ 2 - 0
core/variant_call.cpp

@@ -409,6 +409,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
 	VCALL_LOCALMEM0R(Quat,normalized);
 	VCALL_LOCALMEM0R(Quat,inverse);
 	VCALL_LOCALMEM1R(Quat,dot);
+	VCALL_LOCALMEM1R(Quat,xform);
 	VCALL_LOCALMEM2R(Quat,slerp);
 	VCALL_LOCALMEM2R(Quat,slerpni);
 	VCALL_LOCALMEM4R(Quat,cubic_slerp);
@@ -1361,6 +1362,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
 	ADDFUNC0(QUAT,QUAT,Quat,normalized,varray());
 	ADDFUNC0(QUAT,QUAT,Quat,inverse,varray());
 	ADDFUNC1(QUAT,REAL,Quat,dot,QUAT,"b",varray());
+	ADDFUNC1(QUAT,VECTOR3,Quat,xform,VECTOR3,"v",varray());
 	ADDFUNC2(QUAT,QUAT,Quat,slerp,QUAT,"b",REAL,"t",varray());
 	ADDFUNC2(QUAT,QUAT,Quat,slerpni,QUAT,"b",REAL,"t",varray());
 	ADDFUNC4(QUAT,QUAT,Quat,cubic_slerp,QUAT,"b",QUAT,"pre_a",QUAT,"post_b",REAL,"t",varray());

+ 16 - 2
core/variant_op.cpp

@@ -586,7 +586,21 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
 				} break;
 				DEFAULT_OP_LOCALMEM_NUM(*,VECTOR3,Vector3);
 				DEFAULT_OP_FAIL(PLANE);
-				DEFAULT_OP_FAIL(QUAT);
+				case QUAT: {
+
+					switch(p_b.type) {
+						case VECTOR3: {
+
+							_RETURN( reinterpret_cast<const Quat*>(p_a._data._mem)->xform( *(const Vector3*)p_b._data._mem) );
+						} break;
+						case QUAT: {
+
+							_RETURN( *reinterpret_cast<const Quat*>(p_a._data._mem) * *reinterpret_cast<const Quat*>(p_b._data._mem) );
+						} break;
+					};
+					r_valid=false;
+					return;
+				} break;
 				DEFAULT_OP_FAIL(_AABB);
 				case MATRIX3: {
 
@@ -2573,7 +2587,7 @@ bool Variant::in(const Variant& p_index, bool *r_valid) const {
 				String idx=p_index;
 				const String *str=reinterpret_cast<const String*>(_data._mem);
 
-				return str->find("idx")!=-1;
+				return str->find(idx)!=-1;
 			}
 
 		} break;

+ 1 - 0
demos/2d/area_input/engine.cfg

@@ -2,3 +2,4 @@
 
 name="Area 2D Input Events"
 main_scene="res://input.scn"
+icon="res://icon.png"

BIN
demos/2d/area_input/icon.png


+ 1 - 0
demos/2d/dynamic_collision_shapes/engine.cfg

@@ -2,3 +2,4 @@
 
 name="Run-Time CollisionShape"
 main_scene="res://dynamic_colobjs.scn"
+icon="res://icon.png"

BIN
demos/2d/dynamic_collision_shapes/icon.png


+ 1 - 1
demos/2d/fog_of_war/engine.cfg

@@ -2,7 +2,7 @@
 
 name="Fog of War"
 main_scene="res://fog.scn"
-icon="icon.png"
+icon="res://icon.png"
 
 [input]
 

+ 1 - 0
demos/2d/hdr/engine.cfg

@@ -2,6 +2,7 @@
 
 name="HDR for 2D"
 main_scene="res://beach_cave.scn"
+icon="res://icon.png"
 
 [display]
 

BIN
demos/2d/hdr/icon.png


+ 1 - 0
demos/2d/isometric_light/engine.cfg

@@ -2,6 +2,7 @@
 
 name="Isometric 2D + Lighting"
 main_scene="res://map.scn"
+icon="res://icon.png"
 
 [input]
 

BIN
demos/2d/isometric_light/icon.png


+ 1 - 0
demos/2d/light_mask/engine.cfg

@@ -2,6 +2,7 @@
 
 name="Using Lights As Mask"
 main_scene="res://lightmask.scn"
+icon="res://icon.png"
 
 [rasterizer]
 

BIN
demos/2d/light_mask/icon.png


+ 1 - 0
demos/2d/lights_shadows/engine.cfg

@@ -2,6 +2,7 @@
 
 name="2D Lighting"
 main_scene="res://light_shadows.scn"
+icon="res://icon.png"
 
 [display]
 

BIN
demos/2d/lights_shadows/icon.png


+ 1 - 0
demos/2d/navpoly/engine.cfg

@@ -2,6 +2,7 @@
 
 name="Navigation Polygon (2D)"
 main_scene="res://navigation.scn"
+icon="res://icon.png"
 
 [display]
 

BIN
demos/2d/navpoly/icon.png


+ 1 - 0
demos/2d/normalmaps/engine.cfg

@@ -2,6 +2,7 @@
 
 name="2D Normal Mapping"
 main_scene="res://normalmap.scn"
+icon="res://icon.png"
 
 [display]
 

BIN
demos/2d/normalmaps/icon.png


+ 1 - 1
demos/2d/polygon_path_finder_demo/engine.cfg

@@ -2,4 +2,4 @@
 
 name="polygon_path_finder_demo"
 main_scene="res://new_scene_poly_with_holes.scn"
-icon="icon.png"
+icon="res://icon.png"

+ 1 - 0
demos/2d/screen_space_shaders/engine.cfg

@@ -2,6 +2,7 @@
 
 name="Screen-Space Shaders"
 main_scene="res://screen_shaders.scn"
+icon="res://icon.png"
 
 [display]
 

BIN
demos/2d/screen_space_shaders/icon.png


+ 1 - 0
demos/2d/sdf_font/engine.cfg

@@ -2,3 +2,4 @@
 
 name="Signed Distance Field Font"
 main_scene="res://sdf.scn"
+icon="res://icon.png"

BIN
demos/2d/sdf_font/icon.png


+ 1 - 0
demos/2d/splash/engine.cfg

@@ -2,6 +2,7 @@
 
 name="Splash Screen"
 main_scene="res://splash.xml"
+icon="res://icon.png"
 
 [display]
 

BIN
demos/2d/splash/icon.png


+ 1 - 0
demos/2d/sprite_shaders/engine.cfg

@@ -2,3 +2,4 @@
 
 name="2D Shaders for Sprites"
 main_scene="res://sprite_shaders.scn"
+icon="res://icon.png"

BIN
demos/2d/sprite_shaders/icon.png


BIN
demos/3d/navmesh/icon.png


+ 1 - 0
demos/3d/sat_test/engine.cfg

@@ -2,3 +2,4 @@
 
 name="SAT Collision Test"
 main_scene="res://sat_test.xml"
+icon="res://icon.png"

BIN
demos/3d/sat_test/icon.png


+ 0 - 1
demos/gui/input_mapping/engine.cfg

@@ -2,7 +2,6 @@
 
 name="Input Mapping GUI"
 main_scene="res://controls.scn"
-icon="icon.png"
 
 [display]
 

+ 1 - 0
demos/gui/rich_text_bbcode/engine.cfg

@@ -2,3 +2,4 @@
 
 name="Rich Text Label (BBCode)"
 main_scene="res://rich_text_bbcode.scn"
+icon="res://icon.png"

BIN
demos/gui/rich_text_bbcode/icon.png


+ 1 - 0
demos/misc/instancing/engine.cfg

@@ -2,6 +2,7 @@
 
 name="Scene Instancing Demo"
 main_scene="res://container.scn"
+icon="res://icon.png"
 
 [physics_2d]
 

BIN
demos/misc/instancing/icon.png


+ 10 - 8
demos/misc/regex/regex.gd

@@ -2,21 +2,23 @@ extends VBoxContainer
 
 var regex = RegEx.new()
 
-func update_expression():
-	regex.compile(get_node("Expression").get_text())
+func update_expression(text):
+	regex.compile(text)
 	update_text()
 
 func update_text():
 	var text = get_node("Text").get_text()
-	regex.find(text)
 	var list = get_node("List")
 	for child in list.get_children():
 		child.queue_free()
-	for res in regex.get_captures():
-		var label = Label.new()
-		label.set_text(res)
-		list.add_child(label)
+	if regex.is_valid():
+		regex.find(text)
+		for res in regex.get_captures():
+			var label = Label.new()
+			label.set_text(res)
+			list.add_child(label)
 
 func _ready():
 	get_node("Text").set_text("They asked me \"What's going on \\\"in the manor\\\"?\"")
-	update_expression()
+	update_expression(get_node("Expression").get_text())
+

BIN
demos/misc/regex/regex.scn


+ 1 - 1
demos/misc/tween/engine.cfg

@@ -2,7 +2,7 @@
 
 name="Tween Demo"
 main_scene="res://main.xml"
-icon="icon.png"
+icon="res://icon.png"
 target_fps=60
 
 [display]

+ 1 - 1
demos/misc/window_management/engine.cfg

@@ -2,7 +2,7 @@
 
 name="Window Management"
 main_scene="res://window_management.scn"
-icon="icon.png"
+icon="res://icon.png"
 
 [display]
 

File diff suppressed because it is too large
+ 256 - 57
doc/base/classes.xml


+ 13 - 8
drivers/SCsub

@@ -69,21 +69,27 @@ for f in env.drivers_sources:
 		fname = env.File(f).path
 	else:
 		fname = env.File(f)[0].path
-	#base = string.join(fname.split("/")[:-1], "/")
 	fname = fname.replace("\\", "/")
 	base = string.join(fname.split("/")[:2], "/")
 	if base != cur_base and len(list) > max_src:
-		lib = env.Library("drivers"+str(num), list)
-		lib_list.append(lib)
-		list = []
+		if num > 0:
+			lib = env.Library("drivers"+str(num), list)
+			lib_list.append(lib)
+			list = []
 		num = num+1
 	cur_base = base
 	list.append(f)
 
-if len(list) > 0:
-	lib = env.Library("drivers"+str(num), list)
-	lib_list.append(lib)
+lib = env.Library("drivers"+str(num), list)
+lib_list.append(lib)
 
+if len(lib_list) > 0:
+	import os, sys
+	if os.name=='posix' and sys.platform=='msys':
+		env.Replace(ARFLAGS=['rcsT'])
+
+		lib = env.Library("drivers_collated", lib_list)
+		lib_list = [lib]
 
 drivers_base=[]
 env.add_source_files(drivers_base,"*.cpp")
@@ -93,4 +99,3 @@ env.Prepend(LIBS=lib_list)
 
 #lib = env.Library("drivers",env.drivers_sources)
 #env.Prepend(LIBS=[lib])
-

+ 0 - 2
drivers/alsa/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.drivers_sources,"*.cpp")
 
 Export('env')
-
-

+ 1 - 1
drivers/builtin_zlib/SCsub

@@ -1,7 +1,7 @@
 Import('env')
 
 zlib_sources = [
-	
+
 	"builtin_zlib/zlib/adler32.c",
 	"builtin_zlib/zlib/compress.c",
 	"builtin_zlib/zlib/crc32.c",

+ 0 - 2
drivers/chibi/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.drivers_sources,"*.cpp")
 
 Export('env')
-
-

+ 0 - 1
drivers/dds/SCsub

@@ -8,4 +8,3 @@ dds_sources = [
 env.drivers_sources+=dds_sources
 
 #env.add_source_files(env.drivers_sources, dds_sources)
-

+ 0 - 1
drivers/etc1/SCsub

@@ -12,4 +12,3 @@ if (env["etc1"] != "no"):
 #env.add_source_files(env.drivers_sources, etc_sources)
 
 Export('env')
-

+ 0 - 1
drivers/gl_context/SCsub

@@ -3,4 +3,3 @@ Export('env');
 
 env.add_source_files(env.drivers_sources,"*.cpp")
 env.add_source_files(env.drivers_sources,"*.c")
-

+ 100 - 50
drivers/gles2/rasterizer_gles2.cpp

@@ -1408,6 +1408,40 @@ GLuint RasterizerGLES2::_texture_get_name(RID p_tex) {
 	return texture->tex_id;
 };
 
+void RasterizerGLES2::texture_set_path(RID p_texture,const String& p_path) {
+	Texture * texture = texture_owner.get(p_texture);
+	ERR_FAIL_COND(!texture);
+
+	texture->path=p_path;
+
+}
+
+String RasterizerGLES2::texture_get_path(RID p_texture) const{
+
+	Texture * texture = texture_owner.get(p_texture);
+	ERR_FAIL_COND_V(!texture,String());
+	return texture->path;
+}
+void RasterizerGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info){
+
+	List<RID> textures;
+	texture_owner.get_owned_list(&textures);
+
+	for (List<RID>::Element *E=textures.front();E;E=E->next()) {
+
+		Texture *t = texture_owner.get(E->get());
+		if (!t)
+			continue;
+		VS::TextureInfo tinfo;
+		tinfo.path=t->path;
+		tinfo.format=t->format;
+		tinfo.size.x=t->alloc_width;
+		tinfo.size.y=t->alloc_height;
+		tinfo.bytes=t->total_data_size;
+		r_info->push_back(tinfo);
+	}
+
+}
 
 /* SHADER API */
 
@@ -4041,6 +4075,8 @@ void RasterizerGLES2::render_target_set_size(RID p_render_target,int p_width,int
 		glDeleteTextures(1,&rt->color);
 
 		rt->fbo=0;
+		rt->depth=0;
+		rt->color=0;
 		rt->width=0;
 		rt->height=0;
 		rt->texture_ptr->tex_id=0;
@@ -4060,12 +4096,14 @@ void RasterizerGLES2::render_target_set_size(RID p_render_target,int p_width,int
 	glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
 
 	//depth
-	glGenRenderbuffers(1, &rt->depth);
-	glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
+	if (!low_memory_2d) {
+		glGenRenderbuffers(1, &rt->depth);
+		glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
 
-	glRenderbufferStorage(GL_RENDERBUFFER, use_depth24?_DEPTH_COMPONENT24_OES:GL_DEPTH_COMPONENT16, rt->width,rt->height);
+		glRenderbufferStorage(GL_RENDERBUFFER, use_depth24?_DEPTH_COMPONENT24_OES:GL_DEPTH_COMPONENT16, rt->width,rt->height);
 
-	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
+	}
 
 	//color
 	glGenTextures(1, &rt->color);
@@ -4607,6 +4645,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 			enablers.push_back("#define USE_TIME\n");
 			uses_time=true;
 		}
+		if (vertex_flags.vertex_code_writes_position) {
+			enablers.push_back("#define VERTEX_SHADER_WRITE_POSITION\n");
+		}
 
 		material_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers);
 	} else if (p_shader->mode==VS::SHADER_CANVAS_ITEM) {
@@ -6492,80 +6533,84 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
 			material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP,false);
 			material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER,false);
 
-			if (e->instance->sampled_light.is_valid()) {
+			if (material->flags[VS::MATERIAL_FLAG_UNSHADED] == false && current_debug != VS::SCENARIO_DEBUG_SHADELESS) {
 
-				SampledLight *sl = sampled_light_owner.get(e->instance->sampled_light);
-				if (sl) {
+				if (e->instance->sampled_light.is_valid()) {
 
-					baked_light=NULL; //can't mix
-					material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER,true);
-					glActiveTexture(GL_TEXTURE0+max_texture_units-3);
-					glBindTexture(GL_TEXTURE_2D,sl->texture); //bind the texture
-					sampled_light_dp_multiplier=sl->multiplier;
-					bind_dp_sampler=true;
+					SampledLight *sl = sampled_light_owner.get(e->instance->sampled_light);
+					if (sl) {
+
+						baked_light = NULL; //can't mix
+						material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER, true);
+						glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
+						glBindTexture(GL_TEXTURE_2D, sl->texture); //bind the texture
+						sampled_light_dp_multiplier = sl->multiplier;
+						bind_dp_sampler = true;
+					}
 				}
-			}
 
 
-			if (!additive && baked_light) {
+				if (!additive && baked_light) {
 
-				if (baked_light->mode==VS::BAKED_LIGHT_OCTREE && baked_light->octree_texture.is_valid() && e->instance->baked_light_octree_xform) {
-					material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE,true);
-					bind_baked_light_octree=true;
-					if (prev_baked_light!=baked_light) {
-						Texture *tex=texture_owner.get(baked_light->octree_texture);
-						if (tex) {
+					if (baked_light->mode == VS::BAKED_LIGHT_OCTREE && baked_light->octree_texture.is_valid() && e->instance->baked_light_octree_xform) {
+						material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE, true);
+						bind_baked_light_octree = true;
+						if (prev_baked_light != baked_light) {
+							Texture *tex = texture_owner.get(baked_light->octree_texture);
+							if (tex) {
 
-							glActiveTexture(GL_TEXTURE0+max_texture_units-3);
-							glBindTexture(tex->target,tex->tex_id); //bind the texture
-						}
-						if (baked_light->light_texture.is_valid()) {
-							Texture *texl=texture_owner.get(baked_light->light_texture);
-							if (texl) {
-								glActiveTexture(GL_TEXTURE0+max_texture_units-4);
-								glBindTexture(texl->target,texl->tex_id); //bind the light texture
+								glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
+								glBindTexture(tex->target, tex->tex_id); //bind the texture
+							}
+							if (baked_light->light_texture.is_valid()) {
+								Texture *texl = texture_owner.get(baked_light->light_texture);
+								if (texl) {
+									glActiveTexture(GL_TEXTURE0 + max_texture_units - 4);
+									glBindTexture(texl->target, texl->tex_id); //bind the light texture
+								}
 							}
-						}
 
+						}
 					}
-				} else if (baked_light->mode==VS::BAKED_LIGHT_LIGHTMAPS) {
+					else if (baked_light->mode == VS::BAKED_LIGHT_LIGHTMAPS) {
 
 
-					int lightmap_idx = e->instance->baked_lightmap_id;
+						int lightmap_idx = e->instance->baked_lightmap_id;
 
-					material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP,false);
-					bind_baked_lightmap=false;
+						material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP, false);
+						bind_baked_lightmap = false;
 
 
-					if (baked_light->lightmaps.has(lightmap_idx)) {
+						if (baked_light->lightmaps.has(lightmap_idx)) {
 
 
-						RID texid = baked_light->lightmaps[lightmap_idx];
+							RID texid = baked_light->lightmaps[lightmap_idx];
 
-						if (prev_baked_light!=baked_light || texid!=prev_baked_light_texture) {
+							if (prev_baked_light != baked_light || texid != prev_baked_light_texture) {
 
 
-							Texture *tex = texture_owner.get(texid);
-							if (tex) {
+								Texture *tex = texture_owner.get(texid);
+								if (tex) {
 
-								glActiveTexture(GL_TEXTURE0+max_texture_units-3);
-								glBindTexture(tex->target,tex->tex_id); //bind the texture
+									glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
+									glBindTexture(tex->target, tex->tex_id); //bind the texture
+								}
+
+								prev_baked_light_texture = texid;
 							}
 
-							prev_baked_light_texture=texid;
-						}
+							if (texid.is_valid()) {
+								material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP, true);
+								bind_baked_lightmap = true;
+							}
 
-						if (texid.is_valid()) {
-							material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP,true);
-							bind_baked_lightmap=true;
 						}
-
 					}
 				}
-			}
 
-			if (int(prev_baked_light!=NULL) ^ int(baked_light!=NULL)) {
-				rebind=true;
+				if (int(prev_baked_light != NULL) ^ int(baked_light != NULL)) {
+					rebind = true;
+				}
 			}
 		}
 
@@ -10259,7 +10304,11 @@ void RasterizerGLES2::_update_framebuffer() {
 		framebuffer.fbo=0;
 	}
 
+#ifdef TOOLS_ENABLED
 	framebuffer.active=use_fbo;
+#else
+	framebuffer.active=use_fbo && !low_memory_2d;
+#endif
 	framebuffer.width=dwidth;
 	framebuffer.height=dheight;
 	framebuffer.scale=scale;
@@ -11169,6 +11218,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo
 	use_fp16_fb=bool(GLOBAL_DEF("rasterizer/fp16_framebuffer",true));
 	use_shadow_mapping=true;
 	use_fast_texture_filter=!bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true));
+	low_memory_2d=bool(GLOBAL_DEF("rasterizer/low_memory_2d_mode",false));
 	skel_default.resize(1024*4);
 	for(int i=0;i<1024/3;i++) {
 

+ 8 - 3
drivers/gles2/rasterizer_gles2.h

@@ -105,16 +105,17 @@ class RasterizerGLES2 : public Rasterizer {
 	float anisotropic_level;
 
 	bool use_half_float;
-
+	bool low_memory_2d;
 
 	Vector<float> skel_default;
 
 	Image _get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags,GLenum& r_gl_format,GLenum& r_gl_internal_format,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed);
 
-	class RenderTarget;
+	struct RenderTarget;
 
 	struct Texture {
 
+		String path;
 		uint32_t flags;
 		int width,height;
 		int alloc_width, alloc_height;
@@ -304,7 +305,7 @@ class RasterizerGLES2 : public Rasterizer {
 		virtual ~GeometryOwner() {}
 	};
 
-	class Mesh;
+	struct Mesh;
 
 	struct Surface : public Geometry {
 
@@ -1325,6 +1326,10 @@ public:
 	virtual void texture_set_size_override(RID p_texture,int p_width, int p_height);
 	virtual void texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName& p_function) const;
 
+	virtual void texture_set_path(RID p_texture,const String& p_path);
+	virtual String texture_get_path(RID p_texture) const;
+	virtual void texture_debug_usage(List<VS::TextureInfo> *r_info);
+
 	GLuint _texture_get_name(RID p_tex);
 
 	/* SHADER API */

+ 123 - 115
drivers/gles2/shader_compiler_gles2.cpp

@@ -154,6 +154,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 				if (vnode->name==vname_vertex && p_assign_left) {
 					vertex_code_writes_vertex=true;
 				}
+				if (vnode->name == vname_position && p_assign_left) {
+					vertex_code_writes_position = true;
+				}
 				if (vnode->name==vname_color_interp) {
 					flags->use_color_interp=true;
 				}
@@ -659,6 +662,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	uses_texpixel_size=false;
 	uses_worldvec=false;
 	vertex_code_writes_vertex=false;
+	vertex_code_writes_position = false;
 	uses_shadow_color=false;
 	uniforms=r_uniforms;
 	flags=&r_flags;
@@ -690,6 +694,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	r_flags.uses_texscreen=uses_texscreen;
 	r_flags.uses_texpos=uses_texpos;
 	r_flags.vertex_code_writes_vertex=vertex_code_writes_vertex;
+	r_flags.vertex_code_writes_position=vertex_code_writes_position;
 	r_flags.uses_discard=uses_discard;
 	r_flags.uses_screen_uv=uses_screen_uv;
 	r_flags.uses_light=uses_light;
@@ -778,125 +783,127 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	replace_table["texscreen"]= "texscreen";
 	replace_table["texpos"]= "texpos";
 
-	mode_replace_table[0]["SRC_VERTEX"]="vertex_in.xyz";
-	mode_replace_table[0]["SRC_NORMAL"]="normal_in";
-	mode_replace_table[0]["SRC_TANGENT"]="tangent_in";
-	mode_replace_table[0]["SRC_BINORMALF"]="binormalf";
-
-	mode_replace_table[0]["VERTEX"]="vertex_interp";
-	mode_replace_table[0]["NORMAL"]="normal_interp";
-	mode_replace_table[0]["TANGENT"]="tangent_interp";
-	mode_replace_table[0]["BINORMAL"]="binormal_interp";
-	mode_replace_table[0]["UV"]="uv_interp.xy";
-	mode_replace_table[0]["UV2"]="uv_interp.zw";
-	mode_replace_table[0]["COLOR"]="color_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["POSITION"] = "gl_Position";
+
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SRC_VERTEX"] = "vertex_in.xyz";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SRC_NORMAL"] = "normal_in";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SRC_TANGENT"]="tangent_in";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SRC_BINORMALF"]="binormalf";
+
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["VERTEX"]="vertex_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["NORMAL"]="normal_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["TANGENT"]="tangent_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["BINORMAL"]="binormal_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["UV"]="uv_interp.xy";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["UV2"]="uv_interp.zw";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["COLOR"]="color_interp";
 	//@TODO convert to glsl stuff
-	mode_replace_table[0]["SPEC_EXP"]="vertex_specular_exp";
-	mode_replace_table[0]["WORLD_MATRIX"]="world_transform";
-	mode_replace_table[0]["INV_CAMERA_MATRIX"]="camera_inverse_transform";
-	mode_replace_table[0]["PROJECTION_MATRIX"]="projection_transform";
-	mode_replace_table[0]["MODELVIEW_MATRIX"]="modelview";
-	mode_replace_table[0]["POINT_SIZE"]="gl_PointSize";
-	mode_replace_table[0]["VAR1"]="var1_interp";
-	mode_replace_table[0]["VAR2"]="var2_interp";
-
-//	mode_replace_table[0]["SCREEN_POS"]="SCREEN_POS";
-//	mode_replace_table[0]["SCREEN_SIZE"]="SCREEN_SIZE";
-	mode_replace_table[0]["INSTANCE_ID"]="instance_id";
-	mode_replace_table[0]["TIME"]="time";
-
-	mode_replace_table[1]["VERTEX"]="vertex";
-	//mode_replace_table[1]["POSITION"]="IN_POSITION";
-	mode_replace_table[1]["NORMAL"]="normal";
-	mode_replace_table[1]["TANGENT"]="tangent";
-	mode_replace_table[1]["POSITION"]="gl_Position";
-	mode_replace_table[1]["BINORMAL"]="binormal";
-	mode_replace_table[1]["NORMALMAP"]="normalmap";
-	mode_replace_table[1]["NORMALMAP_DEPTH"]="normaldepth";
-	mode_replace_table[1]["VAR1"]="var1_interp";
-	mode_replace_table[1]["VAR2"]="var2_interp";
-	mode_replace_table[1]["UV"]="uv";
-	mode_replace_table[1]["UV2"]="uv2";
-	mode_replace_table[1]["SCREEN_UV"]="screen_uv";
-	mode_replace_table[1]["VAR1"]="var1_interp";
-	mode_replace_table[1]["VAR2"]="var2_interp";
-	mode_replace_table[1]["COLOR"]="color";
-	mode_replace_table[1]["DIFFUSE"]="diffuse.rgb";
-	mode_replace_table[1]["DIFFUSE_ALPHA"]="diffuse";
-	mode_replace_table[1]["SPECULAR"]="specular";
-	mode_replace_table[1]["EMISSION"]="emission";
-	mode_replace_table[1]["SHADE_PARAM"]="shade_param";
-	mode_replace_table[1]["SPEC_EXP"]="specular_exp";
-	mode_replace_table[1]["GLOW"]="glow";
-	mode_replace_table[1]["DISCARD"]="discard_";
-	mode_replace_table[1]["POINT_COORD"]="gl_PointCoord";
-	mode_replace_table[1]["INV_CAMERA_MATRIX"]="camera_inverse_transform";
-
-	//mode_replace_table[1]["SCREEN_POS"]="SCREEN_POS";
-	//mode_replace_table[1]["SCREEN_TEXEL_SIZE"]="SCREEN_TEXEL_SIZE";
-	mode_replace_table[1]["TIME"]="time";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SPEC_EXP"]="vertex_specular_exp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["WORLD_MATRIX"]="world_transform";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["INV_CAMERA_MATRIX"]="camera_inverse_transform";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["PROJECTION_MATRIX"]="projection_transform";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["MODELVIEW_MATRIX"]="modelview";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["POINT_SIZE"]="gl_PointSize";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["VAR1"]="var1_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["VAR2"]="var2_interp";
+
+//	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SCREEN_POS"]="SCREEN_POS";
+//	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["SCREEN_SIZE"]="SCREEN_SIZE";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["INSTANCE_ID"]="instance_id";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_VERTEX]["TIME"]="time";
+
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["VERTEX"]="vertex";
+	//mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["POSITION"]="IN_POSITION";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["NORMAL"]="normal";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["TANGENT"]="tangent";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["POSITION"]="gl_Position";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["BINORMAL"]="binormal";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["NORMALMAP"]="normalmap";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["NORMALMAP_DEPTH"]="normaldepth";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["VAR1"]="var1_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["VAR2"]="var2_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["UV"]="uv";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["UV2"]="uv2";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["SCREEN_UV"]="screen_uv";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["VAR1"]="var1_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["VAR2"]="var2_interp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["COLOR"]="color";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["DIFFUSE"]="diffuse.rgb";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["DIFFUSE_ALPHA"]="diffuse";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["SPECULAR"]="specular";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["EMISSION"]="emission";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["SHADE_PARAM"]="shade_param";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["SPEC_EXP"]="specular_exp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["GLOW"]="glow";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["DISCARD"]="discard_";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["POINT_COORD"]="gl_PointCoord";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["INV_CAMERA_MATRIX"]="camera_inverse_transform";
+
+	//mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["SCREEN_POS"]="SCREEN_POS";
+	//mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["SCREEN_TEXEL_SIZE"]="SCREEN_TEXEL_SIZE";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_FRAGMENT]["TIME"]="time";
 
 	//////////////
 
-	mode_replace_table[2]["NORMAL"]="normal";
-	//mode_replace_table[2]["POSITION"]="IN_POSITION";
-	mode_replace_table[2]["LIGHT_DIR"]="light_dir";
-	mode_replace_table[2]["LIGHT_DIFFUSE"]="light_diffuse";
-	mode_replace_table[2]["LIGHT_SPECULAR"]="light_specular";
-	mode_replace_table[2]["EYE_VEC"]="eye_vec";
-	mode_replace_table[2]["DIFFUSE"]="mdiffuse";
-	mode_replace_table[2]["SPECULAR"]="specular";
-	mode_replace_table[2]["SPECULAR_EXP"]="specular_exp";
-	mode_replace_table[2]["SHADE_PARAM"]="shade_param";
-	mode_replace_table[2]["LIGHT"]="light";
-	mode_replace_table[2]["POINT_COORD"]="gl_PointCoord";
-	mode_replace_table[2]["TIME"]="time";
-
-	mode_replace_table[3]["SRC_VERTEX"]="src_vtx";
-	mode_replace_table[3]["VERTEX"]="outvec.xy";
-	mode_replace_table[3]["WORLD_VERTEX"]="outvec.xy";
-	mode_replace_table[3]["UV"]="uv_interp";
-	mode_replace_table[3]["COLOR"]="color_interp";
-	mode_replace_table[3]["VAR1"]="var1_interp";
-	mode_replace_table[3]["VAR2"]="var2_interp";
-	mode_replace_table[3]["POINT_SIZE"]="gl_PointSize";
-	mode_replace_table[3]["WORLD_MATRIX"]="modelview_matrix";
-	mode_replace_table[3]["PROJECTION_MATRIX"]="projection_matrix";
-	mode_replace_table[3]["EXTRA_MATRIX"]="extra_matrix";
-	mode_replace_table[3]["TIME"]="time";
-
-	mode_replace_table[4]["POSITION"]="gl_Position";
-	mode_replace_table[4]["NORMAL"]="normal";
-	mode_replace_table[4]["NORMALMAP"]="normal_map";
-	mode_replace_table[4]["NORMALMAP_DEPTH"]="normal_depth";
-	mode_replace_table[4]["UV"]="uv_interp";
-	mode_replace_table[4]["SRC_COLOR"]="color_interp";
-	mode_replace_table[4]["COLOR"]="color";
-	mode_replace_table[4]["TEXTURE"]="texture";
-	mode_replace_table[4]["TEXTURE_PIXEL_SIZE"]="texpixel_size";
-	mode_replace_table[4]["VAR1"]="var1_interp";
-	mode_replace_table[4]["VAR2"]="var2_interp";
-	mode_replace_table[4]["SCREEN_UV"]="screen_uv";
-	mode_replace_table[4]["POINT_COORD"]="gl_PointCoord";
-	mode_replace_table[4]["TIME"]="time";
-
-	mode_replace_table[5]["POSITION"]="gl_Position";
-	mode_replace_table[5]["NORMAL"]="normal";
-	mode_replace_table[5]["UV"]="uv_interp";
-	mode_replace_table[5]["COLOR"]="color";
-	mode_replace_table[5]["TEXTURE"]="texture";
-	mode_replace_table[5]["TEXTURE_PIXEL_SIZE"]="texpixel_size";
-	mode_replace_table[5]["VAR1"]="var1_interp";
-	mode_replace_table[5]["VAR2"]="var2_interp";
-	mode_replace_table[5]["LIGHT_VEC"]="light_vec";
-	mode_replace_table[5]["LIGHT_HEIGHT"]="light_height";
-	mode_replace_table[5]["LIGHT_COLOR"]="light";
-	mode_replace_table[5]["LIGHT_UV"]="light_uv";
-	mode_replace_table[5]["LIGHT"]="light_out";
-	mode_replace_table[5]["SHADOW"]="shadow_color";
-	mode_replace_table[5]["SCREEN_UV"]="screen_uv";
-	mode_replace_table[5]["POINT_COORD"]="gl_PointCoord";
-	mode_replace_table[5]["TIME"]="time";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["NORMAL"]="normal";
+	//mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["POSITION"]="IN_POSITION";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["LIGHT_DIR"]="light_dir";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["LIGHT_DIFFUSE"]="light_diffuse";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["LIGHT_SPECULAR"]="light_specular";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["EYE_VEC"]="eye_vec";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["DIFFUSE"]="mdiffuse";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["SPECULAR"]="specular";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["SPECULAR_EXP"]="specular_exp";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["SHADE_PARAM"]="shade_param";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["LIGHT"]="light";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["POINT_COORD"]="gl_PointCoord";
+	mode_replace_table[ShaderLanguage::SHADER_MATERIAL_LIGHT]["TIME"]="time";
+
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["SRC_VERTEX"]="src_vtx";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["VERTEX"]="outvec.xy";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["WORLD_VERTEX"]="outvec.xy";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["UV"]="uv_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["COLOR"]="color_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["VAR1"]="var1_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["VAR2"]="var2_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["POINT_SIZE"]="gl_PointSize";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["WORLD_MATRIX"]="modelview_matrix";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["PROJECTION_MATRIX"]="projection_matrix";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["EXTRA_MATRIX"]="extra_matrix";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX]["TIME"]="time";
+
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["POSITION"]="gl_Position";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["NORMAL"]="normal";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["NORMALMAP"]="normal_map";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["NORMALMAP_DEPTH"]="normal_depth";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["UV"]="uv_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["SRC_COLOR"]="color_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["COLOR"]="color";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["TEXTURE"]="texture";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["TEXTURE_PIXEL_SIZE"]="texpixel_size";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["VAR1"]="var1_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["VAR2"]="var2_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["SCREEN_UV"]="screen_uv";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["POINT_COORD"]="gl_PointCoord";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT]["TIME"]="time";
+
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["POSITION"]="gl_Position";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["NORMAL"]="normal";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["UV"]="uv_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["COLOR"]="color";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["TEXTURE"]="texture";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["TEXTURE_PIXEL_SIZE"]="texpixel_size";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["VAR1"]="var1_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["VAR2"]="var2_interp";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_VEC"]="light_vec";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_HEIGHT"]="light_height";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_COLOR"]="light";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_UV"]="light_uv";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT"]="light_out";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["SHADOW"]="shadow_color";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["SCREEN_UV"]="screen_uv";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["POINT_COORD"]="gl_PointCoord";
+	mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["TIME"]="time";
 
 
 
@@ -917,6 +924,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	vname_var1_interp="VAR1";
 	vname_var2_interp="VAR2";
 	vname_vertex="VERTEX";
+	vname_position = "POSITION";
 	vname_light="LIGHT";
 	vname_time="TIME";
 	vname_normalmap="NORMALMAP";

+ 4 - 1
drivers/gles2/shader_compiler_gles2.h

@@ -34,7 +34,7 @@ class ShaderCompilerGLES2 {
 
 	class Uniform;
 public:
-	class Flags;
+	struct Flags;
 private:
 
 	ShaderLanguage::ProgramNode *program_node;
@@ -55,6 +55,7 @@ private:
 	bool uses_texpixel_size;
 	bool uses_worldvec;
 	bool vertex_code_writes_vertex;
+	bool vertex_code_writes_position;
 	bool uses_shadow_color;
 
 	bool sinh_used;
@@ -76,6 +77,7 @@ private:
 	StringName vname_var1_interp;
 	StringName vname_var2_interp;
 	StringName vname_vertex;
+	StringName vname_position;
 	StringName vname_light;
 	StringName vname_time;
 	StringName vname_normalmap;
@@ -107,6 +109,7 @@ public:
 		bool uses_texpos;
 		bool uses_normalmap;
 		bool vertex_code_writes_vertex;
+		bool vertex_code_writes_position;
 		bool uses_discard;
 		bool uses_screen_uv;
 		bool use_color_interp;

+ 0 - 2
drivers/gles2/shaders/SCsub

@@ -6,5 +6,3 @@ if env['BUILDERS'].has_key('GLSL120GLES'):
 	env.GLSL120GLES('canvas_shadow.glsl');
 	env.GLSL120GLES('blur.glsl');
 	env.GLSL120GLES('copy.glsl');
-
-

+ 0 - 1
drivers/jpg/SCsub

@@ -10,4 +10,3 @@ jpg_sources = [
 env.drivers_sources+=jpg_sources
 
 #env.add_source_files(env.drivers_sources, jpg_sources)
-

+ 0 - 1
drivers/mpc/SCsub

@@ -19,4 +19,3 @@ env.add_source_files(env.drivers_sources,"*.cpp")
 #env.add_source_files(env.drivers_sources, mpc_sources)
 
 Export('env')
-

+ 0 - 1
drivers/nedmalloc/SCsub

@@ -3,4 +3,3 @@ Export('env');
 
 env.add_source_files(env.drivers_sources,"*.cpp")
 #env.add_source_files(env.drivers_sources,"*.c")
-

+ 26 - 31
drivers/nrex/README.md

@@ -18,47 +18,42 @@ More details about its use is documented in `nrex.hpp`
 
 Currently supported features:
  * Capturing `()` and non-capturing `(?:)` groups
- * Any character `.`
+ * Any character `.` (includes newlines)
  * Shorthand caracter classes `\w\W\s\S\d\D`
- * User-defined character classes such as `[A-Za-z]`
+ * POSIX character classes such as `[[:alnum:]]`
+ * Bracket expressions such as `[A-Za-z]`
  * Simple quantifiers `?`, `*` and `+`
  * Range quantifiers `{0,1}`
  * Lazy (non-greedy) quantifiers `*?`
  * Begining `^` and end `$` anchors
+ * Word boundaries `\b`
  * Alternation `|`
- * Backreferences `\1` to `\99`
-
-To do list:
+ * ASCII `\xFF` code points
  * Unicode `\uFFFF` code points
+ * Positive `(?=)` and negative `(?!)` lookahead
+ * Positive `(?<=)` and negative `(?<!)` lookbehind (fixed length and no alternations)
+ * Backreferences `\1` to `\9` (with option to expand to `\99`)
 
 ## License
 
 Copyright (c) 2015, Zher Huei Lee
 All rights reserved.
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- 1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+This software is provided 'as-is', without any express or implied
+warranty.  In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+    claim that you wrote the original software. If you use this software
+    in a product, an acknowledgment in the product documentation would
+    be appreciated but is not required.
+    
+ 2. Altered source versions must be plainly marked as such, and must not
+    be misrepresented as being the original software.
+    
+ 3. This notice may not be removed or altered from any source
+    distribution.

+ 0 - 2
drivers/nrex/SCsub

@@ -1,4 +1,3 @@
-
 Import('env')
 
 sources = [
@@ -6,4 +5,3 @@ sources = [
 	'regex.cpp',
 ]
 env.add_source_files(env.drivers_sources, sources)
-

File diff suppressed because it is too large
+ 618 - 140
drivers/nrex/nrex.cpp


+ 7 - 3
drivers/nrex/nrex.hpp

@@ -79,7 +79,8 @@ class nrex
          * This is used to provide the array size of the captures needed for
          * nrex::match() to work. The size is actually the number of capture
          * groups + one for the matching of the entire pattern. The result is
-         * always capped at 100.
+         * always capped at 10 or 100, depending on the extend option given in
+         * nrex::compile() (default 10).
          *
          * \return The number of captures
          */
@@ -95,10 +96,13 @@ class nrex
          * runtime error nrex_compile_error if it encounters a problem when
          * parsing the pattern.
          *
-         * \param The regex pattern
+         * \param pattern   The regex pattern
+         * \param extended  If true, raises the limit on number of capture
+         *                  groups and back-references to 99. Otherwise limited
+         *                  to 9. Defaults to false.
          * \return True if the pattern was succesfully compiled
          */
-        bool compile(const nrex_char* pattern);
+        bool compile(const nrex_char* pattern, bool extended = false);
 
         /*!
          * \brief Uses the pattern to search through the provided string

+ 6 - 4
drivers/nrex/regex.cpp

@@ -15,7 +15,7 @@
 
 void RegEx::_bind_methods() {
 
-	ObjectTypeDB::bind_method(_MD("compile","pattern"),&RegEx::compile);
+	ObjectTypeDB::bind_method(_MD("compile","pattern", "expanded"),&RegEx::compile, DEFVAL(true));
 	ObjectTypeDB::bind_method(_MD("find","text","start","end"),&RegEx::find, DEFVAL(0), DEFVAL(-1));
 	ObjectTypeDB::bind_method(_MD("clear"),&RegEx::clear);
 	ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid);
@@ -54,7 +54,9 @@ bool RegEx::is_valid() const {
 };
 
 int RegEx::get_capture_count() const {
-	
+
+	ERR_FAIL_COND_V( !exp.valid(), 0 );
+
 	return exp.capture_size();
 }
 
@@ -66,11 +68,11 @@ String RegEx::get_capture(int capture) const {
 
 }
 
-Error RegEx::compile(const String& p_pattern) {
+Error RegEx::compile(const String& p_pattern, bool expanded) {
 
 	clear();
 
-	exp.compile(p_pattern.c_str());
+	exp.compile(p_pattern.c_str(), expanded);
 
 	ERR_FAIL_COND_V( !exp.valid(), FAILED );
 

+ 1 - 1
drivers/nrex/regex.h

@@ -36,7 +36,7 @@ public:
 	bool is_valid() const;
 	int get_capture_count() const;
 	String get_capture(int capture) const;
-	Error compile(const String& p_pattern);
+	Error compile(const String& p_pattern, bool expanded = false);
 	int find(const String& p_text, int p_start = 0, int p_end = -1) const;
 
 	RegEx();

+ 0 - 1
drivers/ogg/SCsub

@@ -8,4 +8,3 @@ ogg_sources = [
 
 if env['theora'] != "yes" or env['use_theoraplayer_binary'] != "yes":
 	env.drivers_sources+=ogg_sources
-

+ 0 - 2
drivers/openssl/SCsub

@@ -4,5 +4,3 @@ env.add_source_files(env.drivers_sources,"*.cpp")
 env.add_source_files(env.drivers_sources,"*.c")
 
 Export('env')
-
-

+ 8 - 0
drivers/opus/opus_config.h

@@ -7,12 +7,16 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
 
+#if (!defined( _MSC_VER ) || ( _MSC_VER >= 1800 ))
+
 /* Define to 1 if you have the `lrint' function. */
 #define HAVE_LRINT 1
 
 /* Define to 1 if you have the `lrintf' function. */
 #define HAVE_LRINTF 1
 
+#endif
+
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
 
@@ -109,7 +113,11 @@
 /* Define to the equivalent of the C99 'restrict' keyword, or to
    nothing if this is not supported.  Do not define if restrict is
    supported directly.  */
+#if (!defined( _MSC_VER ) || ( _MSC_VER >= 1800 ))
 #define restrict __restrict
+#else
+#undef restrict
+#endif
 /* Work around a bug in Sun C++: it does not support _Restrict or
    __restrict__, even though the corresponding Sun C compiler ends up with
    "#define restrict _Restrict" or "#define restrict __restrict__" in the

+ 0 - 1
drivers/png/SCsub

@@ -38,4 +38,3 @@ env.drivers_sources+=png_sources
 #env.add_source_files(env.drivers_sources, png_sources)
 
 Export('env')
-

+ 0 - 1
drivers/squish/SCsub

@@ -21,4 +21,3 @@ if (env["tools"]=="yes"):
 #env.add_source_files(env.drivers_sources, squish_sources)
 
 Export('env')
-

+ 0 - 3
drivers/theora/SCsub

@@ -1,4 +1,3 @@
-
 Import('env')
 
 sources = [
@@ -34,5 +33,3 @@ sources = [
 
 if env['use_theoraplayer_binary'] != "yes":
 	env.drivers_sources += sources
-
-

+ 30 - 16
drivers/theora/decode.c

@@ -1611,28 +1611,35 @@ static void oc_filter_hedge(unsigned char *_dst,int _dst_ystride,
   int                  sum1;
   int                  bx;
   int                  by;
+  int		       _rlimit1;
+  int		       _rlimit2;
   rdst=_dst;
   rsrc=_src;
-  for(bx=0;bx<8;bx++){
+  for(bx=0;bx<8;++bx){
     cdst=rdst;
     csrc=rsrc;
-    for(by=0;by<10;by++){
+    _rlimit1 = _rlimit2 = _flimit;
+    for(by=0;by<10;++by){
       r[by]=*csrc;
       csrc+=_src_ystride;
     }
     sum0=sum1=0;
-    for(by=0;by<4;by++){
-      sum0+=abs(r[by+1]-r[by]);
-      sum1+=abs(r[by+5]-r[by+6]);
+    for(by=0;by<4;++by){
+      int sumed = abs(r[by+1]-r[by]);
+      sum0+=sumed;
+      _rlimit1-=sumed;
+      sumed = abs(r[by+5]-r[by+6]);
+      sum1+=sumed;
+      _rlimit2-=sumed;
     }
     *_variance0+=OC_MINI(255,sum0);
     *_variance1+=OC_MINI(255,sum1);
-    if(sum0<_flimit&&sum1<_flimit&&r[5]-r[4]<_qstep&&r[4]-r[5]<_qstep){
+    if(_rlimit1&&_rlimit2&&!(r[5]-r[4]-_qstep)&&!(r[4]-r[5]-_qstep)){
       *cdst=(unsigned char)(r[0]*3+r[1]*2+r[2]+r[3]+r[4]+4>>3);
       cdst+=_dst_ystride;
       *cdst=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3);
       cdst+=_dst_ystride;
-      for(by=0;by<4;by++){
+      for(by=0;by<4;++by){
         *cdst=(unsigned char)(r[by]+r[by+1]+r[by+2]+r[by+3]*2+
          r[by+4]+r[by+5]+r[by+6]+4>>3);
         cdst+=_dst_ystride;
@@ -1642,13 +1649,13 @@ static void oc_filter_hedge(unsigned char *_dst,int _dst_ystride,
       *cdst=(unsigned char)(r[5]+r[6]+r[7]+r[8]*2+r[9]*3+4>>3);
     }
     else{
-      for(by=1;by<=8;by++){
+      for(by=1;by<=8;++by){
         *cdst=(unsigned char)r[by];
         cdst+=_dst_ystride;
       }
     }
-    rdst++;
-    rsrc++;
+    ++rdst;
+    ++rsrc;
   }
 }
 
@@ -1663,19 +1670,26 @@ static void oc_filter_vedge(unsigned char *_dst,int _dst_ystride,
   int                  sum1;
   int                  bx;
   int                  by;
+  int		       _rlimit1;
+  int		       _rlimit2;
   cdst=_dst;
-  for(by=0;by<8;by++){
+  for(by=0;by<8;++by){
     rsrc=cdst-1;
     rdst=cdst;
-    for(bx=0;bx<10;bx++)r[bx]=*rsrc++;
+    for(bx=0;bx<10;++bx)r[bx]=*rsrc++;
     sum0=sum1=0;
-    for(bx=0;bx<4;bx++){
-      sum0+=abs(r[bx+1]-r[bx]);
-      sum1+=abs(r[bx+5]-r[bx+6]);
+    _rlimit1 = _rlimit2 = _flimit;
+    for(bx=0;bx<4;++bx){
+      int sumed = abs(r[bx+1]-r[bx]);
+      sum0+=sumed;
+      _rlimit1-=sumed;
+      sumed = abs(r[bx+5]-r[bx+6]);
+      sum1+=sumed;
+      _rlimit2-=sumed;
     }
     _variances[0]+=OC_MINI(255,sum0);
     _variances[1]+=OC_MINI(255,sum1);
-    if(sum0<_flimit&&sum1<_flimit&&r[5]-r[4]<_qstep&&r[4]-r[5]<_qstep){
+    if(_rlimit1&&_rlimit2&&!(r[5]-r[4]-_qstep)&&!(r[4]-r[5]-_qstep)){
       *rdst++=(unsigned char)(r[0]*3+r[1]*2+r[2]+r[3]+r[4]+4>>3);
       *rdst++=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3);
       for(bx=0;bx<4;bx++){

+ 45 - 13
drivers/theora/video_stream_theora.cpp

@@ -178,7 +178,7 @@ void VideoStreamPlaybackTheora::video_write(void){
 
 void VideoStreamPlaybackTheora::clear() {
 
-	if (file_name == "")
+	if (!file)
 		return;
 
 	if(vorbis_p){
@@ -208,6 +208,10 @@ void VideoStreamPlaybackTheora::clear() {
 	frames_pending = 0;
 	videobuf_time = 0;
 
+	if (file) {
+		memdelete(file);
+	}
+	file=NULL;
 	playing = false;
 };
 
@@ -239,7 +243,9 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
 	/* Only interested in Vorbis/Theora streams */
 	int stateflag = 0;
 
-    int audio_track_skip=audio_track;
+	int audio_track_skip=audio_track;
+
+
 	while(!stateflag){
 		int ret=buffer_data();
 		if(ret==0)break;
@@ -265,15 +271,21 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
 				copymem(&to,&test,sizeof(test));
 				theora_p=1;
 			}else if(!vorbis_p && vorbis_synthesis_headerin(&vi,&vc,&op)>=0){
+
+
 				/* it is vorbis */
-                if (audio_track_skip) {
-                    vorbis_info_clear(&vi);
-                    vorbis_comment_clear(&vc);
-                    audio_track_skip--;
-                } else {
-                    copymem(&vo,&test,sizeof(test));
-                    vorbis_p=1;
-                }
+				if (audio_track_skip) {
+					vorbis_info_clear(&vi);
+					vorbis_comment_clear(&vc);
+					ogg_stream_clear(&test);
+					vorbis_info_init(&vi);
+					vorbis_comment_init(&vc);
+
+					audio_track_skip--;
+				} else {
+                                        copymem(&vo,&test,sizeof(test));
+					vorbis_p=1;
+				}
 			}else{
 				/* whatever it is, we don't care about it */
 				ogg_stream_clear(&test);
@@ -392,6 +404,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
 		fprintf(stderr,"Ogg logical stream %lx is Vorbis %d channel %ld Hz audio.\n",
 				vo.serialno,vi.channels,vi.rate);
 		//_setup(vi.channels, vi.rate);
+
 	}else{
 		/* tear down the partial vorbis setup */
 		vorbis_info_clear(&vi);
@@ -401,6 +414,7 @@ void VideoStreamPlaybackTheora::set_file(const String& p_file) {
 	playing = false;
 	buffering=true;
 	time=0;
+	audio_frames_wrote=0;
 };
 
 float VideoStreamPlaybackTheora::get_time() const {
@@ -431,8 +445,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
 		return; //no new frames need to be produced
 
 	bool frame_done=false;
+	bool audio_done=false;
 
-	while (!frame_done) {
+	while (!frame_done || !audio_done) {
 		//a frame needs to be produced
 
 		ogg_packet op;
@@ -490,6 +505,17 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
 				audio_pending=true;
 
 
+				if (vd.granulepos>=0) {
+				//	print_line("wrote: "+itos(audio_frames_wrote)+" gpos: "+itos(vd.granulepos));
+				}
+
+				//print_line("mix audio!");
+
+				audio_frames_wrote+=ret-to_read;
+
+				//print_line("AGP: "+itos(vd.granulepos)+" added "+itos(ret-to_read));
+
+
 			} else {
 
 				/* no pending audio; is there a pending packet to decode? */
@@ -503,6 +529,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
 				};
 			}
 
+
+			audio_done = videobuf_time < (audio_frames_wrote/float(vi.rate));
+
 			if (buffer_full)
 				break;
 		}
@@ -567,7 +596,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
 			}
 		}
 	#else
-		if (!frame_done){
+
+
+		if (!frame_done || !audio_done){
 			//what's the point of waiting for audio to grab a page?
 
 			buffer_data();
@@ -709,8 +740,9 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
 	texture = Ref<ImageTexture>( memnew(ImageTexture ));
 	mix_callback=NULL;
 	mix_udata=NULL;
-    audio_track=0;
+	    audio_track=0;
 	delay_compensation=0;
+	audio_frames_wrote=0;
 };
 
 VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {

+ 2 - 1
drivers/theora/video_stream_theora.h

@@ -32,6 +32,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
 	void video_write(void);
 	float get_time() const;
 
+
 	ogg_sync_state   oy;
 	ogg_page         og;
 	ogg_stream_state vo;
@@ -122,7 +123,7 @@ public:
 
 	Ref<VideoStreamPlayback> instance_playback() {
 		Ref<VideoStreamPlaybackTheora> pb = memnew( VideoStreamPlaybackTheora );
-        pb->set_audio_track(audio_track);
+	pb->set_audio_track(audio_track);
 		pb->set_file(file);
 		return pb;
 	}

+ 0 - 2
drivers/unix/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.drivers_sources,"*.cpp")
 
 Export('env')
-
-

+ 19 - 9
drivers/unix/os_unix.cpp

@@ -65,15 +65,25 @@ void OS_Unix::print_error(const char* p_function,const char* p_file,int p_line,c
 	if (!_print_error_enabled)
 		return;
 
-	if (p_rationale && p_rationale[0]) {
-
-		print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale);
-		print("\E[0;31;40m   At: %s:%i.\E[0;0;37m\n",p_file,p_line);
-
-	} else {
-		print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code);
-		print("\E[0;31;40m   At: %s:%i.\E[0;0;37m\n",p_file,p_line);
-
+	const char* err_details;
+	if (p_rationale && p_rationale[0])
+		err_details=p_rationale;
+	else
+		err_details=p_code;
+
+	switch(p_type) {
+		case ERR_ERROR:
+			print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n",p_function,err_details);
+			print("\E[0;31m   At: %s:%i.\E[0m\n",p_file,p_line);
+			break;
+		case ERR_WARNING:
+			print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n",p_function,err_details);
+			print("\E[0;33m     At: %s:%i.\E[0m\n",p_file,p_line);
+			break;
+		case ERR_SCRIPT:
+			print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n",p_function,err_details);
+			print("\E[0;35m          At: %s:%i.\E[0m\n",p_file,p_line);
+			break;
 	}
 }
 

+ 0 - 2
drivers/vorbis/SCsub

@@ -1,4 +1,3 @@
-
 Import('env')
 
 sources = [
@@ -37,4 +36,3 @@ env.drivers_sources += sources
 
 if env['theora'] != "yes" or env['use_theoraplayer_binary'] != "yes":
 	env.drivers_sources += sources_lib
-

+ 1 - 2
drivers/vorbis/audio_stream_ogg_vorbis.cpp

@@ -289,8 +289,7 @@ Error AudioStreamPlaybackOGGVorbis::set_file(const String& p_file) {
 	const vorbis_info *vinfo=ov_info(&vf,-1);
 	stream_channels=vinfo->channels;
 	stream_srate=vinfo->rate;
-	ogg_int64_t len = ov_time_total(&vf,-1);
-	length=len/1000.0;
+	length = ov_time_total(&vf,-1);
 	ov_clear(&vf);
 	memdelete(f);
 	f=NULL;

+ 1 - 1
drivers/vorbis/audio_stream_ogg_vorbis.h

@@ -85,7 +85,7 @@ public:
 	virtual void stop();
 	virtual bool is_playing() const;
 
-	virtual void set_loop_restart_time(float p_time) { loop_restart_time=0; }
+	virtual void set_loop_restart_time(float p_time) { loop_restart_time=p_time; }
 
 	virtual void set_paused(bool p_paused);
 	virtual bool is_paused(bool p_paused) const;

+ 0 - 1
drivers/webp/SCsub

@@ -61,4 +61,3 @@ env.drivers_sources+=webp_sources
 #env.add_source_files(env.drivers_sources, webp_sources)
 
 Export('env')
-

+ 0 - 2
drivers/windows/SCsub

@@ -3,5 +3,3 @@ Import('env')
 env.add_source_files(env.drivers_sources,"*.cpp")
 
 Export('env')
-
-

+ 0 - 2
main/SCsub

@@ -8,5 +8,3 @@ Export('env')
 lib = env.Library("main",env.main_sources)
 
 env.Prepend(LIBS=[lib])
-
-

+ 23 - 16
main/main.cpp

@@ -796,7 +796,6 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 	main_args.clear();
 	
 	print_help(execpath);
-	
 
 	if (performance)
 		memdelete(performance);
@@ -812,6 +811,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 		memdelete(packed_data);
 	if (file_access_network_client)
 		memdelete(file_access_network_client);
+	if(path_remap)
+		memdelete(path_remap);
 
 // Note 1: *zip_packed_data live into *packed_data
 // Note 2: PackedData::~PackedData destroy this.
@@ -820,7 +821,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 //		memdelete( zip_packed_data );
 //#endif
 
-
+	unregister_core_driver_types();
 	unregister_core_types();
 	
 	OS::get_singleton()->_cmdline.clear();
@@ -1007,8 +1008,21 @@ bool Main::start() {
 	bool export_debug=false;
 	List<String> args = OS::get_singleton()->get_cmdline_args();
 	for (int i=0;i<args.size();i++) {
+		//parameters that do not have an argument to the right
+		if (args[i]=="-nodocbase") {
+			doc_base=false;
+		} else if (args[i]=="-noquit") {
+			noquit=true;
+		} else if (args[i]=="-convert_old") {
+			convert_old=true;
+		} else if (args[i]=="-editor" || args[i]=="-e") {
+			editor=true;
+		} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
+			game_path=args[i];
+		}
 		//parameters that have an argument to the right
-		if (i < (args.size()-1)) {
+		else if (i < (args.size()-1)) {
+			bool parsed_pair=true;
 			if (args[i]=="-doctool") {
 				doc_tool=args[i+1];
 			} else if (args[i]=="-script" || args[i]=="-s") {
@@ -1037,20 +1051,13 @@ bool Main::start() {
 			} else if (args[i]=="-dumpstrings") {
 				editor=true; //needs editor
 				dumpstrings=args[i+1];
+			} else {
+				// The parameter does not match anything known, don't skip the next argument
+				parsed_pair=false;
+			}
+			if (parsed_pair) {
+				i++;
 			}
-			i++;
-		}
-		//parameters that do not have an argument to the right
-		if (args[i]=="-nodocbase") {
-			doc_base=false;
-		} else if (args[i]=="-noquit") {
-			noquit=true;
-		} else if (args[i]=="-convert_old") {
-			convert_old=true;
-		} else if (args[i]=="-editor" || args[i]=="-e") {
-			editor=true;
-		} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
-			game_path=args[i];
 		}
 	}
 

Some files were not shown because too many files changed in this diff