Browse Source

-fixed export templates not loading/exporting on Windows
-fixed TouchScreenButton with stretch2d
-fixed(?) OSX crash on startup (test!!)
-compilation fixes on windows
-CollisionPolygon editor works again
-find buttons en find dialog
-TileMap editor cleanup (removed "error", made nicer)
-viewport flicker fixed
-make .scn default extension for saving scenes
-export the rest of the network classes to gdscript

Juan Linietsky 11 năm trước cách đây
mục cha
commit
58cda02a38
54 tập tin đã thay đổi với 1452 bổ sung1120 xóa
  1. 1 1
      core/io/file_access_network.cpp
  2. 6 2
      core/io/file_access_pack.cpp
  3. 9 6
      core/io/file_access_pack.h
  4. 2 1
      core/io/file_access_zip.cpp
  5. 1 1
      core/io/http_client.cpp
  6. 2 0
      core/io/ioapi.c
  7. 5 0
      core/io/ioapi.h
  8. 35 28
      core/io/stream_peer_tcp.cpp
  9. 48 47
      core/io/stream_peer_tcp.h
  10. 8 1
      core/io/tcp_server.cpp
  11. 2 1
      core/io/tcp_server.h
  12. 3 2
      core/io/unzip.c
  13. 3 2
      core/io/zip.c
  14. 18 0
      core/io/zip_io.h
  15. 17 0
      core/object_type_db.h
  16. 1 1
      core/os/input.h
  17. 18 1
      core/os/os.cpp
  18. 4 0
      core/os/os.h
  19. 6 6
      core/register_core_types.cpp
  20. 4 4
      core/safe_refcount.h
  21. 1 1
      core/script_debugger_remote.cpp
  22. 2 1
      drivers/gles2/rasterizer_gles2.cpp
  23. 1 1
      drivers/speex/audio_stream_speex.cpp
  24. 1 1
      drivers/speex/speex_header.c
  25. 2 1
      drivers/unix/thread_posix.cpp
  26. 1 0
      platform/android/java/src/com/android/godot/GodotLib.java
  27. 20 0
      platform/android/java_glue.cpp
  28. 1 0
      platform/android/java_glue.h
  29. 1 1
      platform/iphone/app_delegate.mm
  30. 39 125
      platform/javascript/export/export.cpp
  31. 1 1
      platform/javascript/os_javascript.cpp
  32. 1 0
      platform/osx/os_osx.mm
  33. 8 2
      platform/windows/os_windows.cpp
  34. 1 1
      platform/x11/os_x11.cpp
  35. 32 0
      scene/2d/particles_2d.cpp
  36. 8 0
      scene/2d/particles_2d.h
  37. 2 2
      scene/2d/screen_button.cpp
  38. 3 0
      scene/animation/animation_player.cpp
  39. 2 0
      scene/gui/file_dialog.cpp
  40. 3 3
      scene/resources/texture.cpp
  41. 2 2
      tools/editor/code_editor.cpp
  42. 12 0
      tools/editor/editor_icons.cpp
  43. 19 0
      tools/editor/editor_import_export.cpp
  44. 3 0
      tools/editor/editor_import_export.h
  45. 21 4
      tools/editor/editor_node.cpp
  46. 1 1
      tools/editor/fileserver/editor_file_server.cpp
  47. BIN
      tools/editor/icons/icon_mirror_x.png
  48. BIN
      tools/editor/icons/icon_mirror_y.png
  49. 14 11
      tools/editor/plugins/collision_polygon_editor_plugin.cpp
  50. 1 1
      tools/editor/plugins/tile_map_editor_plugin.cpp
  51. 47 1
      tools/editor/project_export.cpp
  52. 4 0
      tools/editor/project_export.h
  53. 856 856
      tools/editor/script_editor_debugger.cpp
  54. 149 0
      tools/html_fs/filesystem.js

+ 1 - 1
core/io/file_access_network.cpp

@@ -243,7 +243,7 @@ FileAccessNetworkClient::FileAccessNetworkClient() {
 	quit=false;
 	singleton=this;
 	last_id=0;
-	client = Ref<StreamPeerTCP>( StreamPeerTCP::create() );
+	client = Ref<StreamPeerTCP>( StreamPeerTCP::create_ref() );
 	sem=Semaphore::create();
 	lockcount=0;
 }

+ 6 - 2
core/io/file_access_pack.cpp

@@ -44,7 +44,7 @@ Error PackedData::add_pack(const String& p_path) {
 	return ERR_FILE_UNRECOGNIZED;
 };
 
-void PackedData::add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size, PackSource* p_src) {
+void PackedData::add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src) {
 
 	bool exists = files.has(path);
 
@@ -52,6 +52,8 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o
 	pf.pack=pkg_path;
 	pf.offset=ofs;
 	pf.size=size;
+	for(int i=0;i<16;i++)
+		pf.md5[i]=p_md5[i];
 	pf.src = p_src;
 
 	files[path]=pf;
@@ -163,8 +165,10 @@ bool PackedSourcePCK::try_open_pack(const String& p_path) {
 
 		uint64_t ofs = f->get_64();
 		uint64_t size = f->get_64();
+		uint8_t md5[16];
+		f->get_buffer(md5,16);
 
-		PackedData::get_singleton()->add_path(p_path, path, ofs, size, this);
+		PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5,this);
 	};
 
 	return true;

+ 9 - 6
core/io/file_access_pack.h

@@ -46,8 +46,9 @@ public:
 	struct PackedFile {
 
 		String pack;
-		uint64_t offset;
+		uint64_t offset; //if offset is ZERO, the file was ERASED
 		uint64_t size;
+		uint8_t md5[16];
 		PackSource* src;
 	};
 
@@ -72,7 +73,7 @@ private:
 public:
 
 	void add_pack_source(PackSource* p_source);
-	void add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size, PackSource* p_src); // for PackSource
+	void add_path(const String& pkg_path, const String& path, uint64_t ofs, uint64_t size,const uint8_t* p_md5, PackSource* p_src); // for PackSource
 
 	void set_disabled(bool p_disabled) { disabled=p_disabled; }
 	_FORCE_INLINE_ bool is_disabled() const { return disabled; }
@@ -150,11 +151,13 @@ public:
 
 FileAccess *PackedData::try_open_path(const String& p_path) {
 
-	if (files.has(p_path)) {
-		return files[p_path].src->get_file(p_path, &files[p_path]);
-	}
+	Map<String,PackedFile>::Element *E=files.find(p_path);
+	if (!E)
+		return NULL; //not found
+	if (E->get().offset==0)
+		return NULL; //was erased
 
-	return NULL;
+	return E->get().src->get_file(p_path, &E->get());
 }
 
 bool PackedData::has_path(const String& p_path) {

+ 2 - 1
core/io/file_access_zip.cpp

@@ -197,7 +197,8 @@ bool ZipArchive::try_open_pack(const String& p_name) {
 		String fname = String("res://") + filename_inzip;
 		files[fname] = f;
 
-		PackedData::get_singleton()->add_path(p_name, fname, 0, 0, this);
+		uint8_t md5[16]={0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0};
+		PackedData::get_singleton()->add_path(p_name, fname, 0, 0, md5, this);
 
 		if ((i+1)<gi.number_entry) {
 			unzGoToNextFile(zfile);

+ 1 - 1
core/io/http_client.cpp

@@ -620,7 +620,7 @@ void HTTPClient::_bind_methods() {
 
 HTTPClient::HTTPClient(){
 
-	tcp_connection = StreamPeerTCP::create();
+	tcp_connection = StreamPeerTCP::create_ref();
 	resolving = IP::RESOLVER_INVALID_ID;
 	status=STATUS_DISCONNECTED;
 	conn_port=80;

+ 2 - 0
core/io/ioapi.c

@@ -68,6 +68,8 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef
     p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
     p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
     p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+    p_filefunc64_32->zfile_func64.alloc_mem = p_filefunc32->alloc_mem;
+    p_filefunc64_32->zfile_func64.free_mem = p_filefunc32->free_mem;
 }
 
 /*

+ 5 - 0
core/io/ioapi.h

@@ -144,6 +144,8 @@ typedef struct zlib_filefunc_def_s
     close_file_func     zclose_file;
     testerror_file_func zerror_file;
     voidpf              opaque;
+    alloc_func alloc_mem;
+    free_func free_mem;
 } zlib_filefunc_def;
 
 typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
@@ -160,6 +162,9 @@ typedef struct zlib_filefunc64_def_s
     close_file_func     zclose_file;
     testerror_file_func zerror_file;
     voidpf              opaque;
+    alloc_func alloc_mem;
+    free_func free_mem;
+
 } zlib_filefunc64_def;
 
 void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));

+ 35 - 28
core/io/stream_peer_tcp.cpp

@@ -26,31 +26,38 @@
 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
-#include "stream_peer_tcp.h"
-
-StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL;
-
-void StreamPeerTCP::_bind_methods() {
-
-	ObjectTypeDB::bind_method(_MD("connect","host","ip"),&StreamPeerTCP::connect);
-	ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected);
-	ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host);
-	ObjectTypeDB::bind_method(_MD("get_connected_port"),&StreamPeerTCP::get_connected_port);
-	ObjectTypeDB::bind_method(_MD("disconnect"),&StreamPeerTCP::disconnect);
-}
-
-Ref<StreamPeerTCP> StreamPeerTCP::create() {
-
-	if (!_create)
-		return Ref<StreamPeerTCP>();
-	return Ref<StreamPeerTCP>(_create());
-}
-
-StreamPeerTCP::StreamPeerTCP() {
-
-}
-
-StreamPeerTCP::~StreamPeerTCP() {
-
-};
-
+#include "stream_peer_tcp.h"
+
+StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL;
+
+void StreamPeerTCP::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("connect","host","ip"),&StreamPeerTCP::connect);
+	ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected);
+	ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host);
+	ObjectTypeDB::bind_method(_MD("get_connected_port"),&StreamPeerTCP::get_connected_port);
+	ObjectTypeDB::bind_method(_MD("disconnect"),&StreamPeerTCP::disconnect);
+}
+
+Ref<StreamPeerTCP> StreamPeerTCP::create_ref() {
+
+	if (!_create)
+		return Ref<StreamPeerTCP>();
+	return Ref<StreamPeerTCP>(_create());
+}
+
+StreamPeerTCP* StreamPeerTCP::create() {
+
+	if (!_create)
+		return NULL;
+	return _create();
+}
+
+StreamPeerTCP::StreamPeerTCP() {
+
+}
+
+StreamPeerTCP::~StreamPeerTCP() {
+
+};
+

+ 48 - 47
core/io/stream_peer_tcp.h

@@ -26,50 +26,51 @@
 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
-#ifndef STREAM_PEER_TCP_H
-#define STREAM_PEER_TCP_H
-
-#include "stream_peer.h"
-
-#include "ip_address.h"
-
-class StreamPeerTCP : public StreamPeer {
-
-	OBJ_TYPE( StreamPeerTCP, StreamPeer );
-	OBJ_CATEGORY("Networking");
-
-public:
-
-	enum Status {
-
-		STATUS_NONE,
-		STATUS_CONNECTING,
-		STATUS_CONNECTED,
-		STATUS_ERROR,
-	};
-
-protected:
-
-	static StreamPeerTCP* (*_create)();
-	static void _bind_methods();
-
-public:
-
-	virtual Error connect(const IP_Address& p_host, uint16_t p_port)=0;
-
-	//read/write from streampeer
-
-	virtual bool is_connected() const=0;
-	virtual Status get_status() const=0;
-	virtual void disconnect()=0;
-	virtual IP_Address get_connected_host() const=0;
-	virtual uint16_t get_connected_port() const=0;
-	virtual void set_nodelay(bool p_enabled)=0;
-
-	static Ref<StreamPeerTCP> create();
-
-	StreamPeerTCP();
-	~StreamPeerTCP();
-};
-
-#endif
+#ifndef STREAM_PEER_TCP_H
+#define STREAM_PEER_TCP_H
+
+#include "stream_peer.h"
+
+#include "ip_address.h"
+
+class StreamPeerTCP : public StreamPeer {
+
+	OBJ_TYPE( StreamPeerTCP, StreamPeer );
+	OBJ_CATEGORY("Networking");
+
+public:
+
+	enum Status {
+
+		STATUS_NONE,
+		STATUS_CONNECTING,
+		STATUS_CONNECTED,
+		STATUS_ERROR,
+	};
+
+protected:
+
+	static StreamPeerTCP* (*_create)();
+	static void _bind_methods();
+
+public:
+
+	virtual Error connect(const IP_Address& p_host, uint16_t p_port)=0;
+
+	//read/write from streampeer
+
+	virtual bool is_connected() const=0;
+	virtual Status get_status() const=0;
+	virtual void disconnect()=0;
+	virtual IP_Address get_connected_host() const=0;
+	virtual uint16_t get_connected_port() const=0;
+	virtual void set_nodelay(bool p_enabled)=0;
+
+	static Ref<StreamPeerTCP> create_ref();
+	static StreamPeerTCP* create();
+
+	StreamPeerTCP();
+	~StreamPeerTCP();
+};
+
+#endif

+ 8 - 1
core/io/tcp_server.cpp

@@ -30,13 +30,20 @@
 
 TCP_Server* (*TCP_Server::_create)()=NULL;
 
-Ref<TCP_Server> TCP_Server::create() {
+Ref<TCP_Server> TCP_Server::create_ref() {
 
 	if (!_create)
 		return NULL;
 	return Ref<TCP_Server>(_create());
 }
 
+TCP_Server* TCP_Server::create() {
+
+	if (!_create)
+		return NULL;
+	return _create();
+}
+
 Error TCP_Server::_listen(uint16_t p_port,DVector<String> p_accepted_hosts) {
 
 	List<String> hosts;

+ 2 - 1
core/io/tcp_server.h

@@ -51,7 +51,8 @@ public:
 
 	virtual void stop()=0; //stop listening
 
-	static Ref<TCP_Server> create();
+	static Ref<TCP_Server> create_ref();
+	static TCP_Server* create();
 
 	TCP_Server();
 };

+ 3 - 2
core/io/unzip.c

@@ -1588,8 +1588,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
     }
     else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
     {
-      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
-      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.zalloc = s->z_filefunc.zfile_func64.alloc_mem;
+      pfile_in_zip_read_info->stream.zfree = s->z_filefunc.zfile_func64.free_mem;
       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
       pfile_in_zip_read_info->stream.next_in = 0;
       pfile_in_zip_read_info->stream.avail_in = 0;
@@ -1599,6 +1599,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
         pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
       else
       {
+	   printf("NO OPEN ZLIB %i\n",err);
         TRYFREE(pfile_in_zip_read_info);
         return err;
       }

+ 3 - 2
core/io/zip.c

@@ -1210,8 +1210,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename,
     {
         if(zi->ci.method == Z_DEFLATED)
         {
-          zi->ci.stream.zalloc = (alloc_func)0;
-          zi->ci.stream.zfree = (free_func)0;
+	  zi->ci.stream.zalloc = zi->z_filefunc.zfile_func64.alloc_mem;
+	  zi->ci.stream.zfree = zi->z_filefunc.zfile_func64.free_mem;
+
           zi->ci.stream.opaque = (voidpf)0;
 
           if (windowBits>0)

+ 18 - 0
core/io/zip_io.h

@@ -32,6 +32,7 @@
 #include "io/zip.h"
 #include "io/unzip.h"
 #include "os/file_access.h"
+//#include "copymem.h"
 
 static void* zipio_open(void* data, const char* p_fname, int mode) {
 
@@ -110,6 +111,21 @@ static int zipio_testerror(voidpf opaque, voidpf stream) {
 };
 
 
+
+static voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
+
+	voidpf ptr =memalloc(items*size);
+	zeromem(ptr,items*size);
+	return ptr;
+}
+
+
+static void zipio_free(voidpf opaque, voidpf address) {
+
+	memfree(address);
+}
+
+
 static zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
 
 	zlib_filefunc_def io;
@@ -121,6 +137,8 @@ static zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
 	io.zseek_file = zipio_seek;
 	io.zclose_file = zipio_close;
 	io.zerror_file = zipio_testerror;
+	io.alloc_mem=zipio_alloc;
+	io.free_mem=zipio_free;
 	return io;
 }
 

+ 17 - 0
core/object_type_db.h

@@ -205,6 +205,23 @@ public:
 		//nothing
 	}
 
+	template<class T>
+	static Object* _create_ptr_func() {
+
+		return T::create();
+	}
+
+	template<class T>
+	static void register_create_type() {
+
+		GLOBAL_LOCK_FUNCTION;
+		T::initialize_type();
+		TypeInfo *t=types.getptr(T::get_type_static());
+		ERR_FAIL_COND(!t);
+		t->creation_func=&_create_ptr_func<T>;
+		T::register_custom_data_to_otdb();
+	}
+
 	static void get_type_list( List<String> *p_types);
 	static void get_inheriters_from( const String& p_type,List<String> *p_types);
 	static String type_inherits_from(const String& p_type);

+ 1 - 1
core/os/input.h

@@ -55,7 +55,7 @@ public:
 
 	static Input *get_singleton();
 
-	virtual bool is_key_pressed(int p_scancode)=0;
+	virtual bool is_key_pressed(int p_scancode)=0;	
 	virtual bool is_mouse_button_pressed(int p_button)=0;
 	virtual bool is_joy_button_pressed(int p_device, int p_button)=0;
 	virtual bool is_action_pressed(const StringName& p_action)=0;

+ 18 - 1
core/os/os.cpp

@@ -425,8 +425,25 @@ int OS::get_processor_count() const {
 	return 1;
 }
 
-void OS::set_mouse_mode(MouseMode p_mode) {
+Error OS::native_video_play(String p_path) {
+
+	return FAILED;
+};
+
+bool OS::native_video_is_playing() {
+
+	return false;
+};
 
+void OS::native_video_pause() {
+
+};
+
+void OS::native_video_stop() {
+
+};
+
+void OS::set_mouse_mode(MouseMode p_mode) {
 
 }
 

+ 4 - 0
core/os/os.h

@@ -315,6 +315,10 @@ public:
 
 	virtual String get_unique_ID() const;
 
+	virtual Error native_video_play(String p_path);
+	virtual bool native_video_is_playing();
+	virtual void native_video_pause();
+	virtual void native_video_stop();
 
 	virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, Object* p_obj, String p_callback);
 	virtual Error dialog_input_text(String p_title, String p_description, String p_partial, Object* p_obj, String p_callback);

+ 6 - 6
core/register_core_types.cpp

@@ -106,10 +106,6 @@ void register_core_types() {
 	object_format_loader_xml = memnew( ObjectFormatLoaderInstancerXML );
 	ObjectLoader::add_object_format_loader_instancer( object_format_loader_xml );
 #endif
-	resource_saver_xml = memnew( ResourceFormatSaverXML );
-	ResourceSaver::add_resource_format_saver(resource_saver_xml);
-	resource_loader_xml = memnew( ResourceFormatLoaderXML );
-	ResourceLoader::add_resource_format_loader(resource_loader_xml);
 #endif
 #ifdef OLD_SCENE_FORMAT_ENABLED
 	object_format_saver_binary = memnew( ObjectFormatSaverInstancerBinary );
@@ -128,6 +124,10 @@ void register_core_types() {
 	resource_loader_binary = memnew( ResourceFormatLoaderBinary );
 	ResourceLoader::add_resource_format_loader(resource_loader_binary);
 
+	resource_saver_xml = memnew( ResourceFormatSaverXML );
+	ResourceSaver::add_resource_format_saver(resource_saver_xml);
+	resource_loader_xml = memnew( ResourceFormatLoaderXML );
+	ResourceLoader::add_resource_format_loader(resource_loader_xml);
 
 	ObjectTypeDB::register_type<Object>();
 
@@ -136,8 +136,8 @@ void register_core_types() {
 	ObjectTypeDB::register_type<ResourceImportMetadata>();
 	ObjectTypeDB::register_type<Resource>();
 	ObjectTypeDB::register_virtual_type<StreamPeer>();
-	ObjectTypeDB::register_virtual_type<StreamPeerTCP>();
-	ObjectTypeDB::register_virtual_type<TCP_Server>();
+	ObjectTypeDB::register_create_type<StreamPeerTCP>();
+	ObjectTypeDB::register_create_type<TCP_Server>();
 	ObjectTypeDB::register_virtual_type<IP>();
 	ObjectTypeDB::register_virtual_type<PacketPeer>();
 	ObjectTypeDB::register_type<PacketPeerStream>();

+ 4 - 4
core/safe_refcount.h

@@ -148,7 +148,7 @@ static inline int atomic_decrement( volatile int *pw) {
 
 /* PowerPC32/64 GCC */
 
-#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
+#elif ( defined( __GNUC__ ) ) && ( defined( __powerpc__ ) || defined( __ppc__ ) )
 
 #define REFCOUNT_T int
 #define REFCOUNT_GET_T int const volatile&
@@ -257,14 +257,14 @@ inline int atomic_decrement(volatile int* v)
 
 /* CW PPC */
 
-#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
+#elif ( defined( __MWERKS__ ) ) && defined( __POWERPC__ )
 
 inline long atomic_conditional_increment( register long * pw )
 {
     register int a;
 
-    asm
-    {
+	asm
+	{
 	loop:
 	
 	lwarx   a, 0, pw

+ 1 - 1
core/script_debugger_remote.cpp

@@ -415,7 +415,7 @@ void ScriptDebuggerRemote::set_request_scene_tree_message_func(RequestSceneTreeM
 
 ScriptDebuggerRemote::ScriptDebuggerRemote() {
 
-	tcp_client  = StreamPeerTCP::create();
+	tcp_client  = StreamPeerTCP::create_ref();
 	packet_peer_stream = Ref<PacketPeerStream>( memnew(PacketPeerStream) );
 	packet_peer_stream->set_stream_peer(tcp_client);
 	mutex = Mutex::create();

+ 2 - 1
drivers/gles2/rasterizer_gles2.cpp

@@ -7151,7 +7151,8 @@ void RasterizerGLES2::_update_framebuffer() {
 
 		glDeleteTextures(1,&framebuffer.sample_color);
 		glDeleteFramebuffers(1,&framebuffer.sample_fbo);
-
+		framebuffer.luminance.clear();
+		framebuffer.blur_size=0;
 		framebuffer.fbo=0;
 	}
 

+ 1 - 1
drivers/speex/audio_stream_speex.cpp

@@ -7,7 +7,7 @@
 static _FORCE_INLINE_ uint16_t le_short(uint16_t s)
 {
    uint16_t ret=s;
-#ifdef BIG_ENDIAN_ENABLED
+#if 0 //def BIG_ENDIAN_ENABLED
    ret =  s>>8;
    ret += s<<8;
 #endif

+ 1 - 1
drivers/speex/speex_header.c

@@ -47,7 +47,7 @@
 /** Convert little endian */
 static SPEEX_INLINE spx_int32_t le_int(spx_int32_t i)
 {
-#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) || defined(BIG_ENDIAN_ENABLED) )
+#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) /* || defined(BIG_ENDIAN_ENABLED) */ )
    spx_uint32_t ui, ret;
    ui = i;
    ret =  ui>>24;

+ 2 - 1
drivers/unix/thread_posix.cpp

@@ -56,7 +56,8 @@ Thread* ThreadPosix::create_func_posix(ThreadCreateCallback p_callback,void *p_u
 	tr->callback=p_callback;
 	tr->user=p_user;
 	pthread_attr_init(&tr->pthread_attr);
-	 pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE);
+	pthread_attr_setdetachstate(&tr->pthread_attr, PTHREAD_CREATE_JOINABLE);
+	pthread_attr_setstacksize(&tr->pthread_attr, 256 * 1024);
 	
 	pthread_create(&tr->pthread, &tr->pthread_attr, thread_callback, tr);
 	

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

@@ -59,5 +59,6 @@ public class GodotLib {
      public static native void method(String p_sname,String p_name,String p_ret,String[] p_params);
      public static native String getGlobal(String p_key);
 	 public static native void callobject(int p_ID, String p_method, Object[] p_params);
+	 public static native void calldeferred(int p_ID, String p_method, Object[] p_params);
 
 }

+ 20 - 0
platform/android/java_glue.cpp

@@ -1146,6 +1146,26 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env,
 	// something
 };
 
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_calldeferred(JNIEnv * env, jobject p_obj, jint ID, jstring method, jobjectArray params) {
+
+	String str_method = env->GetStringUTFChars( method, NULL );
+
+	Object* obj = ObjectDB::get_instance(ID);
+	ERR_FAIL_COND(!obj);
+
+	int count = env->GetArrayLength(params);
+	Variant args[VARIANT_ARG_MAX];
+
+	for (int i=0; i<MIN(count,VARIANT_ARG_MAX); i++) {
+
+		jobject obj = env->GetObjectArrayElement(params, i);
+		args[i] = _jobject_to_variant(env, obj);
+	};
+
+
+	obj->call_deferred(str_method, args[0],args[1],args[2],args[3],args[4]);
+	// something
+};
 
 //Main::cleanup();
 

+ 1 - 0
platform/android/java_glue.h

@@ -51,6 +51,7 @@ extern "C" {
     JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_method(JNIEnv * env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
     JNIEXPORT jstring JNICALL Java_com_android_godot_GodotLib_getGlobal(JNIEnv * env, jobject obj, jstring path);
 	JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env, jobject obj, jint ID, jstring method, jobjectArray params);
+	JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_calldeferred(JNIEnv * env, jobject obj, jint ID, jstring method, jobjectArray params);
 };
 
 

+ 1 - 1
platform/iphone/app_delegate.mm

@@ -165,7 +165,7 @@ static int frame_count = 0;
 	printf("**************** app delegate init\n");
 	CGRect rect = [[UIScreen mainScreen] bounds];
 
-	application.statusBarHidden = YES;
+	[application setStatusBarHidden:YES animation:NO];
 	// disable idle timer
 	application.idleTimerDisabled = YES;
 

+ 39 - 125
platform/javascript/export/export.cpp

@@ -60,8 +60,6 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
 
 	Ref<ImageTexture> logo;
 
-	static Error save_pack_file_js(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total);
-
 protected:
 
 	bool _set(const StringName& p_name, const Variant& p_value);
@@ -103,8 +101,6 @@ bool EditorExportPlatformJavaScript::_set(const StringName& p_name, const Varian
 		show_run=p_value;
 	else if (n=="options/memory_size")
 		max_memory=p_value;
-	else if (n=="options/pack_mode")
-		pack_mode=PackMode(int(p_value));
 	else
 		return false;
 
@@ -123,8 +119,6 @@ bool EditorExportPlatformJavaScript::_get(const StringName& p_name,Variant &r_re
 		r_ret=show_run;
 	else if (n=="options/memory_size")
 		r_ret=max_memory;
-	else if (n=="options/pack_mode")
-		r_ret=pack_mode;
 	else
 		return false;
 
@@ -134,7 +128,6 @@ void EditorExportPlatformJavaScript::_get_property_list( List<PropertyInfo> *p_l
 
 	p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_FILE,"zip"));
 	p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_FILE,"zip"));
-	p_list->push_back( PropertyInfo( Variant::INT, "options/pack_mode",PROPERTY_HINT_ENUM,"Single File, Multiple Files"));
 	p_list->push_back( PropertyInfo( Variant::INT, "options/memory_size",PROPERTY_HINT_ENUM,"32mb,64mb,128mb,256mb,512mb,1024mb"));
 	p_list->push_back( PropertyInfo( Variant::BOOL, "browser/enable_run"));
 
@@ -143,32 +136,6 @@ void EditorExportPlatformJavaScript::_get_property_list( List<PropertyInfo> *p_l
 }
 
 
-static const char* files_pre=""\
-"var Module;\n"\
-"if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');\n"\
-"if (!Module.expectedDataFileDownloads) {\n"\
-"  Module.expectedDataFileDownloads = 0;\n"\
-"  Module.finishedDataFileDownloads = 0;\n"\
-"}\n"\
-"Module.expectedDataFileDownloads++;\n"\
-"(function() {\n"\
-"\n"\
-"  function runWithFS() {\n"\
-"function assert(check, msg) {\n"\
-"  if (!check) throw msg + new Error().stack;\n"\
-"} \n";
-
-static const char* files_post=""\
-"}\n"\
-"if (Module['calledRun']) {\n"\
-"  runWithFS();\n"\
-"} else {\n"\
-"  if (!Module['preRun']) Module['preRun'] = [];\n"\
-"  Module[\"preRun\"].push(runWithFS); // FS is not initialized yet, wait for it\n"\
-"}\n"\
-"})();";
-
-
 static void _fix_html(Vector<uint8_t>& html,const String& name,int max_memory) {
 
 
@@ -178,7 +145,7 @@ static void _fix_html(Vector<uint8_t>& html,const String& name,int max_memory) {
 	Vector<String> lines=str.split("\n");
 	for(int i=0;i<lines.size();i++) {
 		if (lines[i].find("godot.js")!=-1) {
-			strnew+="<script type=\"text/javascript\" src=\""+name+"_files.js\"></script>\n";
+			strnew+="<script type=\"text/javascript\" src=\""+name+"_filesystem.js\"></script>\n";
 			strnew+="<script async type=\"text/javascript\" src=\""+name+".js\"></script>\n";
 		} else if (lines[i].find("var Module")!=-1) {
 			strnew+=lines[i];
@@ -195,65 +162,36 @@ static void _fix_html(Vector<uint8_t>& html,const String& name,int max_memory) {
 	}
 }
 
+static void _fix_files(Vector<uint8_t>& html,uint64_t p_data_size) {
 
-struct JSExportData {
-
-	EditorProgress *ep;
-	FileAccess *f;
-
-};
-
-
-static void store_file_buffer(FileAccess*f,const String& p_path,const Vector<uint8_t>& p_data) {
-
-
-	String pre = "Module['FS_createDataFile']('/', '"+p_path.replace("res://","")+"',[";
-	CharString cs = pre.utf8();
-	f->store_buffer((const uint8_t*)cs.ptr(),cs.length());
-	for(int i=0;i<p_data.size();i++) {
-
-
-		uint8_t c=',';
-		if (i>0)
-			f->store_buffer(&c,1);
-
-		uint8_t str[4];
-		uint8_t d = p_data[i];
-		if (d<10) {
-			str[0]='0'+d;
-			str[1]=0;
-			f->store_buffer(str,1);
-		} else if (d<100) {
-
-			str[0]='0'+d/10;
-			str[1]='0'+d%10;
-			str[2]=0;
-			f->store_buffer(str,2);
 
+	String str;
+	String strnew;
+	str.parse_utf8((const char*)html.ptr(),html.size());
+	Vector<String> lines=str.split("\n");
+	for(int i=0;i<lines.size();i++) {
+		if (lines[i].find("$DPLEN")!=-1) {
+			strnew+=lines[i].replace("$DPLEN",itos(p_data_size));
 		} else {
-			str[0]='0'+d/100;
-			str[1]='0'+(d/10)%10;
-			str[2]='0'+d%10;
-			str[3]=0;
-			f->store_buffer(str,3);
+			strnew+=lines[i]+"\n";
 		}
 	}
-	String post = "],true,true);\n";
-	cs = post.utf8();
-	f->store_buffer((const uint8_t*)cs.ptr(),cs.length());
+
+	CharString cs = strnew.utf8();
+	html.resize(cs.size());
+	for(int i=9;i<cs.size();i++) {
+		html[i]=cs[i];
+	}
 }
 
+struct JSExportData {
 
-Error EditorExportPlatformJavaScript::save_pack_file_js(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) {
+	EditorProgress *ep;
+	FileAccess *f;
 
-	JSExportData *ed=(JSExportData*)p_userdata;
+};
 
-	FileAccess *f=(FileAccess *)p_userdata;
-	store_file_buffer(ed->f,p_path,p_data);
-	ed->ep->step("File: "+p_path,3+p_file*100/p_total);
-	return OK;
 
-}
 
 Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p_debug,const String& p_password) {
 
@@ -279,6 +217,20 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p
 
 	ep.step("Exporting to HTML5",0);
 
+	ep.step("Finding Files..",1);
+
+	FileAccess *f=FileAccess::open(p_path.get_base_dir()+"/data.pck",FileAccess::WRITE);
+	if (!f) {
+		EditorNode::add_io_error("Could not create file for writing:\n"+p_path.basename()+"_files.js");
+		return ERR_FILE_CANT_WRITE;
+	}
+	Error err = save_pack(f);
+	size_t len = f->get_len();
+	memdelete(f);
+	if (err)
+		return err;
+
+
 	unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
 	if (!pkg) {
 
@@ -314,6 +266,11 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p
 			_fix_html(data,p_path.get_file().basename(),1<<(max_memory+5));
 			file=p_path.get_file();
 		}
+		if (file=="filesystem.js") {
+
+			_fix_files(data,len);
+			file=p_path.get_file().basename()+"_filesystem.js";
+		}
 		if (file=="godot.js") {
 
 			//_fix_godot(data);
@@ -335,49 +292,6 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p
 	}
 
 
-	ep.step("Finding Files..",1);
-
-	Vector<String> remaps;
-
-	FileAccess *f=FileAccess::open(p_path.basename()+"_files.js",FileAccess::WRITE);
-	if (!f) {
-		EditorNode::add_io_error("Could not create file for writing:\n"+p_path.basename()+"_files.js");
-		return ERR_FILE_CANT_WRITE;
-	}
-
-	f->store_buffer((const uint8_t*)files_pre,strlen(files_pre));
-
-	if (pack_mode==PACK_SINGLE_FILE) {
-
-		String ftmp = EditorSettings::get_singleton()->get_settings_path()+"/tmp/webpack.pck";
-		FileAccess *f2 = FileAccess::open(ftmp,FileAccess::WRITE);
-		if (!f2) {
-			memdelete(f);
-			return ERR_CANT_CREATE;
-		}
-		Error err = save_pack(f2,false);
-		memdelete(f2);
-		if (err) {
-			memdelete(f);
-			return ERR_CANT_CREATE;
-		}
-
-		Vector<uint8_t> data = FileAccess::get_file_as_array(ftmp);
-		store_file_buffer(f,"data.pck",data);
-
-
-	} else {
-		JSExportData ed;
-		ed.ep=&ep;
-		ed.f=f;
-
-		Error err =export_project_files(save_pack_file_js,&ed,false);
-		if (err)
-			return err;
-	}
-	f->store_buffer((const uint8_t*)files_post,strlen(files_post));
-	memdelete(f);
-
 
 	return OK;
 

+ 1 - 1
platform/javascript/os_javascript.cpp

@@ -511,7 +511,7 @@ void OS_JavaScript::process_accelerometer(const Vector3& p_accelerometer) {
 
 bool OS_JavaScript::has_touchscreen_ui_hint() const {
 
-	return true;
+	return false; //???
 }
 
 void OS_JavaScript::main_loop_request_quit() {

+ 1 - 0
platform/osx/os_osx.mm

@@ -1277,6 +1277,7 @@ OS_OSX* OS_OSX::singleton=NULL;
 
 OS_OSX::OS_OSX() {
 
+	main_loop=NULL;
 	singleton=this;
 	autoreleasePool = [[NSAutoreleasePool alloc] init];
 

+ 8 - 2
platform/windows/os_windows.cpp

@@ -1534,7 +1534,9 @@ void OS_Windows::set_icon(const Image& p_icon) {
 
 	/* Create temporary bitmap buffer */
 	int icon_len = 40 + h * w * 4;
-	BYTE *icon_bmp = (BYTE*)alloca(icon_len);
+	Vector<BYTE> v;
+	v.resize(icon_len);
+	BYTE *icon_bmp = &v[0];
 
 	encode_uint32(40,&icon_bmp[0]);
 	encode_uint32(w,&icon_bmp[4]);
@@ -1582,7 +1584,11 @@ bool OS_Windows::has_environment(const String& p_var) const {
 
 String OS_Windows::get_environment(const String& p_var) const {
 
-	return getenv(p_var.utf8().get_data());
+	char* val = getenv(p_var.utf8().get_data());
+	if (val)
+		return val;
+
+	return "";
 };
 
 String OS_Windows::get_stdin_string(bool p_block) {

+ 1 - 1
platform/x11/os_x11.cpp

@@ -1232,7 +1232,7 @@ void OS_X11::set_icon(const Image& p_icon) {
 
 		DVector<uint8_t>::Read r = img.get_data().read();
 
-		uint32_t *wr=(uint32_t*)&pd[2];
+		long *wr=(long*)&pd[2];
 
 		for(int i=0;i<w*h;i++) {
 

+ 32 - 0
scene/2d/particles_2d.cpp

@@ -880,6 +880,26 @@ float Particles2D::get_explosiveness() const{
 	return explosiveness;
 }
 
+void Particles2D::set_flip_h(bool p_flip) {
+
+	flip_h=p_flip;
+}
+
+bool Particles2D::is_flipped_h() const{
+
+	return flip_h;
+}
+
+void Particles2D::set_flip_v(bool p_flip){
+
+	flip_v=p_flip;
+}
+bool Particles2D::is_flipped_v() const{
+
+	return flip_v;
+}
+
+
 void Particles2D::set_emission_points(const DVector<Vector2>& p_points) {
 
 	emission_points=p_points;
@@ -922,6 +942,12 @@ void Particles2D::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_emissor_offset","offset"),&Particles2D::set_emissor_offset);
 	ObjectTypeDB::bind_method(_MD("get_emissor_offset"),&Particles2D::get_emissor_offset);
 
+	ObjectTypeDB::bind_method(_MD("set_flip_h","enable"),&Particles2D::set_flip_h);
+	ObjectTypeDB::bind_method(_MD("is_flipped_h"),&Particles2D::is_flipped_h);
+
+	ObjectTypeDB::bind_method(_MD("set_flip_v","enable"),&Particles2D::set_flip_v);
+	ObjectTypeDB::bind_method(_MD("is_flipped_v"),&Particles2D::is_flipped_v);
+
 	ObjectTypeDB::bind_method(_MD("set_emission_half_extents","extents"),&Particles2D::set_emission_half_extents);
 	ObjectTypeDB::bind_method(_MD("get_emission_half_extents"),&Particles2D::get_emission_half_extents);
 
@@ -958,6 +984,8 @@ void Particles2D::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"config/half_extents"),_SCS("set_emission_half_extents"),_SCS("get_emission_half_extents"));
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/local_space"),_SCS("set_use_local_space"),_SCS("is_using_local_space"));
 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"config/explosiveness",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_explosiveness"),_SCS("get_explosiveness"));
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/flip_h"),_SCS("set_flip_h"),_SCS("is_flipped_h"));
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL,"config/flip_v"),_SCS("set_flip_v"),_SCS("is_flipped_v"));
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"config/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"));
 
 
@@ -1039,6 +1067,10 @@ Particles2D::Particles2D() {
 	set_color_phase_color(2,Color(0,0,0));
 	set_color_phase_color(3,Color(0,0,0));
 
+	flip_h=false;
+	flip_v=false;
+
+
 	emit_timeout = 0;
 	time_to_live = 0;
 	explosiveness=1.0;

+ 8 - 0
scene/2d/particles_2d.h

@@ -143,6 +143,8 @@ private:
 	float emit_timeout;
 	float time_to_live;
 	float time_scale;
+	bool flip_h;
+	bool flip_v;
 	Point2 emissor_offset;
 	Vector2 initial_velocity;
 	Vector2 extents;
@@ -197,6 +199,12 @@ public:
 	void set_explosiveness(float p_value);
 	float get_explosiveness() const;
 
+	void set_flip_h(bool p_flip);
+	bool is_flipped_h() const;
+
+	void set_flip_v(bool p_flip);
+	bool is_flipped_v() const;
+
 	void set_color_phases(int p_phases);
 	int get_color_phases() const;
 

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

@@ -155,7 +155,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) {
 
 			if (finger_pressed==-1 || p_event.screen_touch.index==finger_pressed) {
 
-				Point2 coord = (get_viewport_transform() * get_global_transform()).affine_inverse().xform(Point2(p_event.screen_touch.x,p_event.screen_touch.y));
+				Point2 coord = (get_global_transform()).affine_inverse().xform(Point2(p_event.screen_touch.x,p_event.screen_touch.y));
 
 				bool touched=false;
 				if (bitmask.is_valid()) {
@@ -231,7 +231,7 @@ void TouchScreenButton::_input(const InputEvent& p_event) {
 				if (finger_pressed!=-1)
 					return; //already fingering
 
-				Point2 coord = (get_viewport_transform() * get_global_transform()).affine_inverse().xform(Point2(p_event.screen_touch.x,p_event.screen_touch.y));
+				Point2 coord = (get_global_transform()).affine_inverse().xform(Point2(p_event.screen_touch.x,p_event.screen_touch.y));
 
 				bool touched=false;
 				if (bitmask.is_valid()) {

+ 3 - 0
scene/animation/animation_player.cpp

@@ -240,6 +240,9 @@ void AnimationPlayer::_generate_node_caches(AnimationData* p_anim) {
 		p_anim->node_cache[i]=NULL;
 		RES resource;
 		Node *child = parent->get_node_and_resource(a->track_get_path(i),resource);
+		if (!child) {
+			ERR_EXPLAIN("On Animation: '"+p_anim->name+"', couldn't resolve track:  '"+String(a->track_get_path(i))+"'");
+		}
 		ERR_CONTINUE(!child); // couldn't find the child node
 		uint32_t id=resource.is_valid()?resource->get_instance_ID():child->get_instance_ID();
 		int bone_idx=-1;

+ 2 - 0
scene/gui/file_dialog.cpp

@@ -519,6 +519,8 @@ void FileDialog::_make_dir_confirm() {
 void FileDialog::_make_dir() {
 
 	makedialog->popup_centered_minsize(Size2(250,80));
+	makedirname->grab_focus();
+
 }
 
 void FileDialog::_select_drive(int p_idx) {

+ 3 - 3
scene/resources/texture.cpp

@@ -573,11 +573,11 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
 		return;
 
 	Rect2 src=p_src_rect;
-	src.pos+=rc.pos-margin.pos;
+	src.pos+=(rc.pos-margin.pos);
 	Rect2 src_c = rc.clip(src);
 	if (src_c.size==Size2())
 		return;
-	Vector2 ofs = src_c.pos-rc.pos + margin.pos;
+	Vector2 ofs = (src_c.pos-src.pos);
 
 	Vector2 scale = p_rect.size / p_src_rect.size;
 
@@ -952,7 +952,7 @@ void CubeMap::_bind_methods() {
 	BIND_CONSTANT( SIDE_BACK );
 	BIND_CONSTANT( FLAG_MIPMAPS );
 	BIND_CONSTANT( FLAG_REPEAT );
-	BIND_CONSTANT( 	FLAG_FILTER );
+	BIND_CONSTANT( FLAG_FILTER );
 	BIND_CONSTANT( FLAGS_DEFAULT );
 
 

+ 2 - 2
tools/editor/code_editor.cpp

@@ -83,7 +83,7 @@ void FindReplaceDialog::popup_search() {
 	replace_label->hide();
 	replace_vb->hide();
 	skip->hide();
-	popup_centered(Point2(300,160));
+	popup_centered(Point2(300,190));
 	get_ok()->set_text("Find");
 	search_text->grab_focus();	
 	if (text_edit->is_selection_active() && ( text_edit->get_selection_from_line() == text_edit->get_selection_to_line())) {
@@ -105,7 +105,7 @@ void FindReplaceDialog::popup_replace() {
 	replace_mc->show();
 	replace_label->show();
 	replace_vb->show();
-	popup_centered(Point2(300,250));
+	popup_centered(Point2(300,300));
 	search_text->grab_focus();
 	search_text->select_all();
 	error_label->set_text("");

+ 12 - 0
tools/editor/editor_icons.cpp

@@ -692,6 +692,11 @@ static const unsigned char icon_h_separator_png[]={
 };
 
 
+static const unsigned char icon_mirror_y_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x2,0xd,0x11,0x2f,0xe,0x84,0xa,0x80,0x6f,0x0,0x0,0x0,0x81,0x49,0x44,0x41,0x54,0x38,0xcb,0x63,0x60,0xa0,0x25,0x78,0x78,0xfb,0xf9,0x85,0x87,0xb7,0x9f,0x5f,0xc0,0xa7,0x86,0x11,0x8f,0xe6,0x8b,0xc,0xc,0xc,0xba,0x50,0xee,0x65,0x79,0x55,0x49,0x7d,0x6c,0xea,0x98,0x70,0xd9,0xc,0xd5,0xcc,0x8,0xc5,0xba,0xb8,0x5c,0xc2,0x84,0xc3,0x1,0xdb,0x19,0x18,0x18,0xaa,0x90,0xf8,0x55,0x50,0x31,0x92,0xc3,0xe0,0xff,0xc3,0xdb,0xcf,0xff,0xe3,0x53,0xc3,0x44,0x69,0x40,0x8f,0x1a,0xc0,0xc0,0xc0,0x82,0x23,0xf4,0xdb,0x19,0x18,0x18,0x3e,0x22,0xf1,0x2b,0x18,0x18,0x18,0xf8,0xe5,0x55,0x25,0x2b,0x89,0x4a,0x89,0xd0,0x44,0xa3,0x87,0x24,0xff,0x9f,0x81,0x81,0xe1,0x92,0xbc,0xaa,0xa4,0x1,0xd5,0x93,0x32,0xc5,0x99,0x89,0x62,0x0,0x0,0x9f,0x96,0x36,0xe5,0xef,0x9c,0x9,0x7d,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
 static const unsigned char icon_key_xform_png[]={
 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x8,0x8,0x6,0x0,0x0,0x0,0xc4,0xf,0xbe,0x8b,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdd,0x9,0x1c,0x14,0x1a,0x34,0xff,0x1d,0x2a,0xc5,0x0,0x0,0x0,0x96,0x49,0x44,0x41,0x54,0x18,0xd3,0x63,0x64,0x60,0x60,0x60,0x90,0xe4,0x64,0x67,0x38,0xba,0x64,0xae,0xcc,0x8f,0xd7,0x2f,0xc3,0x19,0x18,0x18,0x18,0x38,0x44,0xc5,0x57,0xfa,0x25,0x67,0x3c,0xb9,0xf2,0xe1,0xb,0x3,0xa3,0x24,0x27,0x3b,0xc3,0xbe,0x89,0x1d,0x79,0x2f,0x76,0xac,0x9d,0xc8,0x80,0x4,0x24,0x3c,0x82,0xf3,0x13,0xaa,0x1a,0x26,0x31,0xde,0x5b,0xbb,0x44,0xe6,0xe1,0xd2,0x19,0x8f,0x19,0xb0,0x0,0xf9,0xe8,0xc,0x59,0x26,0x98,0xb1,0xd8,0xc0,0x8f,0xd7,0x2f,0xc3,0x99,0x18,0x8,0x0,0x26,0xe,0x51,0xf1,0x95,0xb8,0x24,0x39,0x44,0xc5,0x57,0x32,0x79,0x25,0xa6,0x3d,0x91,0xf0,0x8,0xce,0x47,0x97,0x94,0xf0,0x8,0xce,0xf,0x4b,0xcf,0x7a,0xc2,0xc8,0xc0,0xc0,0xc0,0xa0,0x2f,0xc8,0xcb,0xb0,0x7e,0xce,0x74,0x14,0x6f,0x86,0xa6,0x65,0x3e,0x79,0xfd,0xe3,0x37,0x3,0x0,0x1f,0xf5,0x33,0x27,0xce,0x5,0x6d,0x6f,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
 };
@@ -1492,6 +1497,11 @@ static const unsigned char icon_back_no_png[]={
 };
 
 
+static const unsigned char icon_mirror_x_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x2,0xd,0x11,0x2e,0x3b,0xcb,0xa2,0x75,0xd,0x0,0x0,0x0,0x73,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x92,0x31,0xe,0x80,0x30,0xc,0x3,0xf,0x3e,0xd0,0x99,0x89,0xa9,0x2b,0xe5,0x79,0xfc,0x80,0xef,0xb5,0x5d,0x33,0x65,0xca,0xcc,0x7,0x80,0xa5,0x48,0x48,0x48,0x15,0x43,0xc7,0x7a,0x8c,0x1d,0xd9,0x8e,0x2,0x1d,0x6d,0xa1,0x62,0x51,0xc5,0xf6,0xa,0xbf,0xab,0x58,0x7c,0xcf,0xc6,0x17,0x99,0x80,0x5,0x38,0x2a,0x1e,0x7,0xb0,0x14,0x2d,0x0,0xc3,0xe3,0x5c,0x96,0x87,0x9f,0x61,0x2f,0x20,0xcf,0x7e,0x5a,0xc7,0x96,0xfd,0x93,0x8a,0x9d,0x2a,0xb6,0x55,0x34,0x5b,0xd1,0xa4,0xcf,0xd,0x66,0x3f,0x5,0x20,0x3,0xae,0xe2,0xe3,0x4a,0xf4,0xd0,0x5f,0xae,0x21,0x6e,0x17,0xf,0x33,0xa2,0x3a,0x35,0x7,0x62,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
 static const unsigned char icon_iapi_png[]={
 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x1,0x73,0x52,0x47,0x42,0x0,0xae,0xce,0x1c,0xe9,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x0,0x0,0x0,0x0,0x0,0xf9,0x43,0xbb,0x7f,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xda,0x2,0x11,0x5,0x3,0xa,0x20,0x27,0x8e,0x45,0x0,0x0,0x0,0x95,0x49,0x44,0x41,0x54,0x38,0xcb,0x63,0xfc,0xcf,0xf0,0x9f,0x1,0x1b,0x50,0x77,0x64,0xc7,0x2e,0xc1,0xc0,0xc0,0x70,0x73,0xff,0x4f,0x46,0x18,0x9b,0x5,0x97,0xe6,0xf5,0x5c,0x31,0x18,0xe2,0x81,0xdf,0x96,0x60,0x88,0x31,0x91,0xa2,0x59,0x35,0xfb,0x3c,0x86,0x38,0xb,0x36,0x67,0x63,0xb3,0x9,0x9b,0x66,0xac,0x5e,0x50,0x9d,0xd2,0x80,0xa1,0xe8,0x76,0x4e,0x3,0xae,0xe0,0xc0,0xf4,0x2,0xa9,0x80,0xbe,0x6,0xdc,0x9e,0x6a,0x88,0x12,0x85,0x24,0x19,0x80,0x4d,0x33,0x3,0x3,0x3,0x3,0x23,0x72,0x42,0x22,0x36,0xf1,0xe0,0x34,0x80,0xe2,0x30,0x60,0x64,0x60,0xfc,0x8f,0x8b,0x8d,0x4b,0xe,0x6b,0x18,0x30,0x32,0x30,0xfe,0xff,0xcf,0xf0,0x9f,0x11,0x59,0x21,0x3a,0x9f,0x60,0x20,0xa2,0x2b,0xc6,0xa6,0x19,0xaf,0x1,0xff,0x19,0xfe,0x33,0xa2,0xf3,0xd1,0xc5,0xa8,0x92,0x90,0x0,0x1,0x55,0x3c,0x7c,0x48,0xb8,0xea,0x5c,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
 };
@@ -1998,6 +2008,7 @@ void editor_register_icons(Ref<Theme> p_theme) {
 	p_theme->set_icon("GridMap","EditorIcons",make_icon(icon_grid_map_png));
 	p_theme->set_icon("TrackValue","EditorIcons",make_icon(icon_track_value_png));
 	p_theme->set_icon("HSeparator","EditorIcons",make_icon(icon_h_separator_png));
+	p_theme->set_icon("MirrorY","EditorIcons",make_icon(icon_mirror_y_png));
 	p_theme->set_icon("KeyXform","EditorIcons",make_icon(icon_key_xform_png));
 	p_theme->set_icon("ConfirmationDialog","EditorIcons",make_icon(icon_confirmation_dialog_png));
 	p_theme->set_icon("CharacterBody","EditorIcons",make_icon(icon_character_body_png));
@@ -2158,6 +2169,7 @@ void editor_register_icons(Ref<Theme> p_theme) {
 	p_theme->set_icon("Path2D","EditorIcons",make_icon(icon_path_2d_png));
 	p_theme->set_icon("CylinderShape","EditorIcons",make_icon(icon_cylinder_shape_png));
 	p_theme->set_icon("BackNo","EditorIcons",make_icon(icon_back_no_png));
+	p_theme->set_icon("MirrorX","EditorIcons",make_icon(icon_mirror_x_png));
 	p_theme->set_icon("Iapi","EditorIcons",make_icon(icon_iapi_png));
 	p_theme->set_icon("Forward","EditorIcons",make_icon(icon_forward_png));
 	p_theme->set_icon("Remove","EditorIcons",make_icon(icon_remove_png));

+ 19 - 0
tools/editor/editor_import_export.cpp

@@ -471,6 +471,18 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
 		EditorImportExport::get_singleton()->image_export_get_images_in_group(E->get(),&atlas_images);
 		atlas_images.sort_custom<StringName::AlphCompare>();
 
+		for (List<StringName>::Element *F=atlas_images.front();F;) {
+
+			List<StringName>::Element *N=F->next();
+
+			if (!FileAccess::exists(F->get())) {
+				atlas_images.erase(F);
+			}
+
+			F=N;
+
+		}
+
 		if (atlas_images.size()<=1)
 			continue;
 
@@ -814,6 +826,13 @@ Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path
 	pd->file_ofs.push_back(td);
 	pd->f->store_64(0); //ofs
 	pd->f->store_64(0); //size
+	{
+		MD5_CTX ctx;
+		MD5Init(&ctx);
+		MD5Update(&ctx,(unsigned char*)p_data.ptr(),p_data.size());
+		MD5Final(&ctx);
+		pd->f->store_buffer(ctx.digest,16);
+	}
 	pd->ep->step("Storing File: "+p_path,2+p_file*100/p_total);
 	pd->count++;
 	pd->ftmp->store_buffer(p_data.ptr(),p_data.size());

+ 3 - 0
tools/editor/editor_import_export.h

@@ -235,6 +235,7 @@ protected:
 	Map<StringName,Ref<EditorExportPlatform> > exporters;
 	Map<StringName,ImageGroup> image_groups;
 	Map<StringName,StringName> image_group_files;
+	Vector<String> diff_packs;
 
 	static EditorImportExport* singleton;
 
@@ -270,6 +271,8 @@ public:
 	void set_export_image_quality(float p_quality);
 	float get_export_image_quality() const;
 
+	Vector<String>& get_diff_packs() { return diff_packs; }
+
 	void image_export_group_create(const StringName& p_name);
 	void image_export_group_remove(const StringName& p_name);
 	bool image_export_has_group(const StringName& p_name) const;

+ 21 - 4
tools/editor/editor_node.cpp

@@ -1111,10 +1111,20 @@ void EditorNode::_dialog_action(String p_file) {
 			}
 			int ret = unzGoToFirstFile(pkg);
 
+			int fc=0; //coun them
 
-			EditorProgress p("ltask","Loading Export Templates",1);
+			while(ret==UNZ_OK) {
+				fc++;
+				ret = unzGoToNextFile(pkg);
+
+			}
+
+			ret = unzGoToFirstFile(pkg);
+
+			EditorProgress p("ltask","Loading Export Templates",fc);
 			print_line("BEGIN IMPORT");
 
+			fc=0;
 
 			while(ret==UNZ_OK) {
 
@@ -1123,19 +1133,25 @@ void EditorNode::_dialog_action(String p_file) {
 				char fname[16384];
 				ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
 
+
 				String file=fname;
 
 				Vector<uint8_t> data;
 				data.resize(info.uncompressed_size);
 
 				//read
-				unzOpenCurrentFile(pkg);
-				unzReadCurrentFile(pkg,data.ptr(),data.size());
+				ret = unzOpenCurrentFile(pkg);
+				ret = unzReadCurrentFile(pkg,data.ptr(),data.size());
 				unzCloseCurrentFile(pkg);
 
+				print_line(fname);
+				//for(int i=0;i<512;i++) {
+				//	print_line(itos(data[i]));
+				//}
+
 				file=file.get_file();
 
-				p.step("Importing: "+file,0);
+				p.step("Importing: "+file,fc);
 				print_line("IMPORT "+file);
 
 				FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_settings_path()+"/templates/"+file,FileAccess::WRITE);
@@ -1146,6 +1162,7 @@ void EditorNode::_dialog_action(String p_file) {
 				memdelete(f);
 
 				ret = unzGoToNextFile(pkg);
+				fc++;
 			}
 
 			unzClose(pkg);

+ 1 - 1
tools/editor/fileserver/editor_file_server.cpp

@@ -310,7 +310,7 @@ void EditorFileServer::stop(){
 
 EditorFileServer::EditorFileServer() {
 
-	server = TCP_Server::create();
+	server = TCP_Server::create_ref();
 	thread=Thread::create(_thread_start,this);
 	wait_mutex = Mutex::create();
 	quit=false;

BIN
tools/editor/icons/icon_mirror_x.png


BIN
tools/editor/icons/icon_mirror_y.png


+ 14 - 11
tools/editor/plugins/collision_polygon_editor_plugin.cpp

@@ -109,6 +109,7 @@ void CollisionPolygonEditor::_wip_close() {
 
 bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
 
+
 	switch(p_event.type) {
 
 		case InputEvent::MOUSE_BUTTON: {
@@ -140,11 +141,12 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
 							wip.push_back( snap_point(cpoint) );
 							wip_active=true;
 							edited_point_pos=snap_point(cpoint);
-							canvas_item_editor->update();
+							canvas_item_editor->get_viewport_control()->update();
 							edited_point=1;
 							return true;
 						} else {
 
+
 							if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
 								//wip closed
 								_wip_close();
@@ -154,7 +156,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
 
 								wip.push_back( snap_point(cpoint) );
 								edited_point=wip.size();
-								canvas_item_editor->update();
+								canvas_item_editor->get_viewport_control()->update();
 								return true;
 
 								//add wip point
@@ -218,7 +220,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
 									edited_point=closest_idx+1;
 									edited_point_pos=snap_point(xform.affine_inverse().xform(closest_pos));
 									node->set_polygon(poly);
-									canvas_item_editor->update();
+									canvas_item_editor->get_viewport_control()->update();
 									return true;
 								}
 							} else {
@@ -246,7 +248,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
 									pre_move_edit=poly;
 									edited_point=closest_idx;
 									edited_point_pos=xform.affine_inverse().xform(closest_pos);
-									canvas_item_editor->update();
+									canvas_item_editor->get_viewport_control()->update();
 									return true;
 								}
 							}
@@ -323,7 +325,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
 
 				Vector2 gpoint = Point2(mm.x,mm.y);
 				edited_point_pos = snap_point(xform.affine_inverse().xform(gpoint));
-				canvas_item_editor->update();
+				canvas_item_editor->get_viewport_control()->update();
 
 			}
 
@@ -337,6 +339,7 @@ void CollisionPolygonEditor::_canvas_draw() {
 	if (!node)
 		return;
 
+	Control *vpc = canvas_item_editor->get_viewport_control();
 
 	Vector<Vector2> poly;
 
@@ -365,8 +368,8 @@ void CollisionPolygonEditor::_canvas_draw() {
 		Vector2 next_point = xform.xform(p2);
 
 		Color col=Color(1,0.3,0.1,0.8);
-		canvas_item_editor->draw_line(point,next_point,col,2);
-		canvas_item_editor->draw_texture(handle,point-handle->get_size()*0.5);
+		vpc->draw_line(point,next_point,col,2);
+		vpc->draw_texture(handle,point-handle->get_size()*0.5);
 	}
 }
 
@@ -381,8 +384,8 @@ void CollisionPolygonEditor::edit(Node *p_collision_polygon) {
 	if (p_collision_polygon) {
 
 		node=p_collision_polygon->cast_to<CollisionPolygon2D>();
-		if (!canvas_item_editor->is_connected("draw",this,"_canvas_draw"))
-			canvas_item_editor->connect("draw",this,"_canvas_draw");
+		if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
+			canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
 		wip.clear();
 		wip_active=false;
 		edited_point=-1;
@@ -390,8 +393,8 @@ void CollisionPolygonEditor::edit(Node *p_collision_polygon) {
 	} else {
 		node=NULL;
 
-		if (canvas_item_editor->is_connected("draw",this,"_canvas_draw"))
-			canvas_item_editor->disconnect("draw",this,"_canvas_draw");
+		if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
+			canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw");
 
 	}
 

+ 1 - 1
tools/editor/plugins/tile_map_editor_plugin.cpp

@@ -608,7 +608,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
 
 	theme_panel = memnew( Panel );
 	theme_panel->set_anchor(MARGIN_BOTTOM,ANCHOR_END);
-	theme_panel->set_begin( Point2(0,20));
+	theme_panel->set_begin( Point2(0,26));
 	theme_panel->set_end( Point2(100,0) );
 	p_editor->get_viewport()->add_child(theme_panel);
 	theme_panel->hide();

+ 47 - 1
tools/editor/project_export.cpp

@@ -310,6 +310,7 @@ void ProjectExportDialog::_notification(int p_what) {
 void ProjectExportDialog::_validate_platform() {
 
 	get_ok()->set_disabled(true);
+	button_export->set_disabled(true);
 	TreeItem *selected = platforms->get_selected();
 	plat_errors->hide();
 	if (!selected) {
@@ -351,6 +352,7 @@ void ProjectExportDialog::_validate_platform() {
 	}
 
 	get_ok()->set_disabled(false);
+	button_export->set_disabled(false);
 
 }
 
@@ -385,6 +387,35 @@ void ProjectExportDialog::_export_action(const String& p_file) {
 
 }
 
+void ProjectExportDialog::_export_action_pck(const String& p_file) {
+
+	TreeItem *selected = platforms->get_selected();
+	if (!selected)
+		return;
+
+	Ref<EditorExportPlatform> exporter = EditorImportExport::get_singleton()->get_export_platform(selected->get_metadata(0));
+	if (exporter.is_null()) {
+		ERR_PRINT("Invalid platform for export of PCK");
+		return;
+	}
+	FileAccess *f = FileAccess::open(p_file,FileAccess::WRITE);
+	if (!f) {
+		error->set_text("Error exporting project PCK! Can't write");
+		error->popup_centered(Size2(300,70));;
+	}
+	ERR_FAIL_COND(!f);
+
+	Error err = exporter->save_pack(f,false);
+	memdelete(f);
+
+	if (err!=OK) {
+		error->set_text("Error exporting project!");
+		error->popup_centered(Size2(300,70));;
+		return;
+	}
+}
+
+
 Error ProjectExportDialog::export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password, bool p_quit_after) {
 
 	Ref<EditorExportPlatform> exporter = EditorImportExport::get_singleton()->get_export_platform(p_platform);
@@ -408,6 +439,12 @@ Error ProjectExportDialog::export_platform(const String& p_platform, const Strin
 }
 
 void ProjectExportDialog::ok_pressed() {
+	//export pck
+	pck_export->popup_centered_ratio();
+
+}
+void ProjectExportDialog::custom_action(const String&) {
+	//real export
 
 	TreeItem *selected = platforms->get_selected();
 	if (!selected)
@@ -909,6 +946,7 @@ void ProjectExportDialog::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_export_mode_changed"),&ProjectExportDialog::_export_mode_changed);
 	ObjectTypeDB::bind_method(_MD("_filters_edited"),&ProjectExportDialog::_filters_edited);
 	ObjectTypeDB::bind_method(_MD("_export_action"),&ProjectExportDialog::_export_action);
+	ObjectTypeDB::bind_method(_MD("_export_action_pck"),&ProjectExportDialog::_export_action_pck);
 	ObjectTypeDB::bind_method(_MD("_quality_edited"),&ProjectExportDialog::_quality_edited);
 	ObjectTypeDB::bind_method(_MD("_image_export_edited"),&ProjectExportDialog::_image_export_edited);
 	ObjectTypeDB::bind_method(_MD("_format_toggled"),&ProjectExportDialog::_format_toggled);
@@ -1201,7 +1239,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
 	add_child(confirm);
 	confirm->connect("confirmed",this,"_confirmed");
 
-	get_ok()->set_text("Export..");
+	get_ok()->set_text("Export PCK");
 
 
 	expopt="--,Export,Bundle";
@@ -1224,6 +1262,14 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
 	file_export_password->set_editable(false);
 	file_export->get_vbox()->add_margin_child("Password:",file_export_password);
 
+	pck_export = memnew( FileDialog );
+	pck_export->set_access(FileDialog::ACCESS_FILESYSTEM);
+	pck_export->set_title("Export Project PCK");
+	pck_export->connect("file_selected", this,"_export_action_pck");
+	pck_export->add_filter("*.pck ; Data Pack");
+	add_child(pck_export);
+
+	button_export = add_button("Export..",!OS::get_singleton()->get_swap_ok_cancel(),"export_pck");
 
 
 }

+ 4 - 0
tools/editor/project_export.h

@@ -80,10 +80,12 @@ private:
 
 	Tree * tree;
 
+	FileDialog *pck_export;
 	FileDialog *file_export;
 	CheckButton *file_export_check;
 	LineEdit *file_export_password;
 
+	Button *button_export;
 	String _delete_attempt;
 
 	bool updating;
@@ -162,7 +164,9 @@ private:
 	void _group_del(Object *item,int p_column, int p_button);
 
 	void _export_action(const String& p_file);
+	void _export_action_pck(const String& p_file);
 	void ok_pressed();
+	void custom_action(const String&);
 
 	void _save_export_cfg();
 	void _format_toggled();

+ 856 - 856
tools/editor/script_editor_debugger.cpp

@@ -26,859 +26,859 @@
 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 /*************************************************************************/
-#include "script_editor_debugger.h"
-#include "scene/gui/separator.h"
-#include "scene/gui/label.h"
-#include "scene/gui/split_container.h"
-#include "scene/gui/tree.h"
-#include "scene/gui/texture_button.h"
-#include "scene/gui/tab_container.h"
-#include "scene/gui/line_edit.h"
-#include "scene/gui/dialogs.h"
-#include "scene/gui/rich_text_label.h"
-#include "scene/gui/margin_container.h"
-#include "property_editor.h"
-#include "globals.h"
-#include "editor_node.h"
-#include "main/performance.h"
-
-class ScriptEditorDebuggerVariables : public Object {
-
-	OBJ_TYPE( ScriptEditorDebuggerVariables, Object );
-
-	List<PropertyInfo> props;
-	Map<StringName,Variant> values;
-protected:
-
-	bool _set(const StringName& p_name, const Variant& p_value) {
-
-		return false;
-	}
-
-	bool _get(const StringName& p_name,Variant &r_ret) const {
-
-		if (!values.has(p_name))
-			return false;
-		r_ret=values[p_name];
-		return true;
-	}
-	void _get_property_list( List<PropertyInfo> *p_list) const {
-
-		for(const List<PropertyInfo>::Element *E=props.front();E;E=E->next() )
-			p_list->push_back(E->get());
-	}
-
-
-public:
-
-
-	void clear() {
-
-		props.clear();
-		values.clear();
-	}
-
-	String get_var_value(const String& p_var) const {
-
-		for(Map<StringName,Variant>::Element *E=values.front();E;E=E->next()) {
-			String v = E->key().operator String().get_slice("/",1);
-			if (v==p_var)
-				return E->get();
-		}
-
-		return "";
-	}
-
-	void add_property(const String &p_name, const Variant& p_value) {
-
-		PropertyInfo pinfo;
-		pinfo.name=p_name;
-		pinfo.type=p_value.get_type();
-		props.push_back(pinfo);
-		values[p_name]=p_value;
-
-	}
-
-	void update() {
-		_change_notify();
-	}
-
-
-	ScriptEditorDebuggerVariables() {
-
-	}
-};
-
-void ScriptEditorDebugger::debug_next() {
-
-	ERR_FAIL_COND(!breaked);
-	ERR_FAIL_COND(connection.is_null());
-	ERR_FAIL_COND(!connection->is_connected());
-	Array msg;
-	msg.push_back("next");
-	ppeer->put_var(msg);
-	stack_dump->clear();
-	inspector->edit(NULL);
-
-}
-void ScriptEditorDebugger::debug_step() {
-
-	ERR_FAIL_COND(!breaked);
-	ERR_FAIL_COND(connection.is_null());
-	ERR_FAIL_COND(!connection->is_connected());
-
-	Array msg;
-	msg.push_back("step");
-	ppeer->put_var(msg);
-	stack_dump->clear();
-	inspector->edit(NULL);
-}
-
-void ScriptEditorDebugger::debug_break() {
-
-	ERR_FAIL_COND(breaked);
-	ERR_FAIL_COND(connection.is_null());
-	ERR_FAIL_COND(!connection->is_connected());
-
-	Array msg;
-	msg.push_back("break");
-	ppeer->put_var(msg);
-
-}
-
-void ScriptEditorDebugger::debug_continue() {
-
-	ERR_FAIL_COND(!breaked);
-	ERR_FAIL_COND(connection.is_null());
-	ERR_FAIL_COND(!connection->is_connected());
-
-	Array msg;
-	msg.push_back("continue");
-	ppeer->put_var(msg);
-
-}
-
-void ScriptEditorDebugger::_scene_tree_request() {
-
-	ERR_FAIL_COND(connection.is_null());
-	ERR_FAIL_COND(!connection->is_connected());
-
-	Array msg;
-	msg.push_back("request_scene_tree");
-	ppeer->put_var(msg);
-
-}
-
-Size2 ScriptEditorDebugger::get_minimum_size() const {
-
-	Size2 ms = Control::get_minimum_size();
-	ms.y = MAX(ms.y , 250 );
-	return ms;
-
-}
-void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_data) {
-
-
-
-	if (p_msg=="debug_enter") {
-
-		Array msg;
-		msg.push_back("get_stack_dump");
-		ppeer->put_var(msg);
-		ERR_FAIL_COND(p_data.size()!=2);
-		bool can_continue=p_data[0];
-		String error = p_data[1];
-		step->set_disabled(!can_continue);
-		next->set_disabled(!can_continue);
-		reason->set_text(error);
-		reason->set_tooltip(error);
-		breaked=true;
-		dobreak->set_disabled(true);
-		docontinue->set_disabled(false);
-		emit_signal("breaked",true,can_continue);
-		OS::get_singleton()->move_window_to_foreground();
-		tabs->set_current_tab(0);
-
-	} else if (p_msg=="debug_exit") {
-
-		breaked=false;
-		step->set_disabled(true);
-		next->set_disabled(true);
-		reason->set_text("");
-		reason->set_tooltip("");
-		back->set_disabled(true);
-		forward->set_disabled(true);
-		dobreak->set_disabled(false);
-		docontinue->set_disabled(true);
-		emit_signal("breaked",false,false);
-		//tabs->set_current_tab(0);
-
-	} else if (p_msg=="message:click_ctrl") {
-
-		clicked_ctrl->set_text(p_data[0]);
-		clicked_ctrl_type->set_text(p_data[1]);
-
-	} else if (p_msg=="message:scene_tree") {
-
-		scene_tree->clear();
-		Map<int,TreeItem*> lv;
-
-		for(int i=0;i<p_data.size();i+=3) {
-
-			TreeItem *p;
-			int level = p_data[i];
-			if (level==0) {
-				p = NULL;
-			} else {
-				ERR_CONTINUE(!lv.has(level-1));
-				p=lv[level-1];
-			}
-
-			TreeItem *it = scene_tree->create_item(p);
-			it->set_text(0,p_data[i+1]);
-			if (has_icon(p_data[i+2],"EditorIcons"))
-				it->set_icon(0,get_icon(p_data[i+2],"EditorIcons"));
-			lv[level]=it;
-		}
-
-
-	} else if (p_msg=="stack_dump") {
-
-		stack_dump->clear();
-		TreeItem *r = stack_dump->create_item();
-
-		for(int i=0;i<p_data.size();i++) {
-
-			Dictionary d = p_data[i];
-			ERR_CONTINUE(!d.has("function"));
-			ERR_CONTINUE(!d.has("file"));
-			ERR_CONTINUE(!d.has("line"));
-			ERR_CONTINUE(!d.has("id"));
-			TreeItem *s = stack_dump->create_item(r);
-			d["frame"]=i;
-			s->set_metadata(0,d);
-
-//			String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"])+" - at func: "+d["function"];
-			String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"]);
-			s->set_text(0,line);
-
-			if (i==0)
-				s->select(0);
-		}
-	} else if (p_msg=="stack_frame_vars") {
-
-
-		variables->clear();
-
-
-
-		int ofs =0;
-		int mcount = p_data[ofs];
-
-		ofs++;
-		for(int i=0;i<mcount;i++) {
-
-			String n = p_data[ofs+i*2+0];
-			Variant v = p_data[ofs+i*2+1];
-
-			if (n.begins_with("*")) {
-
-				n=n.substr(1,n.length());
-			}
-
-			variables->add_property("members/"+n,v);
-		}
-		ofs+=mcount*2;
-
-		mcount = p_data[ofs];
-
-		ofs++;
-		for(int i=0;i<mcount;i++) {
-
-			String n = p_data[ofs+i*2+0];
-			Variant v = p_data[ofs+i*2+1];
-
-			if (n.begins_with("*")) {
-
-				n=n.substr(1,n.length());
-			}
-
-
-			variables->add_property("locals/"+n,v);
-		}
-
-		variables->update();
-		inspector->edit(variables);
-
-	} else if (p_msg=="output") {
-
-		//OUT
-		for(int i=0;i<p_data.size();i++) {
-
-			String t = p_data[i];
-			//LOG
-
-			if (EditorNode::get_log()->is_hidden()) {
-				log_forced_visible=true;
-				EditorNode::get_log()->show();
-			}
-			EditorNode::get_log()->add_message(t);
-
-		}
-
-	} else if (p_msg=="performance") {
-		Array arr = p_data[0];
-		Vector<float> p;
-		p.resize(arr.size());
-		for(int i=0;i<arr.size();i++) {
-			p[i]=arr[i];
-			if (i<perf_items.size()) {
-				perf_items[i]->set_text(1,rtos(p[i]));
-				if (p[i]>perf_max[i])
-					perf_max[i]=p[i];
-			}
-
-		}
-		perf_history.push_front(p);
-		perf_draw->update();
-
-	} else if (p_msg=="kill_me") {
-
-		editor->call_deferred("stop_child_process");
-	}
-
-}
-
-
-void ScriptEditorDebugger::_performance_select(Object*,int,bool) {
-
-	perf_draw->update();
-
-}
-
-void ScriptEditorDebugger::_performance_draw() {
-
-
-	Vector<int> which;
-	for(int i=0;i<perf_items.size();i++) {
-
-
-		if (perf_items[i]->is_selected(0))
-			which.push_back(i);
-	}
-
-
-	if(which.empty())
-		return;
-
-	Color graph_color=get_color("font_color","TextEdit");
-	Ref<StyleBox> graph_sb = get_stylebox("normal","TextEdit");
-	Ref<Font> graph_font = get_font("font","TextEdit");
-
-	int cols = Math::ceil(Math::sqrt(which.size()));
-	int rows = (which.size()+1)/cols;
-	if (which.size()==1)
-		rows=1;
-
-
-	int margin =3;
-	int point_sep=5;
-	Size2i s = Size2i(perf_draw->get_size())/Size2i(cols,rows);
-	for(int i=0;i<which.size();i++) {
-
-		Point2i p(i%cols,i/cols);
-		Rect2i r(p*s,s);
-		r.pos+=Point2(margin,margin);
-		r.size-=Point2(margin,margin)*2.0;
-		perf_draw->draw_style_box(graph_sb,r);
-		r.pos+=graph_sb->get_offset();
-		r.size-=graph_sb->get_minimum_size();
-		int pi=which[i];
-		Color c = Color(0.7,0.9,0.5);
-		c.set_hsv(Math::fmod(c.get_h()+pi*0.7654,1),c.get_s(),c.get_v());
-
-		c.a=0.8;
-		perf_draw->draw_string(graph_font,r.pos+Point2(0,graph_font->get_ascent()),perf_items[pi]->get_text(0),c,r.size.x);
-		c.a=0.6;
-		perf_draw->draw_string(graph_font,r.pos+Point2(graph_font->get_char_size('X').width,graph_font->get_ascent()+graph_font->get_height()),perf_items[pi]->get_text(1),c,r.size.y);
-
-		float spacing=point_sep/float(cols);
-		float from = r.size.width;
-
-		List<Vector<float> >::Element *E=perf_history.front();
-		float prev=-1;
-		while(from>=0 && E) {
-
-			float m = perf_max[pi];
-			if (m==0)
-				m=0.00001;
-			float h = E->get()[pi]/m;
-			h=(1.0-h)*r.size.y;
-
-			c.a=0.7;
-			if (E!=perf_history.front())
-				perf_draw->draw_line(r.pos+Point2(from,h),r.pos+Point2(from+spacing,prev),c,2.0);
-			prev=h;
-			E=E->next();
-			from-=spacing;
-		}
-
-	}
-
-}
-
-void ScriptEditorDebugger::_notification(int p_what) {
-
-	switch(p_what) {
-
-		case NOTIFICATION_ENTER_SCENE: {
-
-			step->set_icon( get_icon("DebugStep","EditorIcons"));
-			next->set_icon( get_icon("DebugNext","EditorIcons"));
-			back->set_icon( get_icon("Back","EditorIcons"));
-			forward->set_icon( get_icon("Forward","EditorIcons"));
-			dobreak->set_icon( get_icon("Pause","EditorIcons"));
-			docontinue->set_icon( get_icon("DebugContinue","EditorIcons"));
-			tb->set_normal_texture( get_icon("Close","EditorIcons"));
-			tb->set_hover_texture( get_icon("CloseHover","EditorIcons"));
-			tb->set_pressed_texture( get_icon("Close","EditorIcons"));
-			scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
-
-		} break;
-		case NOTIFICATION_PROCESS: {
-
-			if (connection.is_null()) {
-
-				if (server->is_connection_available()) {
-
-					connection = server->take_connection();
-					if (connection.is_null())
-						break;
-
-					EditorNode::get_log()->add_message("** Debug Process Started **");
-					log_forced_visible=false;
-
-					ppeer->set_stream_peer(connection);
-
-
-					show();
-					dobreak->set_disabled(false);
-					tabs->set_current_tab(0);
-
-					emit_signal("show_debugger",true);
-					reason->set_text("Child Process Connected");
-					reason->set_tooltip("Child Process Connected");
-
-				} else {
-
-					break;
-				}
-			};
-
-			if (!connection->is_connected()) {
-				stop();
-				editor->notify_child_process_exited(); //somehow, exited
-				msgdialog->set_text("Process being debugged exited.");
-				msgdialog->popup_centered(Size2(250,100));
-				break;
-			};
-
-			if (ppeer->get_available_packet_count() <= 0) {
-				break;
-			};
-
-			while(ppeer->get_available_packet_count() > 0) {
-
-				if (pending_in_queue) {
-
-					int todo = MIN( ppeer->get_available_packet_count(), pending_in_queue );
-
-					for(int i=0;i<todo;i++) {
-
-						Variant cmd;
-						Error ret = ppeer->get_var(cmd);
-						if (ret!=OK) {
-							stop();
-							ERR_FAIL_COND(ret!=OK);
-						}
-
-						message.push_back(cmd);
-						pending_in_queue--;
-					}
-
-
-					if (pending_in_queue==0) {
-						_parse_message(message_type,message);
-						message.clear();
-
-					}
-
-
-				} else {
-
-					if (ppeer->get_available_packet_count()>=2) {
-
-
-						Variant cmd;
-						Error ret = ppeer->get_var(cmd);
-						if (ret!=OK) {
-							stop();
-							ERR_FAIL_COND(ret!=OK);
-						}
-						if (cmd.get_type()!=Variant::STRING) {
-							stop();
-							ERR_FAIL_COND(cmd.get_type()!=Variant::STRING);
-						}
-
-						message_type=cmd;
-
-						ret = ppeer->get_var(cmd);
-						if (ret!=OK) {
-							stop();
-							ERR_FAIL_COND(ret!=OK);
-						}
-						if (cmd.get_type()!=Variant::INT) {
-							stop();
-							ERR_FAIL_COND(cmd.get_type()!=Variant::INT);
-						}
-
-						pending_in_queue=cmd;
-
-						if (pending_in_queue==0) {
-							_parse_message(message_type,Array());
-							message.clear();
-						}
-
-					} else {
-
-
-						break;
-					}
-
-				}
-			}
-
-
-
-		} break;
-	}
-
-}
-
-
-void ScriptEditorDebugger::start() {
-
-	stop();
-
-
-	uint16_t port = GLOBAL_DEF("debug/remote_port",6007);
-	perf_history.clear();
-	for(int i=0;i<Performance::MONITOR_MAX;i++) {
-
-		perf_max[i]=0;
-	}
-
-	server->listen(port);
-	set_process(true);
-
-}
-
-void ScriptEditorDebugger::pause(){
-
-
-}
-
-void ScriptEditorDebugger::unpause(){
-
-
-}
-
-void ScriptEditorDebugger::stop(){
-
-
-	set_process(false);
-
-	server->stop();
-
-	ppeer->set_stream_peer(Ref<StreamPeer>());
-
-	if (connection.is_valid()) {
-		EditorNode::get_log()->add_message("** Debug Process Stopped **");
-		connection.unref();
-	}
-
-	pending_in_queue=0;
-	message.clear();
-
-	if (log_forced_visible) {
-		EditorNode::get_log()->hide();
-		log_forced_visible=false;
-	}
-
-
-
-	hide();
-	emit_signal("show_debugger",false);
-
-}
-
-
-void ScriptEditorDebugger::_stack_dump_frame_selected() {
-
-	TreeItem *ti = stack_dump->get_selected();
-	if (!ti)
-		return;
-
-
-	Dictionary d = ti->get_metadata(0);
-
-	Ref<Script> s = ResourceLoader::load(d["file"]);
-	emit_signal("goto_script_line",s,int(d["line"])-1);
-
-	ERR_FAIL_COND(connection.is_null());
-	ERR_FAIL_COND(!connection->is_connected());
-	///
-
-	Array msg;
-	msg.push_back("get_stack_frame_vars");
-	msg.push_back(d["frame"]);
-	ppeer->put_var(msg);
-
-}
-
-void ScriptEditorDebugger::_hide_request() {
-
-	hide();
-	emit_signal("show_debugger",false);
-
-}
-
-void ScriptEditorDebugger::_output_clear() {
-
-	//output->clear();
-	//output->push_color(Color(0,0,0));
-
-}
-
-String ScriptEditorDebugger::get_var_value(const String& p_var) const {
-	if (!breaked)
-		return String();
-	return variables->get_var_value(p_var);
-}
-
-void ScriptEditorDebugger::_bind_methods() {
-
-	ObjectTypeDB::bind_method(_MD("_stack_dump_frame_selected"),&ScriptEditorDebugger::_stack_dump_frame_selected);
-	ObjectTypeDB::bind_method(_MD("debug_next"),&ScriptEditorDebugger::debug_next);
-	ObjectTypeDB::bind_method(_MD("debug_step"),&ScriptEditorDebugger::debug_step);
-	ObjectTypeDB::bind_method(_MD("debug_break"),&ScriptEditorDebugger::debug_break);
-	ObjectTypeDB::bind_method(_MD("debug_continue"),&ScriptEditorDebugger::debug_continue);
-	ObjectTypeDB::bind_method(_MD("_output_clear"),&ScriptEditorDebugger::_output_clear);
-	ObjectTypeDB::bind_method(_MD("_hide_request"),&ScriptEditorDebugger::_hide_request);
-	ObjectTypeDB::bind_method(_MD("_performance_draw"),&ScriptEditorDebugger::_performance_draw);
-	ObjectTypeDB::bind_method(_MD("_performance_select"),&ScriptEditorDebugger::_performance_select);
-	ObjectTypeDB::bind_method(_MD("_scene_tree_request"),&ScriptEditorDebugger::_scene_tree_request);
-
-	ADD_SIGNAL(MethodInfo("goto_script_line"));
-	ADD_SIGNAL(MethodInfo("breaked",PropertyInfo(Variant::BOOL,"reallydid")));
-	ADD_SIGNAL(MethodInfo("show_debugger",PropertyInfo(Variant::BOOL,"reallydid")));
-}
-
-ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
-
-
-
-	ppeer = Ref<PacketPeerStream>( memnew( PacketPeerStream ) );
-	editor=p_editor;
-
-	tabs = memnew( TabContainer );
-	tabs->set_v_size_flags(SIZE_EXPAND_FILL);
-	tabs->set_area_as_parent_rect();
-	add_child(tabs);
-
-	tb = memnew( TextureButton );
-	tb->connect("pressed",this,"_hide_request");
-	tb->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,20);
-	tb->set_margin(MARGIN_TOP,2);
-	add_child(tb);
-
-
-
-	VBoxContainer *vbc = memnew( VBoxContainer );
-	vbc->set_name("Debugger");
-	//tabs->add_child(vbc);
-	Control *dbg=vbc;
-
-	HBoxContainer *hbc = memnew( HBoxContainer );
-	vbc->add_child(hbc);
-
-
-	reason = memnew( Label );
-	reason->set_text("");
-	hbc->add_child(reason);
-	reason->add_color_override("font_color",Color(1,0.4,0.0,0.8));
-	reason->set_h_size_flags(SIZE_EXPAND_FILL);
-	reason->set_clip_text(true);
-
-	hbc->add_child( memnew( VSeparator) );
-
-	step = memnew( Button );
-	hbc->add_child(step);
-	step->set_tooltip("Step Into");
-	step->connect("pressed",this,"debug_step");
-
-	next = memnew( Button );
-	hbc->add_child(next);
-	next->set_tooltip("Step Over");
-	next->connect("pressed",this,"debug_next");
-
-	hbc->add_child( memnew( VSeparator) );
-
-	dobreak = memnew( Button );
-	hbc->add_child(dobreak);
-	dobreak->set_tooltip("Break");
-	dobreak->connect("pressed",this,"debug_break");
-
-	docontinue = memnew( Button );
-	hbc->add_child(docontinue);
-	docontinue->set_tooltip("Continue");
-	docontinue->connect("pressed",this,"debug_continue");
-
-	hbc->add_child( memnew( VSeparator) );
-
-	back = memnew( Button );
-	hbc->add_child(back);
-	back->set_tooltip("Inspect Previous Instance");
-
-	forward = memnew( Button );
-	hbc->add_child(forward);
-	back->set_tooltip("Inspect Next Instance");
-
-
-	HSplitContainer *sc = memnew( HSplitContainer );
-	vbc->add_child(sc);
-	sc->set_v_size_flags(SIZE_EXPAND_FILL);
-
-	stack_dump = memnew( Tree );
-	stack_dump->set_columns(1);
-	stack_dump->set_column_titles_visible(true);
-	stack_dump->set_column_title(0,"Stack Frames");
-	stack_dump->set_h_size_flags(SIZE_EXPAND_FILL);
-	stack_dump->set_hide_root(true);
-	stack_dump->connect("cell_selected",this,"_stack_dump_frame_selected");
-	sc->add_child(stack_dump);
-
-	inspector = memnew( PropertyEditor );
-	inspector->set_h_size_flags(SIZE_EXPAND_FILL);
-	inspector->hide_top_label();
-	inspector->get_tree()->set_column_title(0,"Variable");
-	inspector->set_capitalize_paths(false);
-	inspector->set_read_only(true);
-	sc->add_child(inspector);
-
-	server = TCP_Server::create();
-
-	pending_in_queue=0;
-
-	variables = memnew( ScriptEditorDebuggerVariables );
-	inspector->edit(variables);
-	breaked=false;
-
-	tabs->add_child(dbg);
-	//tabs->move_child(vbc,0);
-
-	hbc = memnew( HBoxContainer );
-	vbc->add_child(hbc);
-
-
-	HSplitContainer *hsp = memnew( HSplitContainer );
-
-	perf_monitors = memnew(Tree);
-	perf_monitors->set_columns(2);
-	perf_monitors->set_column_title(0,"Monitor");
-	perf_monitors->set_column_title(1,"Value");
-	perf_monitors->set_column_titles_visible(true);
-	hsp->add_child(perf_monitors);
-	perf_monitors->set_select_mode(Tree::SELECT_MULTI);
-	perf_monitors->connect("multi_selected",this,"_performance_select");
-	perf_draw = memnew( Control );
-	perf_draw->connect("draw",this,"_performance_draw");
-	hsp->add_child(perf_draw);
-	hsp->set_name("Performance");
-	hsp->set_split_offset(300);
-	tabs->add_child(hsp);
-	perf_max.resize(Performance::MONITOR_MAX);
-
-	Map<String,TreeItem*> bases;
-	TreeItem *root=perf_monitors->create_item();
-	perf_monitors->set_hide_root(true);
-	for(int i=0;i<Performance::MONITOR_MAX;i++) {
-
-		String n = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i));
-		String base = n.get_slice("/",0);
-		String name = n.get_slice("/",1);
-		if (!bases.has(base)) {
-			TreeItem *b = perf_monitors->create_item(root);
-			b->set_text(0,base.capitalize());
-			b->set_editable(0,false);
-			b->set_selectable(0,false);
-			bases[base]=b;
-		}
-
-		TreeItem *it = perf_monitors->create_item(bases[base]);
-		it->set_editable(0,false);
-		it->set_selectable(0,true);
-		it->set_text(0,name.capitalize());
-		perf_items.push_back(it);
-		perf_max[i]=0;
-
-	}
-
-	info = memnew( HSplitContainer );
-	info->set_name("Info");
-	tabs->add_child(info);
-
-	VBoxContainer *info_left = memnew( VBoxContainer );
-	info_left->set_h_size_flags(SIZE_EXPAND_FILL);
-	info->add_child(info_left);
-	clicked_ctrl = memnew( LineEdit );
-	info_left->add_margin_child("Clicked Control:",clicked_ctrl);
-	clicked_ctrl_type = memnew( LineEdit );
-	info_left->add_margin_child("Clicked Control Type:",clicked_ctrl_type);
-	VBoxContainer *info_right = memnew(VBoxContainer);
-	info_right->set_h_size_flags(SIZE_EXPAND_FILL);
-	info->add_child(info_right);
-	HBoxContainer *inforhb = memnew( HBoxContainer );
-	info_right->add_child(inforhb);
-	Label *l2 = memnew( Label("Scene Tree:" ) );
-	l2->set_h_size_flags(SIZE_EXPAND_FILL);
-	inforhb->add_child( l2 );
-	Button *refresh = memnew( Button );
-	inforhb->add_child(refresh);
-	refresh->connect("pressed",this,"_scene_tree_request");
-	scene_tree_refresh=refresh;
-	MarginContainer *infomc = memnew( MarginContainer );
-	info_right->add_child(infomc);
-	infomc->set_v_size_flags(SIZE_EXPAND_FILL);
-	scene_tree = memnew( Tree );
-	infomc->add_child(scene_tree);
-
-
-	msgdialog = memnew( AcceptDialog );
-	add_child(msgdialog);
-
-	hide();
-	log_forced_visible=false;
-
-}
-
-ScriptEditorDebugger::~ScriptEditorDebugger() {
-
-//	inspector->edit(NULL);
-	memdelete(variables);
-
-	ppeer->set_stream_peer(Ref<StreamPeer>());
-
-	server->stop();
-
-}
+#include "script_editor_debugger.h"
+#include "scene/gui/separator.h"
+#include "scene/gui/label.h"
+#include "scene/gui/split_container.h"
+#include "scene/gui/tree.h"
+#include "scene/gui/texture_button.h"
+#include "scene/gui/tab_container.h"
+#include "scene/gui/line_edit.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/rich_text_label.h"
+#include "scene/gui/margin_container.h"
+#include "property_editor.h"
+#include "globals.h"
+#include "editor_node.h"
+#include "main/performance.h"
+
+class ScriptEditorDebuggerVariables : public Object {
+
+	OBJ_TYPE( ScriptEditorDebuggerVariables, Object );
+
+	List<PropertyInfo> props;
+	Map<StringName,Variant> values;
+protected:
+
+	bool _set(const StringName& p_name, const Variant& p_value) {
+
+		return false;
+	}
+
+	bool _get(const StringName& p_name,Variant &r_ret) const {
+
+		if (!values.has(p_name))
+			return false;
+		r_ret=values[p_name];
+		return true;
+	}
+	void _get_property_list( List<PropertyInfo> *p_list) const {
+
+		for(const List<PropertyInfo>::Element *E=props.front();E;E=E->next() )
+			p_list->push_back(E->get());
+	}
+
+
+public:
+
+
+	void clear() {
+
+		props.clear();
+		values.clear();
+	}
+
+	String get_var_value(const String& p_var) const {
+
+		for(Map<StringName,Variant>::Element *E=values.front();E;E=E->next()) {
+			String v = E->key().operator String().get_slice("/",1);
+			if (v==p_var)
+				return E->get();
+		}
+
+		return "";
+	}
+
+	void add_property(const String &p_name, const Variant& p_value) {
+
+		PropertyInfo pinfo;
+		pinfo.name=p_name;
+		pinfo.type=p_value.get_type();
+		props.push_back(pinfo);
+		values[p_name]=p_value;
+
+	}
+
+	void update() {
+		_change_notify();
+	}
+
+
+	ScriptEditorDebuggerVariables() {
+
+	}
+};
+
+void ScriptEditorDebugger::debug_next() {
+
+	ERR_FAIL_COND(!breaked);
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+	Array msg;
+	msg.push_back("next");
+	ppeer->put_var(msg);
+	stack_dump->clear();
+	inspector->edit(NULL);
+
+}
+void ScriptEditorDebugger::debug_step() {
+
+	ERR_FAIL_COND(!breaked);
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+
+	Array msg;
+	msg.push_back("step");
+	ppeer->put_var(msg);
+	stack_dump->clear();
+	inspector->edit(NULL);
+}
+
+void ScriptEditorDebugger::debug_break() {
+
+	ERR_FAIL_COND(breaked);
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+
+	Array msg;
+	msg.push_back("break");
+	ppeer->put_var(msg);
+
+}
+
+void ScriptEditorDebugger::debug_continue() {
+
+	ERR_FAIL_COND(!breaked);
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+
+	Array msg;
+	msg.push_back("continue");
+	ppeer->put_var(msg);
+
+}
+
+void ScriptEditorDebugger::_scene_tree_request() {
+
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+
+	Array msg;
+	msg.push_back("request_scene_tree");
+	ppeer->put_var(msg);
+
+}
+
+Size2 ScriptEditorDebugger::get_minimum_size() const {
+
+	Size2 ms = Control::get_minimum_size();
+	ms.y = MAX(ms.y , 250 );
+	return ms;
+
+}
+void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_data) {
+
+
+
+	if (p_msg=="debug_enter") {
+
+		Array msg;
+		msg.push_back("get_stack_dump");
+		ppeer->put_var(msg);
+		ERR_FAIL_COND(p_data.size()!=2);
+		bool can_continue=p_data[0];
+		String error = p_data[1];
+		step->set_disabled(!can_continue);
+		next->set_disabled(!can_continue);
+		reason->set_text(error);
+		reason->set_tooltip(error);
+		breaked=true;
+		dobreak->set_disabled(true);
+		docontinue->set_disabled(false);
+		emit_signal("breaked",true,can_continue);
+		OS::get_singleton()->move_window_to_foreground();
+		tabs->set_current_tab(0);
+
+	} else if (p_msg=="debug_exit") {
+
+		breaked=false;
+		step->set_disabled(true);
+		next->set_disabled(true);
+		reason->set_text("");
+		reason->set_tooltip("");
+		back->set_disabled(true);
+		forward->set_disabled(true);
+		dobreak->set_disabled(false);
+		docontinue->set_disabled(true);
+		emit_signal("breaked",false,false);
+		//tabs->set_current_tab(0);
+
+	} else if (p_msg=="message:click_ctrl") {
+
+		clicked_ctrl->set_text(p_data[0]);
+		clicked_ctrl_type->set_text(p_data[1]);
+
+	} else if (p_msg=="message:scene_tree") {
+
+		scene_tree->clear();
+		Map<int,TreeItem*> lv;
+
+		for(int i=0;i<p_data.size();i+=3) {
+
+			TreeItem *p;
+			int level = p_data[i];
+			if (level==0) {
+				p = NULL;
+			} else {
+				ERR_CONTINUE(!lv.has(level-1));
+				p=lv[level-1];
+			}
+
+			TreeItem *it = scene_tree->create_item(p);
+			it->set_text(0,p_data[i+1]);
+			if (has_icon(p_data[i+2],"EditorIcons"))
+				it->set_icon(0,get_icon(p_data[i+2],"EditorIcons"));
+			lv[level]=it;
+		}
+
+
+	} else if (p_msg=="stack_dump") {
+
+		stack_dump->clear();
+		TreeItem *r = stack_dump->create_item();
+
+		for(int i=0;i<p_data.size();i++) {
+
+			Dictionary d = p_data[i];
+			ERR_CONTINUE(!d.has("function"));
+			ERR_CONTINUE(!d.has("file"));
+			ERR_CONTINUE(!d.has("line"));
+			ERR_CONTINUE(!d.has("id"));
+			TreeItem *s = stack_dump->create_item(r);
+			d["frame"]=i;
+			s->set_metadata(0,d);
+
+//			String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"])+" - at func: "+d["function"];
+			String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"]);
+			s->set_text(0,line);
+
+			if (i==0)
+				s->select(0);
+		}
+	} else if (p_msg=="stack_frame_vars") {
+
+
+		variables->clear();
+
+
+
+		int ofs =0;
+		int mcount = p_data[ofs];
+
+		ofs++;
+		for(int i=0;i<mcount;i++) {
+
+			String n = p_data[ofs+i*2+0];
+			Variant v = p_data[ofs+i*2+1];
+
+			if (n.begins_with("*")) {
+
+				n=n.substr(1,n.length());
+			}
+
+			variables->add_property("members/"+n,v);
+		}
+		ofs+=mcount*2;
+
+		mcount = p_data[ofs];
+
+		ofs++;
+		for(int i=0;i<mcount;i++) {
+
+			String n = p_data[ofs+i*2+0];
+			Variant v = p_data[ofs+i*2+1];
+
+			if (n.begins_with("*")) {
+
+				n=n.substr(1,n.length());
+			}
+
+
+			variables->add_property("locals/"+n,v);
+		}
+
+		variables->update();
+		inspector->edit(variables);
+
+	} else if (p_msg=="output") {
+
+		//OUT
+		for(int i=0;i<p_data.size();i++) {
+
+			String t = p_data[i];
+			//LOG
+
+			if (EditorNode::get_log()->is_hidden()) {
+				log_forced_visible=true;
+				EditorNode::get_log()->show();
+			}
+			EditorNode::get_log()->add_message(t);
+
+		}
+
+	} else if (p_msg=="performance") {
+		Array arr = p_data[0];
+		Vector<float> p;
+		p.resize(arr.size());
+		for(int i=0;i<arr.size();i++) {
+			p[i]=arr[i];
+			if (i<perf_items.size()) {
+				perf_items[i]->set_text(1,rtos(p[i]));
+				if (p[i]>perf_max[i])
+					perf_max[i]=p[i];
+			}
+
+		}
+		perf_history.push_front(p);
+		perf_draw->update();
+
+	} else if (p_msg=="kill_me") {
+
+		editor->call_deferred("stop_child_process");
+	}
+
+}
+
+
+void ScriptEditorDebugger::_performance_select(Object*,int,bool) {
+
+	perf_draw->update();
+
+}
+
+void ScriptEditorDebugger::_performance_draw() {
+
+
+	Vector<int> which;
+	for(int i=0;i<perf_items.size();i++) {
+
+
+		if (perf_items[i]->is_selected(0))
+			which.push_back(i);
+	}
+
+
+	if(which.empty())
+		return;
+
+	Color graph_color=get_color("font_color","TextEdit");
+	Ref<StyleBox> graph_sb = get_stylebox("normal","TextEdit");
+	Ref<Font> graph_font = get_font("font","TextEdit");
+
+	int cols = Math::ceil(Math::sqrt(which.size()));
+	int rows = (which.size()+1)/cols;
+	if (which.size()==1)
+		rows=1;
+
+
+	int margin =3;
+	int point_sep=5;
+	Size2i s = Size2i(perf_draw->get_size())/Size2i(cols,rows);
+	for(int i=0;i<which.size();i++) {
+
+		Point2i p(i%cols,i/cols);
+		Rect2i r(p*s,s);
+		r.pos+=Point2(margin,margin);
+		r.size-=Point2(margin,margin)*2.0;
+		perf_draw->draw_style_box(graph_sb,r);
+		r.pos+=graph_sb->get_offset();
+		r.size-=graph_sb->get_minimum_size();
+		int pi=which[i];
+		Color c = Color(0.7,0.9,0.5);
+		c.set_hsv(Math::fmod(c.get_h()+pi*0.7654,1),c.get_s(),c.get_v());
+
+		c.a=0.8;
+		perf_draw->draw_string(graph_font,r.pos+Point2(0,graph_font->get_ascent()),perf_items[pi]->get_text(0),c,r.size.x);
+		c.a=0.6;
+		perf_draw->draw_string(graph_font,r.pos+Point2(graph_font->get_char_size('X').width,graph_font->get_ascent()+graph_font->get_height()),perf_items[pi]->get_text(1),c,r.size.y);
+
+		float spacing=point_sep/float(cols);
+		float from = r.size.width;
+
+		List<Vector<float> >::Element *E=perf_history.front();
+		float prev=-1;
+		while(from>=0 && E) {
+
+			float m = perf_max[pi];
+			if (m==0)
+				m=0.00001;
+			float h = E->get()[pi]/m;
+			h=(1.0-h)*r.size.y;
+
+			c.a=0.7;
+			if (E!=perf_history.front())
+				perf_draw->draw_line(r.pos+Point2(from,h),r.pos+Point2(from+spacing,prev),c,2.0);
+			prev=h;
+			E=E->next();
+			from-=spacing;
+		}
+
+	}
+
+}
+
+void ScriptEditorDebugger::_notification(int p_what) {
+
+	switch(p_what) {
+
+		case NOTIFICATION_ENTER_SCENE: {
+
+			step->set_icon( get_icon("DebugStep","EditorIcons"));
+			next->set_icon( get_icon("DebugNext","EditorIcons"));
+			back->set_icon( get_icon("Back","EditorIcons"));
+			forward->set_icon( get_icon("Forward","EditorIcons"));
+			dobreak->set_icon( get_icon("Pause","EditorIcons"));
+			docontinue->set_icon( get_icon("DebugContinue","EditorIcons"));
+			tb->set_normal_texture( get_icon("Close","EditorIcons"));
+			tb->set_hover_texture( get_icon("CloseHover","EditorIcons"));
+			tb->set_pressed_texture( get_icon("Close","EditorIcons"));
+			scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
+
+		} break;
+		case NOTIFICATION_PROCESS: {
+
+			if (connection.is_null()) {
+
+				if (server->is_connection_available()) {
+
+					connection = server->take_connection();
+					if (connection.is_null())
+						break;
+
+					EditorNode::get_log()->add_message("** Debug Process Started **");
+					log_forced_visible=false;
+
+					ppeer->set_stream_peer(connection);
+
+
+					show();
+					dobreak->set_disabled(false);
+					tabs->set_current_tab(0);
+
+					emit_signal("show_debugger",true);
+					reason->set_text("Child Process Connected");
+					reason->set_tooltip("Child Process Connected");
+
+				} else {
+
+					break;
+				}
+			};
+
+			if (!connection->is_connected()) {
+				stop();
+				editor->notify_child_process_exited(); //somehow, exited
+				msgdialog->set_text("Process being debugged exited.");
+				msgdialog->popup_centered(Size2(250,100));
+				break;
+			};
+
+			if (ppeer->get_available_packet_count() <= 0) {
+				break;
+			};
+
+			while(ppeer->get_available_packet_count() > 0) {
+
+				if (pending_in_queue) {
+
+					int todo = MIN( ppeer->get_available_packet_count(), pending_in_queue );
+
+					for(int i=0;i<todo;i++) {
+
+						Variant cmd;
+						Error ret = ppeer->get_var(cmd);
+						if (ret!=OK) {
+							stop();
+							ERR_FAIL_COND(ret!=OK);
+						}
+
+						message.push_back(cmd);
+						pending_in_queue--;
+					}
+
+
+					if (pending_in_queue==0) {
+						_parse_message(message_type,message);
+						message.clear();
+
+					}
+
+
+				} else {
+
+					if (ppeer->get_available_packet_count()>=2) {
+
+
+						Variant cmd;
+						Error ret = ppeer->get_var(cmd);
+						if (ret!=OK) {
+							stop();
+							ERR_FAIL_COND(ret!=OK);
+						}
+						if (cmd.get_type()!=Variant::STRING) {
+							stop();
+							ERR_FAIL_COND(cmd.get_type()!=Variant::STRING);
+						}
+
+						message_type=cmd;
+
+						ret = ppeer->get_var(cmd);
+						if (ret!=OK) {
+							stop();
+							ERR_FAIL_COND(ret!=OK);
+						}
+						if (cmd.get_type()!=Variant::INT) {
+							stop();
+							ERR_FAIL_COND(cmd.get_type()!=Variant::INT);
+						}
+
+						pending_in_queue=cmd;
+
+						if (pending_in_queue==0) {
+							_parse_message(message_type,Array());
+							message.clear();
+						}
+
+					} else {
+
+
+						break;
+					}
+
+				}
+			}
+
+
+
+		} break;
+	}
+
+}
+
+
+void ScriptEditorDebugger::start() {
+
+	stop();
+
+
+	uint16_t port = GLOBAL_DEF("debug/remote_port",6007);
+	perf_history.clear();
+	for(int i=0;i<Performance::MONITOR_MAX;i++) {
+
+		perf_max[i]=0;
+	}
+
+	server->listen(port);
+	set_process(true);
+
+}
+
+void ScriptEditorDebugger::pause(){
+
+
+}
+
+void ScriptEditorDebugger::unpause(){
+
+
+}
+
+void ScriptEditorDebugger::stop(){
+
+
+	set_process(false);
+
+	server->stop();
+
+	ppeer->set_stream_peer(Ref<StreamPeer>());
+
+	if (connection.is_valid()) {
+		EditorNode::get_log()->add_message("** Debug Process Stopped **");
+		connection.unref();
+	}
+
+	pending_in_queue=0;
+	message.clear();
+
+	if (log_forced_visible) {
+		EditorNode::get_log()->hide();
+		log_forced_visible=false;
+	}
+
+
+
+	hide();
+	emit_signal("show_debugger",false);
+
+}
+
+
+void ScriptEditorDebugger::_stack_dump_frame_selected() {
+
+	TreeItem *ti = stack_dump->get_selected();
+	if (!ti)
+		return;
+
+
+	Dictionary d = ti->get_metadata(0);
+
+	Ref<Script> s = ResourceLoader::load(d["file"]);
+	emit_signal("goto_script_line",s,int(d["line"])-1);
+
+	ERR_FAIL_COND(connection.is_null());
+	ERR_FAIL_COND(!connection->is_connected());
+	///
+
+	Array msg;
+	msg.push_back("get_stack_frame_vars");
+	msg.push_back(d["frame"]);
+	ppeer->put_var(msg);
+
+}
+
+void ScriptEditorDebugger::_hide_request() {
+
+	hide();
+	emit_signal("show_debugger",false);
+
+}
+
+void ScriptEditorDebugger::_output_clear() {
+
+	//output->clear();
+	//output->push_color(Color(0,0,0));
+
+}
+
+String ScriptEditorDebugger::get_var_value(const String& p_var) const {
+	if (!breaked)
+		return String();
+	return variables->get_var_value(p_var);
+}
+
+void ScriptEditorDebugger::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("_stack_dump_frame_selected"),&ScriptEditorDebugger::_stack_dump_frame_selected);
+	ObjectTypeDB::bind_method(_MD("debug_next"),&ScriptEditorDebugger::debug_next);
+	ObjectTypeDB::bind_method(_MD("debug_step"),&ScriptEditorDebugger::debug_step);
+	ObjectTypeDB::bind_method(_MD("debug_break"),&ScriptEditorDebugger::debug_break);
+	ObjectTypeDB::bind_method(_MD("debug_continue"),&ScriptEditorDebugger::debug_continue);
+	ObjectTypeDB::bind_method(_MD("_output_clear"),&ScriptEditorDebugger::_output_clear);
+	ObjectTypeDB::bind_method(_MD("_hide_request"),&ScriptEditorDebugger::_hide_request);
+	ObjectTypeDB::bind_method(_MD("_performance_draw"),&ScriptEditorDebugger::_performance_draw);
+	ObjectTypeDB::bind_method(_MD("_performance_select"),&ScriptEditorDebugger::_performance_select);
+	ObjectTypeDB::bind_method(_MD("_scene_tree_request"),&ScriptEditorDebugger::_scene_tree_request);
+
+	ADD_SIGNAL(MethodInfo("goto_script_line"));
+	ADD_SIGNAL(MethodInfo("breaked",PropertyInfo(Variant::BOOL,"reallydid")));
+	ADD_SIGNAL(MethodInfo("show_debugger",PropertyInfo(Variant::BOOL,"reallydid")));
+}
+
+ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){
+
+
+
+	ppeer = Ref<PacketPeerStream>( memnew( PacketPeerStream ) );
+	editor=p_editor;
+
+	tabs = memnew( TabContainer );
+	tabs->set_v_size_flags(SIZE_EXPAND_FILL);
+	tabs->set_area_as_parent_rect();
+	add_child(tabs);
+
+	tb = memnew( TextureButton );
+	tb->connect("pressed",this,"_hide_request");
+	tb->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,20);
+	tb->set_margin(MARGIN_TOP,2);
+	add_child(tb);
+
+
+
+	VBoxContainer *vbc = memnew( VBoxContainer );
+	vbc->set_name("Debugger");
+	//tabs->add_child(vbc);
+	Control *dbg=vbc;
+
+	HBoxContainer *hbc = memnew( HBoxContainer );
+	vbc->add_child(hbc);
+
+
+	reason = memnew( Label );
+	reason->set_text("");
+	hbc->add_child(reason);
+	reason->add_color_override("font_color",Color(1,0.4,0.0,0.8));
+	reason->set_h_size_flags(SIZE_EXPAND_FILL);
+	reason->set_clip_text(true);
+
+	hbc->add_child( memnew( VSeparator) );
+
+	step = memnew( Button );
+	hbc->add_child(step);
+	step->set_tooltip("Step Into");
+	step->connect("pressed",this,"debug_step");
+
+	next = memnew( Button );
+	hbc->add_child(next);
+	next->set_tooltip("Step Over");
+	next->connect("pressed",this,"debug_next");
+
+	hbc->add_child( memnew( VSeparator) );
+
+	dobreak = memnew( Button );
+	hbc->add_child(dobreak);
+	dobreak->set_tooltip("Break");
+	dobreak->connect("pressed",this,"debug_break");
+
+	docontinue = memnew( Button );
+	hbc->add_child(docontinue);
+	docontinue->set_tooltip("Continue");
+	docontinue->connect("pressed",this,"debug_continue");
+
+	hbc->add_child( memnew( VSeparator) );
+
+	back = memnew( Button );
+	hbc->add_child(back);
+	back->set_tooltip("Inspect Previous Instance");
+
+	forward = memnew( Button );
+	hbc->add_child(forward);
+	back->set_tooltip("Inspect Next Instance");
+
+
+	HSplitContainer *sc = memnew( HSplitContainer );
+	vbc->add_child(sc);
+	sc->set_v_size_flags(SIZE_EXPAND_FILL);
+
+	stack_dump = memnew( Tree );
+	stack_dump->set_columns(1);
+	stack_dump->set_column_titles_visible(true);
+	stack_dump->set_column_title(0,"Stack Frames");
+	stack_dump->set_h_size_flags(SIZE_EXPAND_FILL);
+	stack_dump->set_hide_root(true);
+	stack_dump->connect("cell_selected",this,"_stack_dump_frame_selected");
+	sc->add_child(stack_dump);
+
+	inspector = memnew( PropertyEditor );
+	inspector->set_h_size_flags(SIZE_EXPAND_FILL);
+	inspector->hide_top_label();
+	inspector->get_tree()->set_column_title(0,"Variable");
+	inspector->set_capitalize_paths(false);
+	inspector->set_read_only(true);
+	sc->add_child(inspector);
+
+	server = TCP_Server::create_ref();
+
+	pending_in_queue=0;
+
+	variables = memnew( ScriptEditorDebuggerVariables );
+	inspector->edit(variables);
+	breaked=false;
+
+	tabs->add_child(dbg);
+	//tabs->move_child(vbc,0);
+
+	hbc = memnew( HBoxContainer );
+	vbc->add_child(hbc);
+
+
+	HSplitContainer *hsp = memnew( HSplitContainer );
+
+	perf_monitors = memnew(Tree);
+	perf_monitors->set_columns(2);
+	perf_monitors->set_column_title(0,"Monitor");
+	perf_monitors->set_column_title(1,"Value");
+	perf_monitors->set_column_titles_visible(true);
+	hsp->add_child(perf_monitors);
+	perf_monitors->set_select_mode(Tree::SELECT_MULTI);
+	perf_monitors->connect("multi_selected",this,"_performance_select");
+	perf_draw = memnew( Control );
+	perf_draw->connect("draw",this,"_performance_draw");
+	hsp->add_child(perf_draw);
+	hsp->set_name("Performance");
+	hsp->set_split_offset(300);
+	tabs->add_child(hsp);
+	perf_max.resize(Performance::MONITOR_MAX);
+
+	Map<String,TreeItem*> bases;
+	TreeItem *root=perf_monitors->create_item();
+	perf_monitors->set_hide_root(true);
+	for(int i=0;i<Performance::MONITOR_MAX;i++) {
+
+		String n = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i));
+		String base = n.get_slice("/",0);
+		String name = n.get_slice("/",1);
+		if (!bases.has(base)) {
+			TreeItem *b = perf_monitors->create_item(root);
+			b->set_text(0,base.capitalize());
+			b->set_editable(0,false);
+			b->set_selectable(0,false);
+			bases[base]=b;
+		}
+
+		TreeItem *it = perf_monitors->create_item(bases[base]);
+		it->set_editable(0,false);
+		it->set_selectable(0,true);
+		it->set_text(0,name.capitalize());
+		perf_items.push_back(it);
+		perf_max[i]=0;
+
+	}
+
+	info = memnew( HSplitContainer );
+	info->set_name("Info");
+	tabs->add_child(info);
+
+	VBoxContainer *info_left = memnew( VBoxContainer );
+	info_left->set_h_size_flags(SIZE_EXPAND_FILL);
+	info->add_child(info_left);
+	clicked_ctrl = memnew( LineEdit );
+	info_left->add_margin_child("Clicked Control:",clicked_ctrl);
+	clicked_ctrl_type = memnew( LineEdit );
+	info_left->add_margin_child("Clicked Control Type:",clicked_ctrl_type);
+	VBoxContainer *info_right = memnew(VBoxContainer);
+	info_right->set_h_size_flags(SIZE_EXPAND_FILL);
+	info->add_child(info_right);
+	HBoxContainer *inforhb = memnew( HBoxContainer );
+	info_right->add_child(inforhb);
+	Label *l2 = memnew( Label("Scene Tree:" ) );
+	l2->set_h_size_flags(SIZE_EXPAND_FILL);
+	inforhb->add_child( l2 );
+	Button *refresh = memnew( Button );
+	inforhb->add_child(refresh);
+	refresh->connect("pressed",this,"_scene_tree_request");
+	scene_tree_refresh=refresh;
+	MarginContainer *infomc = memnew( MarginContainer );
+	info_right->add_child(infomc);
+	infomc->set_v_size_flags(SIZE_EXPAND_FILL);
+	scene_tree = memnew( Tree );
+	infomc->add_child(scene_tree);
+
+
+	msgdialog = memnew( AcceptDialog );
+	add_child(msgdialog);
+
+	hide();
+	log_forced_visible=false;
+
+}
+
+ScriptEditorDebugger::~ScriptEditorDebugger() {
+
+//	inspector->edit(NULL);
+	memdelete(variables);
+
+	ppeer->set_stream_peer(Ref<StreamPeer>());
+
+	server->stop();
+
+}

+ 149 - 0
tools/html_fs/filesystem.js

@@ -0,0 +1,149 @@
+
+var Module;
+if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');
+if (!Module.expectedDataFileDownloads) {
+  Module.expectedDataFileDownloads = 0;
+  Module.finishedDataFileDownloads = 0;
+}
+Module.expectedDataFileDownloads++;
+(function() {
+
+    function fetchRemotePackage(packageName, callback, errback) {
+      var xhr = new XMLHttpRequest();
+      xhr.open('GET', packageName, true);
+      xhr.responseType = 'arraybuffer';
+      xhr.onprogress = function(event) {
+        var url = packageName;
+        if (event.loaded && event.total) {
+          if (!xhr.addedTotal) {
+            xhr.addedTotal = true;
+            if (!Module.dataFileDownloads) Module.dataFileDownloads = {};
+            Module.dataFileDownloads[url] = {
+              loaded: event.loaded,
+              total: event.total
+            };
+          } else {
+            Module.dataFileDownloads[url].loaded = event.loaded;
+          }
+          var total = 0;
+          var loaded = 0;
+          var num = 0;
+          for (var download in Module.dataFileDownloads) {
+          var data = Module.dataFileDownloads[download];
+            total += data.total;
+            loaded += data.loaded;
+            num++;
+          }
+          total = Math.ceil(total * Module.expectedDataFileDownloads/num);
+          if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')');
+        } else if (!Module.dataFileDownloads) {
+          if (Module['setStatus']) Module['setStatus']('Downloading data...');
+        }
+      };
+      xhr.onload = function(event) {
+        var packageData = xhr.response;
+        callback(packageData);
+      };
+      xhr.send(null);
+    };
+
+    function handleError(error) {
+      console.error('package error:', error);
+    };
+  
+      var fetched = null, fetchedCallback = null;
+      fetchRemotePackage('data.pck', function(data) {
+        if (fetchedCallback) {
+          fetchedCallback(data);
+          fetchedCallback = null;
+        } else {
+          fetched = data;
+        }
+      }, handleError);
+    
+  function runWithFS() {
+
+function assert(check, msg) {
+  if (!check) throw msg + new Error().stack;
+}
+
+    function DataRequest(start, end, crunched, audio) {
+      this.start = start;
+      this.end = end;
+      this.crunched = crunched;
+      this.audio = audio;
+    }
+    DataRequest.prototype = {
+      requests: {},
+      open: function(mode, name) {
+        this.name = name;
+        this.requests[name] = this;
+        Module['addRunDependency']('fp ' + this.name);
+      },
+      send: function() {},
+      onload: function() {
+        var byteArray = this.byteArray.subarray(this.start, this.end);
+
+          this.finish(byteArray);
+
+      },
+      finish: function(byteArray) {
+        var that = this;
+        Module['FS_createPreloadedFile'](this.name, null, byteArray, true, true, function() {
+          Module['removeRunDependency']('fp ' + that.name);
+        }, function() {
+          if (that.audio) {
+            Module['removeRunDependency']('fp ' + that.name); // workaround for chromium bug 124926 (still no audio with this, but at least we don't hang)
+          } else {
+            Module.printErr('Preloading file ' + that.name + ' failed');
+          }
+        }, false, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change
+        this.requests[this.name] = null;
+      },
+    };
+      new DataRequest(0, $DPLEN, 0, 0).open('GET', '/data.pck');
+
+    var PACKAGE_PATH;
+    if (typeof window === 'object') {
+      PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/');
+    } else {
+      // worker
+      PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/');
+    }
+    var PACKAGE_NAME = 'data.pck';
+    var REMOTE_PACKAGE_NAME = 'data.pck';
+    var PACKAGE_UUID = 'b39761ce-0348-4959-9b16-302ed8e1592e';
+  
+    function processPackageData(arrayBuffer) {
+      Module.finishedDataFileDownloads++;
+      assert(arrayBuffer, 'Loading data file failed.');
+      var byteArray = new Uint8Array(arrayBuffer);
+      var curr;
+      
+      // Reuse the bytearray from the XHR as the source for file reads.
+      DataRequest.prototype.byteArray = byteArray;
+          DataRequest.prototype.requests["/data.pck"].onload();
+          Module['removeRunDependency']('datafile_datapack');
+
+    };
+    Module['addRunDependency']('datafile_datapack');
+  
+    if (!Module.preloadResults) Module.preloadResults = {};
+  
+      Module.preloadResults[PACKAGE_NAME] = {fromCache: false};
+      if (fetched) {
+        processPackageData(fetched);
+        fetched = null;
+      } else {
+        fetchedCallback = processPackageData;
+      }
+    
+  }
+  if (Module['calledRun']) {
+    runWithFS();
+  } else {
+    if (!Module['preRun']) Module['preRun'] = [];
+    Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
+  }
+
+})();