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 years ago
parent
commit
58cda02a38
54 changed files with 1452 additions and 1120 deletions
  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
+  }
+
+})();