Browse Source

Merge branch 'master' of https://github.com/okamstudio/godot

Mariano Javier Suligoy 10 years ago
parent
commit
3a83337420
43 changed files with 965 additions and 406 deletions
  1. 7 4
      SConstruct
  2. 27 0
      core/bind/core_bind.cpp
  3. 16 0
      core/bind/core_bind.h
  4. 3 1
      core/os/os.cpp
  5. 1 0
      core/os/os.h
  6. 142 3
      core/script_debugger_remote.cpp
  7. 27 0
      core/script_debugger_remote.h
  8. 7 0
      core/script_language.h
  9. 141 175
      doc/base/classes.xml
  10. 123 123
      doc/engine_classes.xml
  11. 4 1
      drivers/png/SCsub
  12. 8 0
      drivers/unix/os_unix.cpp
  13. 1 0
      drivers/unix/os_unix.h
  14. 1 1
      drivers/vorbis/audio_stream_ogg_vorbis.cpp
  15. 1 1
      main/main.cpp
  16. 27 9
      modules/gdscript/gd_parser.cpp
  17. 13 0
      modules/gdscript/gd_script.h
  18. 6 0
      modules/gdscript/gd_tokenizer.cpp
  19. 41 1
      platform/android/detect.py
  20. 16 11
      platform/android/export/export.cpp
  21. 4 4
      platform/bb10/export/export.cpp
  22. 4 4
      platform/javascript/export/export.cpp
  23. 4 4
      platform/osx/export/export.cpp
  24. 6 0
      platform/windows/os_windows.cpp
  25. 2 1
      platform/windows/os_windows.h
  26. 2 2
      scene/2d/canvas_item.cpp
  27. 44 1
      tools/editor/editor_import_export.cpp
  28. 4 3
      tools/editor/editor_import_export.h
  29. 20 1
      tools/editor/editor_log.cpp
  30. 3 1
      tools/editor/editor_log.h
  31. 45 32
      tools/editor/editor_node.cpp
  32. 4 2
      tools/editor/editor_node.h
  33. 1 0
      tools/editor/editor_run.h
  34. 18 1
      tools/editor/editor_run_native.cpp
  35. 5 0
      tools/editor/editor_run_native.h
  36. 32 0
      tools/editor/editor_settings.cpp
  37. 1 0
      tools/editor/editor_settings.h
  38. 0 20
      tools/editor/fileserver/editor_file_server.cpp
  39. BIN
      tools/editor/icons/icon_debug.png
  40. BIN
      tools/editor/icons/icon_remote.png
  41. 1 0
      tools/editor/plugins/script_editor_plugin.cpp
  42. 139 0
      tools/editor/script_editor_debugger.cpp
  43. 14 0
      tools/editor/script_editor_debugger.h

+ 7 - 4
SConstruct

@@ -54,13 +54,16 @@ methods.save_active_platforms(active_platforms,active_platform_ids)
 
 custom_tools=['default']
 
+platform_arg = ARGUMENTS.get("platform", False)
+
 if (os.name=="posix"):
 	pass
 elif (os.name=="nt"):
-    if (os.getenv("VSINSTALLDIR")==None):
-	custom_tools=['mingw']
+    if (os.getenv("VSINSTALLDIR")==None or platform_arg=="android"):
+		custom_tools=['mingw']
 
 env_base=Environment(tools=custom_tools,ENV = {'PATH' : os.environ['PATH']});
+
 #env_base=Environment(tools=custom_tools);
 env_base.global_defaults=global_defaults
 env_base.android_source_modules=[]
@@ -363,8 +366,8 @@ if selected_platform in platform_list:
 		
 		#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"
-		env['MSVSCLEANCOM'] = "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']

+ 27 - 0
core/bind/core_bind.cpp

@@ -494,6 +494,10 @@ uint64_t _OS::get_unix_time() const {
 	return OS::get_singleton()->get_unix_time();
 };
 
+uint64_t _OS::get_system_time_msec() const {
+	return OS::get_singleton()->get_system_time_msec();
+}
+
 void _OS::delay_usec(uint32_t p_usec) const {
 
 	OS::get_singleton()->delay_usec(p_usec);
@@ -694,6 +698,17 @@ bool _OS::is_debug_build() const {
 
 }
 
+void _OS::set_screen_orientation(ScreenOrientation p_orientation) {
+
+	OS::get_singleton()->set_screen_orientation(OS::ScreenOrientation(p_orientation));
+}
+
+_OS::ScreenOrientation _OS::get_screen_orientation() const {
+
+	return ScreenOrientation(OS::get_singleton()->get_screen_orientation());
+}
+
+
 String _OS::get_system_dir(SystemDir p_dir) const {
 
 	return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
@@ -752,6 +767,9 @@ void _OS::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_window_maximized", "enabled"),&_OS::set_window_maximized);
 	ObjectTypeDB::bind_method(_MD("is_window_maximized"),&_OS::is_window_maximized);
 
+	ObjectTypeDB::bind_method(_MD("set_screen_orientation","orientation"),&_OS::set_screen_orientation);
+	ObjectTypeDB::bind_method(_MD("get_screen_orientation"),&_OS::get_screen_orientation);
+
 
 	ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second);
 	ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second);
@@ -787,6 +805,7 @@ void _OS::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_time","utc"),&_OS::get_time,DEFVAL(false));
 	ObjectTypeDB::bind_method(_MD("get_time_zone_info"),&_OS::get_time_zone_info);
 	ObjectTypeDB::bind_method(_MD("get_unix_time"),&_OS::get_unix_time);
+	ObjectTypeDB::bind_method(_MD("get_system_time_msec"), &_OS::get_system_time_msec);
 
 	ObjectTypeDB::bind_method(_MD("set_icon"),&_OS::set_icon);
 
@@ -863,6 +882,14 @@ void _OS::_bind_methods() {
 	BIND_CONSTANT( MONTH_NOVEMBER );
 	BIND_CONSTANT( MONTH_DECEMBER );
 
+	BIND_CONSTANT( SCREEN_ORIENTATION_LANDSCAPE );
+	BIND_CONSTANT( SCREEN_ORIENTATION_PORTRAIT );
+	BIND_CONSTANT( SCREEN_ORIENTATION_REVERSE_LANDSCAPE );
+	BIND_CONSTANT( SCREEN_ORIENTATION_REVERSE_PORTRAIT );
+	BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR_LANDSCAPE );
+	BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR_PORTRAIT );
+	BIND_CONSTANT( SCREEN_ORIENTATION_SENSOR );
+
 	BIND_CONSTANT( SYSTEM_DIR_DESKTOP);
 	BIND_CONSTANT( SYSTEM_DIR_DCIM );
 	BIND_CONSTANT( SYSTEM_DIR_DOCUMENTS );

+ 16 - 0
core/bind/core_bind.h

@@ -208,6 +208,7 @@ public:
 	Dictionary get_time(bool utc) const;
 	Dictionary get_time_zone_info() const;
 	uint64_t get_unix_time() const;
+	uint64_t get_system_time_msec() const;
 
 	int get_static_memory_usage() const;
 	int get_static_memory_peak_usage() const;
@@ -239,11 +240,25 @@ public:
 		SYSTEM_DIR_RINGTONES,
 	};
 
+	enum ScreenOrientation {
+
+		SCREEN_ORIENTATION_LANDSCAPE,
+		SCREEN_ORIENTATION_PORTRAIT,
+		SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
+		SCREEN_ORIENTATION_REVERSE_PORTRAIT,
+		SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
+		SCREEN_ORIENTATION_SENSOR_PORTRAIT,
+		SCREEN_ORIENTATION_SENSOR,
+	};
+
 	String get_system_dir(SystemDir p_dir) const;
 
 
 	String get_data_dir() const;
 
+	void set_screen_orientation(ScreenOrientation p_orientation);
+	ScreenOrientation get_screen_orientation() const;
+
 	void set_time_scale(float p_scale);
 	float get_time_scale();
 
@@ -255,6 +270,7 @@ public:
 };
 
 VARIANT_ENUM_CAST(_OS::SystemDir);
+VARIANT_ENUM_CAST(_OS::ScreenOrientation);
 
 
 class _Geometry : public Object {

+ 3 - 1
core/os/os.cpp

@@ -50,7 +50,9 @@ uint64_t OS::get_unix_time() const {
 
 	return 0;
 };
-
+uint64_t OS::get_system_time_msec() const {
+	return 0;
+}
 void OS::debug_break() {
 
 	// something

+ 1 - 0
core/os/os.h

@@ -254,6 +254,7 @@ public:
 	virtual Time get_time(bool local=false) const=0;
 	virtual TimeZoneInfo get_time_zone_info() const=0;
 	virtual uint64_t get_unix_time() const;
+	virtual uint64_t get_system_time_msec() const;
 
 	virtual void delay_usec(uint32_t p_usec) const=0; 
 	virtual uint64_t get_ticks_usec() const=0;

+ 142 - 3
core/script_debugger_remote.cpp

@@ -34,7 +34,11 @@
 Error ScriptDebuggerRemote::connect_to_host(const String& p_host,uint16_t p_port) {
 
 
-    IP_Address ip = IP::get_singleton()->resolve_hostname(p_host);
+    IP_Address ip;
+    if (p_host.is_valid_ip_address())
+	    ip=p_host;
+    else
+	    ip = IP::get_singleton()->resolve_hostname(p_host);
 
 
     int port = p_port;
@@ -243,6 +247,15 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) {
 
 				if (request_scene_tree)
 					request_scene_tree(request_scene_tree_ud);
+
+			} else if (command=="breakpoint") {
+
+				bool set = cmd[3];
+				if (set)
+					insert_breakpoint(cmd[2],cmd[1]);
+				else
+					remove_breakpoint(cmd[2],cmd[1]);
+
 			} else {
 				_parse_live_edit(cmd);
 			}
@@ -289,6 +302,37 @@ void ScriptDebuggerRemote::_get_output() {
 		messages.pop_front();
 		locking=false;
 	}
+
+	while (errors.size()) {
+		locking=true;
+		packet_peer_stream->put_var("error");
+		OutputError oe = errors.front()->get();
+
+		packet_peer_stream->put_var(oe.callstack.size()+2);
+
+		Array error_data;
+
+		error_data.push_back(oe.hr);
+		error_data.push_back(oe.min);
+		error_data.push_back(oe.sec);
+		error_data.push_back(oe.msec);
+		error_data.push_back(oe.source_func);
+		error_data.push_back(oe.source_file);
+		error_data.push_back(oe.source_line);
+		error_data.push_back(oe.error);
+		error_data.push_back(oe.error_descr);
+		error_data.push_back(oe.warning);
+		packet_peer_stream->put_var(error_data);
+		packet_peer_stream->put_var(oe.callstack.size());
+		for(int i=0;i<oe.callstack.size();i++) {
+			packet_peer_stream->put_var(oe.callstack[i]);
+
+		}
+
+		errors.pop_front();
+		locking=false;
+
+	}
 	mutex->unlock();
 }
 
@@ -303,6 +347,61 @@ void ScriptDebuggerRemote::line_poll() {
 }
 
 
+void ScriptDebuggerRemote::_err_handler(void* ud,const char* p_func,const char*p_file,int p_line,const char *p_err, const char * p_descr,ErrorHandlerType p_type) {
+
+	if (p_type==ERR_HANDLER_SCRIPT)
+		return; //ignore script errors, those go through debugger
+
+	ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote*)ud;
+
+	OutputError oe;
+	oe.error=p_err;
+	oe.error_descr=p_descr;
+	oe.source_file=p_file;
+	oe.source_line=p_line;
+	oe.source_func=p_func;
+	oe.warning=p_type==ERR_HANDLER_WARNING;
+	uint64_t time = OS::get_singleton()->get_ticks_msec();
+	oe.hr=time/3600000;
+	oe.min=(time/60000)%60;
+	oe.sec=(time/1000)%60;
+	oe.msec=time%1000;
+	Array cstack;
+
+	Vector<ScriptLanguage::StackInfo> si;
+
+	for(int i=0;i<ScriptServer::get_language_count();i++) {
+		si=ScriptServer::get_language(i)->debug_get_current_stack_info();
+		if (si.size())
+			break;
+	}
+
+	cstack.resize(si.size()*2);
+	for(int i=0;i<si.size();i++) {
+		String path;
+		int line=0;
+		if (si[i].script.is_valid()) {
+			path=si[i].script->get_path();
+			line=si[i].line;
+		}
+		cstack[i*2+0]=path;
+		cstack[i*2+1]=line;
+	}
+
+	oe.callstack=cstack;
+
+
+	sdr->mutex->lock();
+
+	if (!sdr->locking && sdr->tcp_client->is_connected()) {
+
+		sdr->errors.push_back(oe);
+	}
+
+	sdr->mutex->unlock();
+}
+
+
 bool ScriptDebuggerRemote::_parse_live_edit(const Array& cmd) {
 
 	String cmdstr = cmd[0];
@@ -432,6 +531,13 @@ void ScriptDebuggerRemote::_poll_events() {
 
 			if (request_scene_tree)
 				request_scene_tree(request_scene_tree_ud);
+		} else if (command=="breakpoint") {
+
+			bool set = cmd[3];
+			if (set)
+				insert_breakpoint(cmd[2],cmd[1]);
+			else
+				remove_breakpoint(cmd[2],cmd[1]);
 		} else {
 			_parse_live_edit(cmd);
 		}
@@ -497,10 +603,35 @@ void ScriptDebuggerRemote::_print_handler(void *p_this,const String& p_string) {
 
 	ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote*)p_this;
 
+	uint64_t ticks = OS::get_singleton()->get_ticks_usec()/1000;
+	sdr->msec_count+=ticks-sdr->last_msec;
+	sdr->last_msec=ticks;
+
+	if (sdr->msec_count>1000) {
+		sdr->char_count=0;
+		sdr->msec_count=0;
+	}
+
+	String s = p_string;
+	int allowed_chars = MIN(MAX(sdr->max_cps - sdr->char_count,0), s.length());
+
+	if (allowed_chars==0)
+		return;
+
+	if (allowed_chars<s.length()) {
+		s=s.substr(0,allowed_chars);
+	}
+
+	sdr->char_count+=allowed_chars;
+
+	if (sdr->char_count>=sdr->max_cps) {
+		s+="\n[output overflow, print less text!]\n";
+	}
+
 	sdr->mutex->lock();
 	if (!sdr->locking && sdr->tcp_client->is_connected()) {
 
-		sdr->output_strings .push_back(p_string);
+		sdr->output_strings.push_back(s);
 	}
 	sdr->mutex->unlock();
 }
@@ -538,13 +669,21 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
 	poll_every=0;
 	request_scene_tree=NULL;
 	live_edit_funcs=NULL;
+	max_cps = GLOBAL_DEF("debug/max_remote_stdout_chars_per_second",2048);
+	char_count=0;
+	msec_count=0;
+	last_msec=0;
+
+	eh.errfunc=_err_handler;
+	eh.userdata=this;
+	add_error_handler(&eh);
 
 }
 
 ScriptDebuggerRemote::~ScriptDebuggerRemote() {
 
 	remove_print_handler(&phl);
+	remove_error_handler(&eh);
 	memdelete(mutex);
 
-
 }

+ 27 - 0
core/script_debugger_remote.h

@@ -49,8 +49,31 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 	Object *performance;
 	bool requested_quit;
 	Mutex *mutex;
+
+	struct OutputError {
+
+		int hr;
+		int min;
+		int sec;
+		int msec;
+		String source_file;
+		String source_func;
+		int source_line;
+		String error;
+		String error_descr;
+		bool warning;
+		Array callstack;
+
+	};
+
 	List<String> output_strings;
 	List<Message> messages;
+	List<OutputError> errors;
+
+	int max_cps;
+	int char_count;
+	uint64_t last_msec;
+	uint64_t msec_count;
 
 	bool locking; //hack to avoid a deadloop
 	static void _print_handler(void *p_this,const String& p_string);
@@ -69,6 +92,10 @@ class ScriptDebuggerRemote : public ScriptDebugger {
 
 	LiveEditFuncs *live_edit_funcs;
 
+	ErrorHandlerList eh;
+	static void _err_handler(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type);
+
+
 public:
 
 	Error connect_to_host(const String& p_host,uint16_t p_port);

+ 7 - 0
core/script_language.h

@@ -176,6 +176,13 @@ public:
 	virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems=-1,int p_max_depth=-1)=0;
 	virtual String debug_parse_stack_level_expression(int p_level,const String& p_expression,int p_max_subitems=-1,int p_max_depth=-1)=0;
 
+	struct StackInfo {
+		Ref<Script> script;
+		int line;
+	};
+
+	virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); }
+
 	/* LOADER FUNCTIONS */
 
 	virtual void get_recognized_extensions(List<String> *p_extensions) const=0;

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


File diff suppressed because it is too large
+ 123 - 123
doc/engine_classes.xml


+ 4 - 1
drivers/png/SCsub

@@ -27,7 +27,10 @@ if ("neon_enabled" in env and env["neon_enabled"]):
 	if "S_compiler" in env:
 		env_neon['CC'] = env['S_compiler']
 	env_neon.Append(CPPFLAGS=["-DPNG_ARM_NEON"])
-	png_sources.append(env_neon.Object("#drivers/png/filter_neon.S"))
+	import os
+	# Currently .ASM filter_neon.S does not compile on NT.
+	if (os.name!="nt"):
+		png_sources.append(env_neon.Object("#drivers/png/filter_neon.S"))
 
 
 env.drivers_sources+=png_sources

+ 8 - 0
drivers/unix/os_unix.cpp

@@ -223,6 +223,14 @@ uint64_t OS_Unix::get_unix_time() const {
 	return time(NULL);
 };
 
+uint64_t OS_Unix::get_system_time_msec() const {
+	struct timeval tv_now;
+	gettimeofday(&tv_now, NULL);
+	localtime(&tv_now.tv_usec);
+	uint64_t msec = tv_now.tv_usec/1000;
+	return msec;
+}
+
 
 OS::Date OS_Unix::get_date(bool utc) const {
 

+ 1 - 0
drivers/unix/os_unix.h

@@ -93,6 +93,7 @@ public:
 	virtual TimeZoneInfo get_time_zone_info() const;
 
 	virtual uint64_t get_unix_time() const;
+	virtual uint64_t get_system_time_msec() const;
 
 	virtual void delay_usec(uint32_t p_usec) const; 
 	virtual uint64_t get_ticks_usec() const;

+ 1 - 1
drivers/vorbis/audio_stream_ogg_vorbis.cpp

@@ -232,7 +232,7 @@ void AudioStreamOGGVorbis::seek_pos(float p_time) {
 
 	if (!playing)
 		return;
-	bool ok = ov_time_seek(&vf,p_time*1000)==0;
+	bool ok = ov_time_seek(&vf,p_time)==0;
 	ERR_FAIL_COND(!ok);
 	frames_mixed=stream_srate*p_time;
 }

+ 1 - 1
main/main.cpp

@@ -518,7 +518,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
 	}
 
 
-
+	GLOBAL_DEF("debug/max_remote_stdout_chars_per_second",2048);
 	if (debug_mode == "remote") {
 
 		ScriptDebuggerRemote *sdr = memnew( ScriptDebuggerRemote );

+ 27 - 9
modules/gdscript/gd_parser.cpp

@@ -2315,6 +2315,17 @@ void GDParser::_parse_class(ClassNode *p_class) {
 
 								case Variant::INT: {
 
+									if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="FLAGS") {
+
+										current_export.hint=PROPERTY_HINT_ALL_FLAGS;
+										tokenizer->advance();
+										if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
+											_set_error("Expected ')' in hint.");
+											return;
+										}
+										break;
+									}
+
 									if (tokenizer->get_token()==GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type()==Variant::STRING) {
 										//enumeration
 										current_export.hint=PROPERTY_HINT_ENUM;
@@ -2542,16 +2553,23 @@ void GDParser::_parse_class(ClassNode *p_class) {
 					} else if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
 
 						String identifier = tokenizer->get_token_identifier();
-						if (!ObjectTypeDB::is_type(identifier,"Resource")) {
-
-							current_export=PropertyInfo();
-							_set_error("Export hint not a type or resource.");
+						if (identifier == "flag") {
+							current_export.type=Variant::INT;
+							current_export.hint=PROPERTY_HINT_ALL_FLAGS;
+						}else if (identifier == "multiline"){
+							current_export.type=Variant::STRING;
+							current_export.hint=PROPERTY_HINT_MULTILINE_TEXT;
+						} else {
+							if (!ObjectTypeDB::is_type(identifier,"Resource")) {
+	
+								current_export=PropertyInfo();
+								_set_error("Export hint not a type or resource.");
+							}
+	
+							current_export.type=Variant::OBJECT;
+							current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
+							current_export.hint_string=identifier;
 						}
-
-						current_export.type=Variant::OBJECT;
-						current_export.hint=PROPERTY_HINT_RESOURCE_TYPE;
-						current_export.hint_string=identifier;
-
 						tokenizer->advance();
 					}
 

+ 13 - 0
modules/gdscript/gd_script.h

@@ -475,6 +475,19 @@ public:
     }
 
 
+	virtual Vector<StackInfo> debug_get_current_stack_info() {
+	    if (Thread::get_main_ID()!=Thread::get_caller_ID())
+		return Vector<StackInfo>();
+
+		Vector<StackInfo> csi;
+		csi.resize(_debug_call_stack_pos);
+		for(int i=0;i<_debug_call_stack_pos;i++) {
+			csi[_debug_call_stack_pos-i-1].line=_call_stack[i].line?*_call_stack[i].line:0;
+			csi[_debug_call_stack_pos-i-1].script=Ref<GDScript>(_call_stack[i].function->get_script());
+		}
+		return csi;
+	}
+
 	struct {
 
 		StringName _init;

+ 6 - 0
modules/gdscript/gd_tokenizer.cpp

@@ -97,6 +97,7 @@ const char* GDTokenizer::token_names[TK_MAX]={
 "preload",
 "assert",
 "yield",
+"signal",
 "'['",
 "']'",
 "'{'",
@@ -642,6 +643,11 @@ void GDTokenizerText::_advance() {
 						str+=res;
 
 					} else {
+						if (CharType(GETCHAR(i))=='\n') {
+							line++;
+							column=0;
+						}
+
 						str+=CharType(GETCHAR(i));
 					}
 					i++;

+ 41 - 1
platform/android/detect.py

@@ -54,13 +54,53 @@ def create(env):
 
 def configure(env):
 
+	# Workaround for MinGW. See:
+	# http://www.scons.org/wiki/LongCmdLinesOnWin32
+	import os
+	if (os.name=="nt"):
+	
+		import subprocess
+			
+		def mySubProcess(cmdline,env):
+			#print "SPAWNED : " + cmdline
+			startupinfo = subprocess.STARTUPINFO()
+			startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+			proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+				stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
+			data, err = proc.communicate()
+			rv = proc.wait()
+			if rv:
+				print "====="
+				print err
+				print "====="
+			return rv
+				
+		def mySpawn(sh, escape, cmd, args, env):
+								
+			newargs = ' '.join(args[1:])
+			cmdline = cmd + " " + newargs
+				
+			rv=0
+			if len(cmdline) > 32000 and cmd.endswith("ar") :
+				cmdline = cmd + " " + args[1] + " " + args[2] + " "
+				for i in range(3,len(args)) :
+					rv = mySubProcess( cmdline + args[i], env )
+					if rv :
+						break	
+			else:				
+				rv = mySubProcess( cmdline, env )
+					
+			return rv
+				
+		env['SPAWN'] = mySpawn
+	
 	if env['x86']=='yes':
 		env['NDK_TARGET']='x86-4.8'
 
 	if env['PLATFORM'] == 'win32':
 		import methods
 		env.Tool('gcc')
-		env['SPAWN'] = methods.win32_spawn
+		#env['SPAWN'] = methods.win32_spawn
 		env['SHLIBSUFFIX'] = '.so'
 
 #	env.android_source_modules.append("../libs/apk_expansion")	

+ 16 - 11
platform/android/export/export.cpp

@@ -228,7 +228,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
 	String get_package_name();
 
 	String get_project_name() const;
-	void _fix_manifest(Vector<uint8_t>& p_manifest);
+	void _fix_manifest(Vector<uint8_t>& p_manifest, bool p_give_internet);
 	void _fix_resources(Vector<uint8_t>& p_manifest);
 	static Error save_apk_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total);
 
@@ -249,11 +249,11 @@ public:
 	virtual int get_device_count() const;
 	virtual String get_device_name(int p_device) const;
 	virtual String get_device_info(int p_device) const;
-	virtual Error run(int p_device,bool p_dumb=false);
+	virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool requieres_password(bool p_debug) const { return !p_debug; }
 	virtual String get_binary_extension() const { return "apk"; }
-	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
+	virtual Error export_project(const String& p_path, bool p_debug, bool p_dumb=false, bool p_remote_debug=false);
 
 	virtual bool can_export(String *r_error=NULL) const;
 
@@ -608,7 +608,7 @@ String EditorExportPlatformAndroid::get_project_name() const {
 }
 
 
-void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {
+void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest,bool p_give_internet) {
 
 
 	const int CHUNK_AXML_FILE = 0x00080003;
@@ -838,7 +838,10 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector<uint8_t>& p_manifest) {
 
 						} else if (value.begins_with("godot.")) {
 							String perm = value.get_slice(".",1);
-							if (perms.has(perm)) {
+							print_line("PERM: "+perm+" HAS: "+itos(perms.has(perm)));
+
+							if (perms.has(perm) || (p_give_internet && perm=="INTERNET")) {
+
 								string_table[attr_value]="android.permission."+perm;
 							}
 
@@ -1011,7 +1014,7 @@ Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata,const String&
 
 
 
-Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb) {
+Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb,bool p_remote_debug) {
 
 	String src_apk;
 
@@ -1075,7 +1078,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
 
 		if (file=="AndroidManifest.xml") {
 
-			_fix_manifest(data);
+			_fix_manifest(data,p_dumb || p_remote_debug);
 		}
 
 		if (file=="resources.arsc") {
@@ -1153,9 +1156,11 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
 		}
 	}
 
+	gen_export_flags(cl,p_dumb,p_remote_debug);
+
 	if (p_dumb) {
 
-		String host = EditorSettings::get_singleton()->get("file_server/host");
+		/*String host = EditorSettings::get_singleton()->get("file_server/host");
 		int port = EditorSettings::get_singleton()->get("file_server/post");
 		String passwd = EditorSettings::get_singleton()->get("file_server/password");
 		cl.push_back("-rfs");
@@ -1163,7 +1168,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
 		if (passwd!="") {
 			cl.push_back("-rfs_pass");
 			cl.push_back(passwd);
-		}
+		}*/
 
 
 	} else {
@@ -1480,7 +1485,7 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) {
 
 }
 
-Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
+Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb, bool p_remote_debug) {
 
 	ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
 	device_lock->lock();
@@ -1499,7 +1504,7 @@ Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) {
 	ep.step("Exporting APK",0);
 
 	String export_to=EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpexport.apk";
-	Error err = export_project(export_to,true,p_dumb);
+	Error err = export_project(export_to,true,p_dumb,p_remote_debug);
 	if (err) {
 		device_lock->unlock();
 		return err;

+ 4 - 4
platform/bb10/export/export.cpp

@@ -67,11 +67,11 @@ public:
 	virtual int get_device_count() const;
 	virtual String get_device_name(int p_device) const;
 	virtual String get_device_info(int p_device) const;
-	virtual Error run(int p_device,bool p_dumb=false);
+	virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool requieres_password(bool p_debug) const { return !p_debug; }
 	virtual String get_binary_extension() const { return "bar"; }
-	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
+	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool can_export(String *r_error=NULL) const;
 
@@ -270,7 +270,7 @@ void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {
 
 
 
-Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, bool p_dumb) {
+Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, bool p_dumb, bool p_remote_debug) {
 
 
 	EditorProgress ep("export","Exporting for BlackBerry 10",104);
@@ -619,7 +619,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
 
 }
 
-Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) {
+Error EditorExportPlatformBB10::run(int p_device, bool p_dumb, bool p_remote_debug) {
 
 	ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
 

+ 4 - 4
platform/javascript/export/export.cpp

@@ -77,11 +77,11 @@ public:
 	virtual int get_device_count() const { return show_run?1:0; };
 	virtual String get_device_name(int p_device) const  { return "Run in Browser"; }
 	virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; }
-	virtual Error run(int p_device,bool p_dumb=false);
+	virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool requieres_password(bool p_debug) const { return false; }
 	virtual String get_binary_extension() const { return "html"; }
-	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
+	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool can_export(String *r_error=NULL) const;
 
@@ -194,7 +194,7 @@ struct JSExportData {
 
 
 
-Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, bool p_dumb) {
+Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, bool p_dumb, bool p_remote_debug) {
 
 
 	String src_template;
@@ -299,7 +299,7 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool
 }
 
 
-Error EditorExportPlatformJavaScript::run(int p_device, bool p_dumb) {
+Error EditorExportPlatformJavaScript::run(int p_device, bool p_dumb, bool p_remote_debug) {
 
 	String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html";
 	Error err = export_project(path,true,"");

+ 4 - 4
platform/osx/export/export.cpp

@@ -57,11 +57,11 @@ public:
 	virtual int get_device_count() const { return 0; };
 	virtual String get_device_name(int p_device) const  { return String(); }
 	virtual String get_device_info(int p_device) const { return String(); }
-	virtual Error run(int p_device,bool p_dumb=false);
+	virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool requieres_password(bool p_debug) const { return false; }
 	virtual String get_binary_extension() const { return "zip"; }
-	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
+	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false);
 
 	virtual bool can_export(String *r_error=NULL) const;
 
@@ -245,7 +245,7 @@ void EditorExportPlatformOSX::_fix_plist(Vector<uint8_t>& plist,const String& p_
 	}
 }
 
-Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb) {
+Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb, bool p_remote_debug) {
 
 	String src_pkg;
 
@@ -437,7 +437,7 @@ Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug
 }
 
 
-Error EditorExportPlatformOSX::run(int p_device, bool p_dumb) {
+Error EditorExportPlatformOSX::run(int p_device, bool p_dumb, bool p_remote_debug) {
 
 	return OK;
 }

+ 6 - 0
platform/windows/os_windows.cpp

@@ -1899,6 +1899,12 @@ uint64_t OS_Windows::get_unix_time() const {
 	return (*(uint64_t*)&ft - *(uint64_t*)&fep) / 10000000;
 };
 
+uint64_t OS_Windows::get_system_time_msec() const {
+	SYSTEMTIME st;
+	GetSystemTime(&st);
+	return st.wMilliseconds;
+}
+
 void OS_Windows::delay_usec(uint32_t p_usec) const {
 
         if (p_usec < 1000)

+ 2 - 1
platform/windows/os_windows.h

@@ -263,6 +263,7 @@ public:
 	virtual Time get_time(bool utc) const;
 	virtual TimeZoneInfo get_time_zone_info() const;
 	virtual uint64_t get_unix_time() const;
+	virtual uint64_t get_system_time_msec() const;
 
 	virtual bool can_draw() const;
 	virtual Error set_cwd(const String& p_cwd);
@@ -272,7 +273,7 @@ public:
 
 	virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL);
 	virtual Error kill(const ProcessID& p_pid);
-
+	
 	virtual bool has_environment(const String& p_var) const;
 	virtual String get_environment(const String& p_var) const;
 

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

@@ -1071,8 +1071,8 @@ void CanvasItem::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("draw_rect","rect","color"),&CanvasItem::draw_rect);
 	ObjectTypeDB::bind_method(_MD("draw_circle","pos","radius","color"),&CanvasItem::draw_circle);
 	ObjectTypeDB::bind_method(_MD("draw_texture","texture:Texture","pos"),&CanvasItem::draw_texture);
-	ObjectTypeDB::bind_method(_MD("draw_texture_rect","texture:Texture","rect","tile","modulate"),&CanvasItem::draw_texture_rect,DEFVAL(false),DEFVAL(Color(1,1,1)));
-	ObjectTypeDB::bind_method(_MD("draw_texture_rect_region","texture:Texture","rect","src_rect","modulate"),&CanvasItem::draw_texture_rect_region,DEFVAL(Color(1,1,1)));
+	ObjectTypeDB::bind_method(_MD("draw_texture_rect","texture:Texture","rect","tile","modulate","transpose"),&CanvasItem::draw_texture_rect,DEFVAL(Color(1,1,1)),DEFVAL(false));
+	ObjectTypeDB::bind_method(_MD("draw_texture_rect_region","texture:Texture","rect","src_rect","modulate","transpose"),&CanvasItem::draw_texture_rect_region,DEFVAL(Color(1,1,1)),DEFVAL(false));
 	ObjectTypeDB::bind_method(_MD("draw_style_box","style_box:StyleBox","rect"),&CanvasItem::draw_style_box);
 	ObjectTypeDB::bind_method(_MD("draw_primitive","points","colors","uvs","texture:Texture","width"),&CanvasItem::draw_primitive,DEFVAL(Array()),DEFVAL(Ref<Texture>()),DEFVAL(1.0));
 	ObjectTypeDB::bind_method(_MD("draw_polygon","points","colors","uvs","texture:Texture"),&CanvasItem::draw_polygon,DEFVAL(Array()),DEFVAL(Ref<Texture>()));

+ 44 - 1
tools/editor/editor_import_export.cpp

@@ -40,6 +40,7 @@
 #include "io/resource_saver.h"
 #include "io/md5.h"
 #include "io_plugins/editor_texture_import_plugin.h"
+#include "tools/editor/plugins/script_editor_plugin.h"
 
 String EditorImportPlugin::validate_source_path(const String& p_path) {
 
@@ -916,6 +917,48 @@ static int _get_pad(int p_alignment, int p_n) {
 	return pad;
 };
 
+void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, bool p_dumb, bool p_remote_debug) {
+
+	String host = EditorSettings::get_singleton()->get("network/debug_host");
+
+	if (p_dumb) {
+		int port = EditorSettings::get_singleton()->get("file_server/port");
+		String passwd = EditorSettings::get_singleton()->get("file_server/password");
+		r_flags.push_back("-rfs");
+		r_flags.push_back(host+":"+itos(port));
+		if (passwd!="") {
+			r_flags.push_back("-rfs_pass");
+			r_flags.push_back(passwd);
+		}
+	}
+
+	if (p_remote_debug) {
+
+		r_flags.push_back("-rdebug");
+		r_flags.push_back(host+":"+String::num(GLOBAL_DEF("debug/debug_port", 6007)));
+
+		List<String> breakpoints;
+		ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
+
+
+		if (breakpoints.size()) {
+
+			r_flags.push_back("-bp");
+			String bpoints;
+			for(const List<String>::Element *E=breakpoints.front();E;E=E->next()) {
+
+				bpoints+=E->get().replace(" ","%20");
+				if (E->next())
+					bpoints+=",";
+			}
+
+			r_flags.push_back(bpoints);
+		}
+
+	}
+
+}
+
 Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) {
 
 
@@ -1029,7 +1072,7 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p
 	return OK;
 }
 
-Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, bool p_dumb) {
+Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, bool p_dumb,bool p_remote_debug) {
 
 
 

+ 4 - 3
tools/editor/editor_import_export.h

@@ -104,6 +104,7 @@ protected:
 
 	};
 
+	void gen_export_flags(Vector<String> &r_flags,bool p_dumb,bool p_remote_debug);
 	static Error save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total);
 
 public:
@@ -131,14 +132,14 @@ public:
 	virtual int get_device_count() const { return 0; }
 	virtual String get_device_name(int p_device) const { return ""; }
 	virtual String get_device_info(int p_device) const { return ""; }
-	virtual Error run(int p_device,bool p_dumb=false) { return OK; }
+	virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false) { return OK; }
 
 	virtual bool can_export(String *r_error=NULL) const=0;
 
 
 	virtual bool requieres_password(bool p_debug) const { return false; }
 	virtual String get_binary_extension() const=0;
-	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false)=0;
+	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false)=0;
 
 	EditorExportPlatform() {};
 };
@@ -188,7 +189,7 @@ public:
 	virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; }
 
 	virtual String get_binary_extension() const { return binary_extension; }
-	virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false);
+	virtual Error export_project(const String& p_path, bool p_debug, bool p_dumb=false, bool p_remote_debug=false);
 	virtual void set_release_binary32(const String& p_binary) { release_binary32=p_binary; }
 	virtual void set_debug_binary32(const String& p_binary) { debug_binary32=p_binary; }
 	virtual void set_release_binary64(const String& p_binary) { release_binary64=p_binary; }

+ 20 - 1
tools/editor/editor_log.cpp

@@ -104,6 +104,17 @@ void EditorLog::_close_request() {
 }
 
 
+void EditorLog::_clear_request() {
+
+	log->clear();
+
+}
+
+void EditorLog::clear() {
+	_clear_request();
+}
+
+
 void EditorLog::add_message(const String& p_msg,bool p_error) {
 
 
@@ -167,9 +178,12 @@ void EditorLog::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("_close_request"),&EditorLog::_close_request );
 	ObjectTypeDB::bind_method(_MD("_flip_request"),&EditorLog::_flip_request );
+	ObjectTypeDB::bind_method(_MD("_clear_request"),&EditorLog::_clear_request );
+
 	//ObjectTypeDB::bind_method(_MD("_dragged"),&EditorLog::_dragged );
 	ADD_SIGNAL( MethodInfo("close_request"));
 	ADD_SIGNAL( MethodInfo("show_request"));
+	ADD_SIGNAL( MethodInfo("clear_request"));
 }
 
 EditorLog::EditorLog() {
@@ -198,6 +212,11 @@ EditorLog::EditorLog() {
 	//pd->connect("dragged",this,"_dragged");
 	//pd->set_default_cursor_shape(Control::CURSOR_MOVE);
 
+	clearbutton = memnew( Button );
+	hb->add_child(clearbutton);
+	clearbutton->set_text("Clear");
+	clearbutton->connect("pressed", this,"_clear_request");
+
 	tb = memnew( TextureButton );
 	hb->add_child(tb);
 	tb->connect("pressed",this,"_close_request");
@@ -241,8 +260,8 @@ void EditorLog::deinit() {
 
 }
 
+
 EditorLog::~EditorLog() {
 
 
 }
-

+ 3 - 1
tools/editor/editor_log.h

@@ -45,6 +45,7 @@ class EditorLog : public PanelContainer {
 	OBJ_TYPE( EditorLog, PanelContainer );
 
 	ToolButton *button;
+	Button *clearbutton;
 	Label *title;
 	RichTextLabel *log;
 	TextureButton *tb;
@@ -58,10 +59,10 @@ class EditorLog : public PanelContainer {
 
 	Thread::ID current;
 
-
 //	void _dragged(const Point2& p_ofs);
 	void _close_request();
 	void _flip_request();
+	void _clear_request();
 	static void _undo_redo_cbk(void *p_self,const String& p_name);
 protected:
 
@@ -73,6 +74,7 @@ public:
 	void deinit();
 
 	ToolButton *get_button();
+	void clear();
 	EditorLog();
 	~EditorLog();
 };

+ 45 - 32
tools/editor/editor_node.cpp

@@ -1587,7 +1587,6 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
 		Node *scene = editor_data.get_edited_scene_root();
 
 		if (!scene) {
-
 			current_option=-1;
 			//accept->get_cancel()->hide();
 			accept->get_ok()->set_text("I see..");
@@ -1668,6 +1667,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
 		editor_data.save_editor_external_data();
 	}
 
+	if (bool(EDITOR_DEF("run/always_clear_output_on_play", true))) {
+		log->clear();
+	}
+
 
 	List<String> breakpoints;
 	editor_data.get_editor_breakpoints(&breakpoints);
@@ -2365,6 +2368,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
 
 			_run(true);
 
+		} break;
+		case RUN_PLAY_NATIVE: {
+
+			emit_signal("play_pressed");
+			editor_run.run_native_notify();
+
+
 		} break;
 		case RUN_SCENE_SETTINGS: {
 
@@ -2397,32 +2407,42 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
 		case RUN_FILE_SERVER: {
 
 			//file_server
-			bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER));
+			bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER));
 
 			if (ischecked) {
 				file_server->stop();
-				fileserver_menu->set_icon(gui_base->get_icon("FileServer","EditorIcons"));
-				fileserver_menu->get_popup()->set_item_text( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server");
+				//debug_button->set_icon(gui_base->get_icon("FileServer","EditorIcons"));
+				//debug_button->get_popup()->set_item_text( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server");
 			} else {
 				file_server->start();
-				fileserver_menu->set_icon(gui_base->get_icon("FileServerActive","EditorIcons"));
-				fileserver_menu->get_popup()->set_item_text( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server");
+				//debug_button->set_icon(gui_base->get_icon("FileServerActive","EditorIcons"));
+				//debug_button->get_popup()->set_item_text( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server");
 			}
 
-			fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),!ischecked);
+			debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),!ischecked);
 
 		} break;
 		case RUN_LIVE_DEBUG: {
 
-			ScriptEditor::get_singleton()->get_debugger()->set_live_debugging(live_debug_button->is_pressed());
+			bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_LIVE_DEBUG));
+
+			debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_LIVE_DEBUG),!ischecked);
+			ScriptEditor::get_singleton()->get_debugger()->set_live_debugging(!ischecked);
 		} break;
 
 		case RUN_DEPLOY_DUMB_CLIENTS: {
 
-			bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS));
-			fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked);
+			bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS));
+			debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked);
 			run_native->set_deploy_dumb(!ischecked);
 
+		} break;
+		case RUN_DEPLOY_REMOTE_DEBUG: {
+
+			bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG));
+			debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG),!ischecked);
+			run_native->set_deploy_debug_remote(!ischecked);
+
 		} break;
 		case SETTINGS_UPDATE_ALWAYS: {
 
@@ -4604,6 +4624,7 @@ EditorNode::EditorNode() {
 	menu_hb->add_child(native_play_button);
 	native_play_button->hide();
 	native_play_button->get_popup()->connect("item_pressed",this,"_run_in_device");
+	run_native->connect("native_run",this,"_menu_option",varray(RUN_PLAY_NATIVE));
 
 //	VSeparator *s1 = memnew( VSeparator );
 //	play_hb->add_child(s1);
@@ -4624,29 +4645,21 @@ EditorNode::EditorNode() {
 	play_custom_scene_button->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY_CUSTOM_SCENE));
 	play_custom_scene_button->set_tooltip("Play custom scene ("+keycode_get_string(KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_F5)+").");
 
-	live_debug_button = memnew( ToolButton );
-	play_hb->add_child(live_debug_button);
-	live_debug_button->set_toggle_mode(true);
-	live_debug_button->set_focus_mode(Control::FOCUS_NONE);
-	live_debug_button->set_icon(gui_base->get_icon("LiveDebug","EditorIcons"));
-	live_debug_button->connect("pressed", this,"_menu_option",make_binds(RUN_LIVE_DEBUG));
-	live_debug_button->set_tooltip("Toggle Live Debugging On/Off");
-
-	fileserver_menu = memnew( MenuButton );
-	play_hb->add_child(fileserver_menu);
-	fileserver_menu->set_flat(true);
-	fileserver_menu->set_focus_mode(Control::FOCUS_NONE);
-	fileserver_menu->set_icon(gui_base->get_icon("FileServer","EditorIcons"));
-	//fileserver_menu->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY_CUSTOM_SCENE));
-	fileserver_menu->set_tooltip("Serve the project filesystem to remote clients.");
-
-	p=fileserver_menu->get_popup();
-	p->add_check_item("Enable File Server",RUN_FILE_SERVER);
-	p->set_item_tooltip(p->get_item_index(RUN_FILE_SERVER),"Enable/Disable the File Server.");
+	debug_button = memnew( MenuButton );
+	debug_button->set_flat(true);
+	play_hb->add_child(debug_button);
+	//debug_button->set_toggle_mode(true);
+	debug_button->set_focus_mode(Control::FOCUS_NONE);
+	debug_button->set_icon(gui_base->get_icon("Remote","EditorIcons"));
+	//debug_button->connect("pressed", this,"_menu_option",make_binds(RUN_LIVE_DEBUG));
+	debug_button->set_tooltip("Debug Options");
+
+	p=debug_button->get_popup();
+	p->add_check_item("Live Editing",RUN_LIVE_DEBUG);
+	p->add_check_item("File Server",RUN_FILE_SERVER);
 	p->add_separator();
-	p->add_check_item("Deploy Dumb Clients",RUN_DEPLOY_DUMB_CLIENTS);
-	//p->set_item_checked( p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),true );
-	p->set_item_tooltip(p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),"Deploy dumb clients when the File Server is active.");
+	p->add_check_item("Deploy Remote Debug",RUN_DEPLOY_REMOTE_DEBUG);
+	p->add_check_item("Deploy File Server Clients",RUN_DEPLOY_DUMB_CLIENTS);
 	p->connect("item_pressed",this,"_menu_option");
 
 	/*

+ 4 - 2
tools/editor/editor_node.h

@@ -146,6 +146,7 @@ class EditorNode : public Node {
 		RUN_PAUSE,
 		RUN_STOP,
 		RUN_PLAY_SCENE,
+		RUN_PLAY_NATIVE,
 		RUN_PLAY_CUSTOM_SCENE,
 		RUN_SCENE_SETTINGS,
 		RUN_SETTINGS,
@@ -153,6 +154,7 @@ class EditorNode : public Node {
 		RUN_FILE_SERVER,
 		RUN_DEPLOY_DUMB_CLIENTS,
 		RUN_LIVE_DEBUG,
+		RUN_DEPLOY_REMOTE_DEBUG,
 		SETTINGS_UPDATE_ALWAYS,
 		SETTINGS_UPDATE_CHANGES,
 		SETTINGS_IMPORT,
@@ -240,9 +242,9 @@ class EditorNode : public Node {
 	ToolButton *animation_menu;
 	ToolButton *play_scene_button;
 	ToolButton *play_custom_scene_button;
-	ToolButton *live_debug_button;
+	MenuButton *debug_button;
 	TextureProgress *audio_vu;
-	MenuButton *fileserver_menu;
+	//MenuButton *fileserver_menu;
 
 	TextEdit *load_errors;
 	AcceptDialog *load_error_dialog;

+ 1 - 0
tools/editor/editor_run.h

@@ -48,6 +48,7 @@ public:
 
 	Status get_status() const;
 	Error run(const String& p_scene,const String p_custom_args,const List<String>& p_breakpoints,const String& p_edited_scene);
+	void run_native_notify() { status=STATUS_PLAY; }
 	void stop();
 	EditorRun();
 };

+ 18 - 1
tools/editor/editor_run_native.cpp

@@ -101,12 +101,18 @@ void EditorRunNative::_run_native(int p_idx,const String& p_platform) {
 
 	Ref<EditorExportPlatform> eep = EditorImportExport::get_singleton()->get_export_platform(p_platform);
 	ERR_FAIL_COND(eep.is_null());
-	eep->run(p_idx,deploy_dumb);
+	if (deploy_debug_remote) {
+		emit_signal("native_run");
+
+	}
+	eep->run(p_idx,deploy_dumb,deploy_debug_remote);
 }
 
 void EditorRunNative::_bind_methods() {
 
 	ObjectTypeDB::bind_method("_run_native",&EditorRunNative::_run_native);
+
+	ADD_SIGNAL(MethodInfo("native_run"));
 }
 
 void EditorRunNative::set_deploy_dumb(bool p_enabled) {
@@ -119,10 +125,21 @@ bool EditorRunNative::is_deploy_dumb_enabled() const{
 	return deploy_dumb;
 }
 
+void EditorRunNative::set_deploy_debug_remote(bool p_enabled) {
+
+	deploy_debug_remote=p_enabled;
+}
+
+bool EditorRunNative::is_deploy_debug_remote_enabled() const{
+
+	return deploy_debug_remote;
+}
+
 
 EditorRunNative::EditorRunNative()
 {
 	set_process(true);
 	first=true;
 	deploy_dumb=false;
+	deploy_debug_remote=false;
 }

+ 5 - 0
tools/editor/editor_run_native.h

@@ -39,6 +39,7 @@ class EditorRunNative : public HBoxContainer {
 	Map<StringName,MenuButton*> menus;
 	bool first;
 	bool deploy_dumb;
+	bool deploy_debug_remote;
 
 	void _run_native(int p_idx,const String& p_platform);
 
@@ -50,6 +51,10 @@ public:
 
 	void set_deploy_dumb(bool p_enabled);
 	bool is_deploy_dumb_enabled() const;
+
+	void set_deploy_debug_remote(bool p_enabled);
+	bool is_deploy_debug_remote_enabled() const;
+
 	EditorRunNative();
 };
 

+ 32 - 0
tools/editor/editor_settings.cpp

@@ -274,6 +274,7 @@ void EditorSettings::create() {
 			print_line("EditorSettings: Load OK!");
 		}
 
+		singleton->setup_network();
 		singleton->load_favorites();
 		singleton->scan_plugins();
 
@@ -289,6 +290,7 @@ void EditorSettings::create() {
 	singleton->config_file_path=config_file_path;
 	singleton->settings_path=config_path+"/"+config_dir;
 	singleton->_load_defaults();
+	singleton->setup_network();
 	singleton->scan_plugins();
 
 
@@ -330,6 +332,35 @@ Error EditorSettings::_load_plugin(const String& p_path, Plugin &plugin) {
 	return OK;
 }
 
+void EditorSettings::setup_network() {
+
+	List<IP_Address> local_ip;
+	IP::get_singleton()->get_local_addresses(&local_ip);
+	String lip;
+	String hint;
+	String current=get("network/debug_host");
+
+	for(List<IP_Address>::Element *E=local_ip.front();E;E=E->next()) {
+
+		String ip = E->get();
+		if (ip=="127.0.0.1")
+			continue;
+
+		if (lip!="")
+			lip=ip;
+		if (ip==current)
+			lip=current; //so it saves
+		if (hint!="")
+			hint+=",";
+		hint+=ip;
+
+	}
+
+	set("network/debug_host",lip);
+	add_property_hint(PropertyInfo(Variant::STRING,"network/debug_host",PROPERTY_HINT_ENUM,hint));
+
+}
+
 void EditorSettings::scan_plugins() {
 
 	Map<String,Plugin> new_plugins;
@@ -465,6 +496,7 @@ void EditorSettings::_load_defaults() {
 	set("2d_editor/bone_selected_color",Color(0.9,0.45,0.45,0.9));
 	set("2d_editor/bone_ik_color",Color(0.9,0.9,0.45,0.9));
 
+
 	set("on_save/compress_binary_resources",true);
 	set("on_save/save_modified_external_resources",true);
 	set("on_save/save_paths_as_relative",false);

+ 1 - 0
tools/editor/editor_settings.h

@@ -113,6 +113,7 @@ public:
 
 	void scan_plugins();
 	void enable_plugins();
+	void setup_network();
 
 	void raise_order(const String& p_name);
 	static void create();

+ 0 - 20
tools/editor/fileserver/editor_file_server.cpp

@@ -318,27 +318,7 @@ EditorFileServer::EditorFileServer() {
 	cmd=CMD_NONE;
 	thread=Thread::create(_thread_start,this);
 
-	List<IP_Address> local_ip;
-	IP::get_singleton()->get_local_addresses(&local_ip);
 	EDITOR_DEF("file_server/port",6010);
-	String lip;
-	String hint;
-	for(List<IP_Address>::Element *E=local_ip.front();E;E=E->next()) {
-
-		String ip = E->get();
-		if (ip=="127.0.0.1")
-			continue;
-
-		if (lip!="")
-			lip=ip;
-		if (hint!="")
-			hint+=",";
-		hint+=ip;
-
-	}
-
-	EDITOR_DEF("file_server/host",lip);
-	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"file_server/host",PROPERTY_HINT_ENUM,hint));
 	EDITOR_DEF("file_server/password","");
 }
 

BIN
tools/editor/icons/icon_debug.png


BIN
tools/editor/icons/icon_remote.png


+ 1 - 0
tools/editor/plugins/script_editor_plugin.cpp

@@ -1101,6 +1101,7 @@ void ScriptEditor::_menu_option(int p_option) {
 			int line=current->get_text_edit()->cursor_get_line();
 			bool dobreak = !current->get_text_edit()->is_line_set_as_breakpoint(line);
 			current->get_text_edit()->set_line_as_breakpoint(line,dobreak);
+			get_debugger()->set_breakpoint(current->get_edited_script()->get_path(),line+1,dobreak);
 		} break;
 		case DEBUG_NEXT: {
 

+ 139 - 0
tools/editor/script_editor_debugger.cpp

@@ -344,6 +344,63 @@ void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_dat
 		perf_history.push_front(p);
 		perf_draw->update();
 
+	} else if (p_msg=="error") {
+
+		Array err = p_data[0];
+
+		Array vals;
+		vals.push_back(err[0]);
+		vals.push_back(err[1]);
+		vals.push_back(err[2]);
+		vals.push_back(err[3]);
+
+		bool warning = err[9];
+		bool e;
+		String time = String("%d:%02d:%02d:%04d").sprintf(vals,&e);
+		String txt=time+" - "+String(err[8]);
+
+		String tooltip="Type:"+String(warning?"Warning":"Error");
+		tooltip+="\nDescription: "+String(err[8]);
+		tooltip+="\nTime: "+time;
+		tooltip+="\nC Error: "+String(err[7]);
+		tooltip+="\nC Source: "+String(err[5])+":"+String(err[6]);
+		tooltip+="\nC Function: "+String(err[4]);
+
+
+
+		error_list->add_item(txt,EditorNode::get_singleton()->get_gui_base()->get_icon(warning?"Warning":"Error","EditorIcons"));
+		error_list->set_item_tooltip( error_list->get_item_count() -1,tooltip );
+
+		int scc = p_data[1];
+
+		Array stack;
+		stack.resize(scc);
+		for(int i=0;i<scc;i++) {
+			stack[i]=p_data[2+i];
+		}
+
+		error_list->set_item_metadata( error_list->get_item_count() -1,stack );
+
+		error_count++;
+		/*
+		int count = p_data[1];
+
+		Array cstack;
+
+		OutputError oe = errors.front()->get();
+
+		packet_peer_stream->put_var(oe.hr);
+		packet_peer_stream->put_var(oe.min);
+		packet_peer_stream->put_var(oe.sec);
+		packet_peer_stream->put_var(oe.msec);
+		packet_peer_stream->put_var(oe.source_func);
+		packet_peer_stream->put_var(oe.source_file);
+		packet_peer_stream->put_var(oe.source_line);
+		packet_peer_stream->put_var(oe.error);
+		packet_peer_stream->put_var(oe.error_descr);
+		packet_peer_stream->put_var(oe.warning);
+		packet_peer_stream->put_var(oe.callstack);
+		*/
 	} else if (p_msg=="kill_me") {
 
 		editor->call_deferred("stop_child_process");
@@ -447,10 +504,21 @@ void ScriptEditorDebugger::_notification(int p_what) {
 			scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
 			le_set->connect("pressed",this,"_live_edit_set");
 			le_clear->connect("pressed",this,"_live_edit_clear");
+			error_list->connect("item_selected",this,"_error_selected");
+			error_stack->connect("item_selected",this,"_error_stack_selected");
 
 		} break;
 		case NOTIFICATION_PROCESS: {
 
+			if (error_count!=last_error_count) {
+
+				if (error_count==0) {
+					error_split->set_name("Errors");
+				} else {
+					error_split->set_name("Errors ("+itos(error_count)+")");
+				}
+				last_error_count=error_count;
+			}
 			if (connection.is_null()) {
 
 				if (server->is_connection_available()) {
@@ -475,6 +543,9 @@ void ScriptEditorDebugger::_notification(int p_what) {
 					scene_tree->clear();
 					le_set->set_disabled(true);
 					le_clear->set_disabled(false);
+					error_list->clear();
+					error_stack->clear();
+					error_count=0;
 					//live_edit_root->set_text("/root");
 
 					update_live_edit_root();
@@ -1007,6 +1078,51 @@ void ScriptEditorDebugger::live_debug_reparent_node(const NodePath& p_at, const
 
 }
 
+void ScriptEditorDebugger::set_breakpoint(const String& p_path,int p_line,bool p_enabled) {
+
+	if (connection.is_valid()) {
+	       Array msg;
+	       msg.push_back("breakpoint");
+	       msg.push_back(p_path);
+	       msg.push_back(p_line);
+	       msg.push_back(p_enabled);
+	       ppeer->put_var(msg);
+       }
+}
+
+
+void ScriptEditorDebugger::_error_selected(int p_idx) {
+
+	error_stack->clear();
+	Array st=error_list->get_item_metadata(p_idx);
+	for(int i=0;i<st.size();i+=2) {
+
+		String script=st[i];
+		int line=st[i+1];
+		Array md;
+		md.push_back(st[i]);
+		md.push_back(st[i+1]);
+
+		String str = script.get_file()+":"+itos(line);
+
+		error_stack->add_item(str);
+		error_stack->set_item_metadata(error_stack->get_item_count()-1,md);
+		error_stack->set_item_tooltip(error_stack->get_item_count()-1,"File: "+String(st[i])+"\nLine: "+itos(line));
+	}
+}
+
+void ScriptEditorDebugger:: _error_stack_selected(int p_idx){
+
+	Array arr = error_stack->get_item_metadata(p_idx);
+	if (arr.size()!=2)
+		return;
+
+
+	Ref<Script> s = ResourceLoader::load(arr[0]);
+	emit_signal("goto_script_line",s,int(arr[1])-1);
+
+}
+
 
 void ScriptEditorDebugger::_bind_methods() {
 
@@ -1023,6 +1139,9 @@ void ScriptEditorDebugger::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_live_edit_set"),&ScriptEditorDebugger::_live_edit_set);
 	ObjectTypeDB::bind_method(_MD("_live_edit_clear"),&ScriptEditorDebugger::_live_edit_clear);
 
+	ObjectTypeDB::bind_method(_MD("_error_selected"),&ScriptEditorDebugger::_error_selected);
+	ObjectTypeDB::bind_method(_MD("_error_stack_selected"),&ScriptEditorDebugger::_error_stack_selected);
+
 	ObjectTypeDB::bind_method(_MD("live_debug_create_node"),&ScriptEditorDebugger::live_debug_create_node);
 	ObjectTypeDB::bind_method(_MD("live_debug_instance_node"),&ScriptEditorDebugger::live_debug_instance_node);
 	ObjectTypeDB::bind_method(_MD("live_debug_remove_node"),&ScriptEditorDebugger::live_debug_remove_node);
@@ -1143,6 +1262,23 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
 	vbc->add_child(hbc);
 
 
+	error_split = memnew( HSplitContainer );
+	VBoxContainer *errvb = memnew( VBoxContainer );
+	errvb->set_h_size_flags(SIZE_EXPAND_FILL);
+	error_list = memnew( ItemList );
+	errvb->add_margin_child("Errors:",error_list,true);
+	error_split->add_child(errvb);
+
+	errvb = memnew( VBoxContainer );
+	errvb->set_h_size_flags(SIZE_EXPAND_FILL);
+	error_stack = memnew( ItemList );
+	errvb->add_margin_child("Stack Trace (if applies):",error_stack,true);
+	error_split->add_child(errvb);
+
+	error_split->set_name("Errors");
+	tabs->add_child(error_split);
+
+
 	HSplitContainer *hsp = memnew( HSplitContainer );
 
 	perf_monitors = memnew(Tree);
@@ -1246,6 +1382,9 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
 	p_editor->get_undo_redo()->set_property_notify_callback(_property_changeds,this);
 	live_debug=false;
 	last_path_id=false;
+	error_count=0;
+	last_error_count=0;
+
 
 }
 

+ 14 - 0
tools/editor/script_editor_debugger.h

@@ -45,6 +45,7 @@ class TextureButton;
 class AcceptDialog;
 class TreeItem;
 class HSplitContainer;
+class ItemList;
 
 class ScriptEditorDebugger : public Control {
 
@@ -63,6 +64,14 @@ class ScriptEditorDebugger : public Control {
 	Button *le_set;
 	Button *le_clear;
 
+	HSplitContainer *error_split;
+	ItemList *error_list;
+	ItemList *error_stack;
+
+	int error_count;
+	int last_error_count;
+
+
 
 	TextureButton *tb;
 
@@ -132,6 +141,9 @@ class ScriptEditorDebugger : public Control {
 	static void _method_changeds(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE);
 	static void _property_changeds(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value);
 
+	void _error_selected(int p_idx);
+	void _error_stack_selected(int p_idx);
+
 protected:
 
 	void _notification(int p_what);
@@ -161,6 +173,8 @@ public:
 	void live_debug_duplicate_node(const NodePath& p_at,const String& p_new_name);
 	void live_debug_reparent_node(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos);
 
+	void set_breakpoint(const String& p_path,int p_line,bool p_enabled);
+
 	void update_live_edit_root();
 
 

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