diff options
54 files changed, 923 insertions, 101 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index ec159da00f..960cdbac20 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -98,6 +98,13 @@ void _ResourceSaver::_bind_methods() { ObjectTypeDB::bind_method(_MD("save","path","resource:Resource"),&_ResourceSaver::save, DEFVAL(0)); ObjectTypeDB::bind_method(_MD("get_recognized_extensions","type"),&_ResourceSaver::get_recognized_extensions); + + BIND_CONSTANT(FLAG_RELATIVE_PATHS); + BIND_CONSTANT(FLAG_BUNDLE_RESOURCES); + BIND_CONSTANT(FLAG_CHANGE_PATH); + BIND_CONSTANT(FLAG_OMIT_EDITOR_PROPERTIES); + BIND_CONSTANT(FLAG_SAVE_BIG_ENDIAN); + BIND_CONSTANT(FLAG_COMPRESS); } _ResourceSaver::_ResourceSaver() { diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 18eb594760..bb68bbaad8 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -39,6 +39,16 @@ protected: static _ResourceSaver *singleton; public: + enum SaverFlags { + + FLAG_RELATIVE_PATHS=1, + FLAG_BUNDLE_RESOURCES=2, + FLAG_CHANGE_PATH=4, + FLAG_OMIT_EDITOR_PROPERTIES=8, + FLAG_SAVE_BIG_ENDIAN=16, + FLAG_COMPRESS=32, + }; + static _ResourceSaver *get_singleton() { return singleton; } Error save(const String &p_path,const RES& p_resource, uint32_t p_flags); diff --git a/core/image.cpp b/core/image.cpp index ccabd04d6f..db20862af5 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1660,6 +1660,31 @@ void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) { } + +void Image::premultiply_alpha() { + + if (data.size()==0) + return; + + if (format!=FORMAT_RGBA) + return; //not needed + + DVector<uint8_t>::Write wp = data.write(); + unsigned char *data_ptr=wp.ptr(); + + + for(int i=0;i<height;i++) { + for(int j=0;j<width;j++) { + + BColor bc = _get_pixel(j,i,data_ptr,0); + bc.r=(int(bc.r)*int(bc.a))>>8; + bc.g=(int(bc.g)*int(bc.a))>>8; + bc.b=(int(bc.b)*int(bc.a))>>8; + _put_pixel(j,i,bc,data_ptr); + } + } +} + void Image::fix_alpha_edges() { if (data.size()==0) diff --git a/core/image.h b/core/image.h index 186aceb1bf..99300fc3af 100644 --- a/core/image.h +++ b/core/image.h @@ -320,6 +320,7 @@ public: void decompress(); void fix_alpha_edges(); + void premultiply_alpha(); void blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest); void brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index bcd4197e11..29f27dcbda 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -25,6 +25,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_ } else if (p_mode==MODE_READ) { + writing=false; key=p_key; uint32_t magic = p_base->get_32(); print_line("MAGIC: "+itos(magic)); @@ -278,6 +279,10 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String& p_file){ FileAccessEncrypted::FileAccessEncrypted() { file=NULL; + pos=0; + eofed=false; + mode=MODE_MAX; + writing=false; } diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 503a009444..d2a685f6b0 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -188,6 +188,18 @@ void IP::erase_resolve_item(ResolverID p_id) { } +Array IP::_get_local_addresses() const { + + Array addresses; + List<IP_Address> ip_addresses; + get_local_addresses(&ip_addresses); + for(List<IP_Address>::Element *E=ip_addresses.front();E;E=E->next()) { + addresses.push_back(E->get()); + } + + return addresses; +} + void IP::_bind_methods() { ObjectTypeDB::bind_method(_MD("resolve_hostname","host"),&IP::resolve_hostname); @@ -195,6 +207,7 @@ void IP::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_resolve_item_status","id"),&IP::get_resolve_item_status); ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address); ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item); + ObjectTypeDB::bind_method(_MD("get_local_addresses"),&IP::_get_local_addresses); BIND_CONSTANT( RESOLVER_STATUS_NONE ); BIND_CONSTANT( RESOLVER_STATUS_WAITING ); diff --git a/core/io/ip.h b/core/io/ip.h index f1ef5fe794..0181dc7d12 100644 --- a/core/io/ip.h +++ b/core/io/ip.h @@ -66,16 +66,19 @@ protected: static void _bind_methods(); virtual IP_Address _resolve_hostname(const String& p_hostname)=0; + Array _get_local_addresses() const; static IP* (*_create)(); public: + IP_Address resolve_hostname(const String& p_hostname); // async resolver hostname ResolverID resolve_hostname_queue_item(const String& p_hostname); ResolverStatus get_resolve_item_status(ResolverID p_id) const; IP_Address get_resolve_item_address(ResolverID p_id) const; + virtual void get_local_addresses(List<IP_Address> *r_addresses) const=0; void erase_resolve_item(ResolverID p_id); static IP* get_singleton(); diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index 31e7d19bae..ffa0cad8e4 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -100,7 +100,7 @@ FileAccess *FileAccess::open(const String& p_path, int p_mode_flags, Error *r_er FileAccess *ret=NULL; if (!(p_mode_flags&WRITE) && PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled()) { ret = PackedData::get_singleton()->try_open_path(p_path); - if (ret) { + if (ret) { if (r_error) *r_error=OK; return ret; diff --git a/core/os/input.cpp b/core/os/input.cpp index d7c0d86d64..70733aadec 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -211,6 +211,8 @@ void InputDefault::parse_input_event(const InputEvent& p_event) { if (p_event.key.scancode==0) break; + // print_line(p_event); + if (p_event.key.pressed) keys_pressed.insert(p_event.key.scancode); else diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index a8e02526b9..d01331a256 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -37,7 +37,7 @@ void MainLoop::_bind_methods() { BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT); BIND_CONSTANT(NOTIFICATION_WM_QUIT_REQUEST); BIND_CONSTANT(NOTIFICATION_WM_UNFOCUS_REQUEST); - + BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING); }; diff --git a/core/script_language.h b/core/script_language.h index 9731273610..560de520ca 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -141,6 +141,7 @@ public: virtual int find_function(const String& p_function,const String& p_code) const=0; virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const=0; virtual Error complete_keyword(const String& p_code, int p_line, const String& p_base_path, const String& p_keyword, List<String>* r_options) { return ERR_UNAVAILABLE; } + virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const=0; /* DEBUGGER FUNCTIONS */ diff --git a/demos/2d/platformer/stage.xml b/demos/2d/platformer/stage.xml index 952c21e936..6a112e02aa 100644 --- a/demos/2d/platformer/stage.xml +++ b/demos/2d/platformer/stage.xml @@ -3,10 +3,10 @@ <ext_resource path="res://music.ogg" type="AudioStream"></ext_resource> <ext_resource path="res://tileset.xml" type="TileSet"></ext_resource> <ext_resource path="res://coin.xml" type="PackedScene"></ext_resource> + <ext_resource path="res://player.xml" type="PackedScene"></ext_resource> + <ext_resource path="res://moving_platform.xml" type="PackedScene"></ext_resource> <ext_resource path="res://seesaw.xml" type="PackedScene"></ext_resource> <ext_resource path="res://enemy.xml" type="PackedScene"></ext_resource> - <ext_resource path="res://moving_platform.xml" type="PackedScene"></ext_resource> - <ext_resource path="res://player.xml" type="PackedScene"></ext_resource> <ext_resource path="res://parallax_bg.xml" type="PackedScene"></ext_resource> <main_resource> <dictionary name="_bundled" shared="false"> @@ -160,9 +160,13 @@ <string> "pixel_snap" </string> <bool> False </bool> <string> "zoom" </string> - <real> 0.735092 </real> + <real> 0.54036 </real> + <string> "use_snap" </string> + <bool> False </bool> <string> "ofs" </string> - <vector2> 55.9232, 767.661 </vector2> + <vector2> 418.81, 615.088 </vector2> + <string> "snap" </string> + <int> 10 </int> </dictionary> <string> "3D" </string> <dictionary shared="false"> diff --git a/doc/make_doc.sh b/doc/make_doc.sh index a76f568bfc..a76f568bfc 100755..100644 --- a/doc/make_doc.sh +++ b/doc/make_doc.sh diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index f43b43bd77..472e92f23a 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -6436,7 +6436,10 @@ void RasterizerGLES2::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) { case VS::MATERIAL_BLEND_MODE_MUL: { glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - + } break; + case VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA: { + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); } break; } diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 66bdf15db4..f36741d586 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -64,6 +64,9 @@ void main() { highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ); color = vec4(vec3(enc32),1.0); #endif + +// color.rgb*=color.a; gl_FragColor = color; + } diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index c11426d356..18b19ca095 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -30,12 +30,24 @@ #if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) + #ifdef WINDOWS_ENABLED +#define WINVER 0x0600 #include <ws2tcpip.h> #include <winsock2.h> #include <windows.h> +#include <stdio.h> +#include <iphlpapi.h> #else #include <netdb.h> +#ifdef ANDROID_ENABLED +#include "platform/android/ifaddrs_android.h" +#else +#include <ifaddrs.h> +#endif +#include <arpa/inet.h> +#include <sys/socket.h> + #endif IP_Address IP_Unix::_resolve_hostname(const String& p_hostname) { @@ -52,6 +64,93 @@ IP_Address IP_Unix::_resolve_hostname(const String& p_hostname) { } +#if defined(WINDOWS_ENABLED) + +void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const { + + ULONG buf_size = 1024; + IP_ADAPTER_ADDRESSES* addrs; + + while (true) { + + addrs = (IP_ADAPTER_ADDRESSES*)memalloc(buf_size); + int err = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_SKIP_FRIENDLY_NAME, + NULL, addrs, &buf_size); + if (err == NO_ERROR) { + break; + }; + memfree(addrs); + if (err == ERROR_BUFFER_OVERFLOW) { + continue; // will go back and alloc the right size + }; + + ERR_EXPLAIN("Call to GetAdaptersAddresses failed with error " + itos(err)); + ERR_FAIL(); + return; + }; + + + IP_ADAPTER_ADDRESSES* adapter = addrs; + + while (adapter != NULL) { + + IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; + while (address != NULL) { + + char addr_chr[INET_ADDRSTRLEN]; + SOCKADDR_IN* ipv4 = reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr); + + IP_Address ip; + ip.host= *((unsigned long*)&ipv4->sin_addr); + + + //inet_ntop(AF_INET, &ipv4->sin_addr, addr_chr, INET_ADDRSTRLEN); + + r_addresses->push_back(ip); + + address = address->Next; + }; + adapter = adapter->Next; + }; + + memfree(addrs); +}; + + +#else + +void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const { + + struct ifaddrs * ifAddrStruct=NULL; + struct ifaddrs * ifa=NULL; + + getifaddrs(&ifAddrStruct); + + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4 + // is a valid IP4 Address + + IP_Address ip; + ip.host= *((unsigned long*)&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr); + + r_addresses->push_back(ip); + }/* else if (ifa->ifa_addr->sa_family==AF_INET6) { // check it is IP6 + // is a valid IP6 Address + tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; + char addressBuffer[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN); + printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); + } */ + } + + if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct); + +} +#endif + void IP_Unix::make_default() { _create=_create_unix; diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index ec2d42c837..2fd5cf964b 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -41,6 +41,8 @@ class IP_Unix : public IP { static IP* _create_unix(); public: + virtual void get_local_addresses(List<IP_Address> *r_addresses) const; + static void make_default(); IP_Unix(); }; diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index 48f0092827..548b10cf15 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1263,6 +1263,16 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode * gdfunc->name=func_name; gdfunc->_script=p_script; gdfunc->source=source; + +#ifdef DEBUG_ENABLED + + { + gdfunc->func_cname=(String(source)+" - "+String(func_name)).utf8(); + gdfunc->_func_cname=gdfunc->func_cname.get_data(); + + } + +#endif if (p_func) { gdfunc->_initial_line=p_func->line; } else { diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index f8717c292f..5f5de8b5db 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -787,3 +787,67 @@ Error GDScriptLanguage::complete_keyword(const String& p_code, int p_line, const return OK; } +void GDScriptLanguage::auto_indent_code(String& p_code,int p_from_line,int p_to_line) const { + + + Vector<String> lines = p_code.split("\n"); + List<int> indent_stack; + + for(int i=0;i<lines.size();i++) { + + String l = lines[i]; + int tc=0; + for(int j=0;j<l.length();j++) { + if (l[j]==' ' || l[j]=='\t') { + + tc++; + } else { + break; + } + } + + + String st = l.substr(tc,l.length()).strip_edges(); + if (st=="" || st.begins_with("#")) + continue; //ignore! + + int ilevel=0; + if (indent_stack.size()) { + ilevel=indent_stack.back()->get(); + } + + if (tc>ilevel) { + indent_stack.push_back(tc); + } else if (tc<ilevel) { + while(indent_stack.size() && indent_stack.back()->get()>tc) { + indent_stack.pop_back(); + } + + if (indent_stack.size() && indent_stack.back()->get()!=tc) + indent_stack.push_back(tc); //this is not right but gets the job done + } + + if (i>=p_from_line) { + + l=""; + for(int j=0;j<indent_stack.size();j++) + l+="\t"; + l+=st; + + + } else if (i>p_to_line) { + break; + } + + //print_line(itos(indent_stack.size())+","+itos(tc)+": "+l); + lines[i]=l; + } + + p_code=""; + for(int i=0;i<lines.size();i++) { + if (i>0) + p_code+="\n"; + p_code+=lines[i]; + } + +} diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f540660cd3..2829132d99 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1221,6 +1221,15 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { return; //go back a level } + if (pending_newline!=-1) { + + NewLineNode *nl = alloc_node<NewLineNode>(); + nl->line=pending_newline; + p_block->statements.push_back(nl); + pending_newline=-1; + + } + switch(token) { @@ -1234,16 +1243,19 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { } break; case GDTokenizer::TK_NEWLINE: { - NewLineNode *nl = alloc_node<NewLineNode>(); - nl->line=tokenizer->get_token_line(); - p_block->statements.push_back(nl); - if (!_parse_newline()) { if (!error_set) { p_block->end_line=tokenizer->get_token_line(); + pending_newline=p_block->end_line; + } return; } + + NewLineNode *nl = alloc_node<NewLineNode>(); + nl->line=tokenizer->get_token_line(); + p_block->statements.push_back(nl); + } break; case GDTokenizer::TK_CF_PASS: { if (tokenizer->get_token(1)!=GDTokenizer::TK_SEMICOLON && tokenizer->get_token(1)!=GDTokenizer::TK_NEWLINE ) { @@ -1782,6 +1794,7 @@ void GDParser::_parse_class(ClassNode *p_class) { case GDTokenizer::TK_PR_FUNCTION: { bool _static=false; + pending_newline=-1; if (tokenizer->get_token(-1)==GDTokenizer::TK_PR_STATIC) { @@ -2490,6 +2503,7 @@ void GDParser::clear() { tab_level.push_back(0); error_line=0; error_column=0; + pending_newline=-1; parenthesis=0; current_export.type=Variant::NIL; error=""; @@ -2501,6 +2515,7 @@ GDParser::GDParser() { head=NULL; list=NULL; tokenizer=NULL; + pending_newline=-1; clear(); } diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 278e5f543d..825bd954d1 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -362,6 +362,8 @@ private: int error_line; int error_column; + int pending_newline; + List<int> tab_level; String base_path; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index c6183aadc4..0d49f79f1c 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1159,6 +1159,9 @@ GDFunction::GDFunction() { _stack_size=0; _call_size=0; name="<anonymous>"; +#ifdef DEBUG_ENABLED + _func_cname=NULL; +#endif } diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 983899240a..56da0bb2e3 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -118,10 +118,13 @@ friend class GDCompiler; Vector<Variant> constants; Vector<StringName> global_names; Vector<int> default_arguments; - Vector<int> code; +#ifdef DEBUG_ENABLED + CharString func_cname; + const char*_func_cname; +#endif - List<StackDebug> stack_debug; + List<StackDebug> stack_debug; _FORCE_INLINE_ Variant *_get_variant(int p_address,GDInstance *p_instance,GDScript *p_script,Variant &self,Variant *p_stack,String& r_error) const; _FORCE_INLINE_ String _get_call_error(const Variant::CallError& p_err, const String& p_where,const Variant**argptrs) const; @@ -427,6 +430,7 @@ public: virtual int find_function(const String& p_function,const String& p_code) const; virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const; virtual Error complete_keyword(const String& p_code, int p_line, const String& p_base_path,const String& p_keyword, List<String>* r_options); + virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const; /* DEBUGGER FUNCTIONS */ diff --git a/platform/android/SCsub b/platform/android/SCsub index 5464376c31..8e61b7d8e0 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -13,6 +13,7 @@ android_files = [ 'dir_access_jandroid.cpp', 'thread_jandroid.cpp', 'audio_driver_jandroid.cpp', + 'ifaddrs_android.cpp', 'android_native_app_glue.c', 'java_glue.cpp' ] diff --git a/platform/android/ifaddrs_android.cpp b/platform/android/ifaddrs_android.cpp new file mode 100644 index 0000000000..c1e9eb3584 --- /dev/null +++ b/platform/android/ifaddrs_android.cpp @@ -0,0 +1,221 @@ +/* + * libjingle + * Copyright 2012, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ifaddrs_android.h" +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/utsname.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <net/if.h> +#include <unistd.h> +#include <errno.h> +#include <linux/netlink.h> +#include <linux/rtnetlink.h> +struct netlinkrequest { + nlmsghdr header; + ifaddrmsg msg; +}; +namespace { +const int kMaxReadSize = 4096; +}; +static int set_ifname(struct ifaddrs* ifaddr, int interface) { + char buf[IFNAMSIZ] = {0}; + char* name = if_indextoname(interface, buf); + if (name == NULL) { + return -1; + } + ifaddr->ifa_name = new char[strlen(name) + 1]; + strncpy(ifaddr->ifa_name, name, strlen(name) + 1); + return 0; +} +static int set_flags(struct ifaddrs* ifaddr) { + int fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) { + return -1; + } + ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1); + int rc = ioctl(fd, SIOCGIFFLAGS, &ifr); + close(fd); + if (rc == -1) { + return -1; + } + ifaddr->ifa_flags = ifr.ifr_flags; + return 0; +} +static int set_addresses(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* data, + size_t len) { + if (msg->ifa_family == AF_INET) { + sockaddr_in* sa = new sockaddr_in; + sa->sin_family = AF_INET; + memcpy(&sa->sin_addr, data, len); + ifaddr->ifa_addr = reinterpret_cast<sockaddr*>(sa); + } else if (msg->ifa_family == AF_INET6) { + sockaddr_in6* sa = new sockaddr_in6; + sa->sin6_family = AF_INET6; + sa->sin6_scope_id = msg->ifa_index; + memcpy(&sa->sin6_addr, data, len); + ifaddr->ifa_addr = reinterpret_cast<sockaddr*>(sa); + } else { + return -1; + } + return 0; +} +static int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) { + char* prefix = NULL; + if (family == AF_INET) { + sockaddr_in* mask = new sockaddr_in; + mask->sin_family = AF_INET; + memset(&mask->sin_addr, 0, sizeof(in_addr)); + ifaddr->ifa_netmask = reinterpret_cast<sockaddr*>(mask); + if (prefixlen > 32) { + prefixlen = 32; + } + prefix = reinterpret_cast<char*>(&mask->sin_addr); + } else if (family == AF_INET6) { + sockaddr_in6* mask = new sockaddr_in6; + mask->sin6_family = AF_INET6; + memset(&mask->sin6_addr, 0, sizeof(in6_addr)); + ifaddr->ifa_netmask = reinterpret_cast<sockaddr*>(mask); + if (prefixlen > 128) { + prefixlen = 128; + } + prefix = reinterpret_cast<char*>(&mask->sin6_addr); + } else { + return -1; + } + for (int i = 0; i < (prefixlen / 8); i++) { + *prefix++ = 0xFF; + } + char remainder = 0xff; + remainder <<= (8 - prefixlen % 8); + *prefix = remainder; + return 0; +} +static int populate_ifaddrs(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* bytes, + size_t len) { + if (set_ifname(ifaddr, msg->ifa_index) != 0) { + return -1; + } + if (set_flags(ifaddr) != 0) { + return -1; + } + if (set_addresses(ifaddr, msg, bytes, len) != 0) { + return -1; + } + if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) { + return -1; + } + return 0; +} +int getifaddrs(struct ifaddrs** result) { + int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (fd < 0) { + return -1; + } + netlinkrequest ifaddr_request; + memset(&ifaddr_request, 0, sizeof(ifaddr_request)); + ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST; + ifaddr_request.header.nlmsg_type = RTM_GETADDR; + ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(ifaddrmsg)); + ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0); + if (static_cast<size_t>(count) != ifaddr_request.header.nlmsg_len) { + close(fd); + return -1; + } + struct ifaddrs* start = NULL; + struct ifaddrs* current = NULL; + char buf[kMaxReadSize]; + ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0); + while (amount_read > 0) { + nlmsghdr* header = reinterpret_cast<nlmsghdr*>(&buf[0]); + size_t header_size = static_cast<size_t>(amount_read); + for ( ; NLMSG_OK(header, header_size); + header = NLMSG_NEXT(header, header_size)) { + switch (header->nlmsg_type) { + case NLMSG_DONE: + // Success. Return. + *result = start; + close(fd); + return 0; + case NLMSG_ERROR: + close(fd); + freeifaddrs(start); + return -1; + case RTM_NEWADDR: { + ifaddrmsg* address_msg = + reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(header)); + rtattr* rta = IFA_RTA(address_msg); + ssize_t payload_len = IFA_PAYLOAD(header); + while (RTA_OK(rta, payload_len)) { + if (rta->rta_type == IFA_ADDRESS) { + int family = address_msg->ifa_family; + if (family == AF_INET || family == AF_INET6) { + ifaddrs* newest = new ifaddrs; + memset(newest, 0, sizeof(ifaddrs)); + if (current) { + current->ifa_next = newest; + } else { + start = newest; + } + if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta), + RTA_PAYLOAD(rta)) != 0) { + freeifaddrs(start); + *result = NULL; + return -1; + } + current = newest; + } + } + rta = RTA_NEXT(rta, payload_len); + } + break; + } + } + } + amount_read = recv(fd, &buf, kMaxReadSize, 0); + } + close(fd); + freeifaddrs(start); + return -1; +} +void freeifaddrs(struct ifaddrs* addrs) { + struct ifaddrs* last = NULL; + struct ifaddrs* cursor = addrs; + while (cursor) { + delete[] cursor->ifa_name; + delete cursor->ifa_addr; + delete cursor->ifa_netmask; + last = cursor; + cursor = cursor->ifa_next; + delete last; + } +} diff --git a/platform/android/ifaddrs_android.h b/platform/android/ifaddrs_android.h new file mode 100644 index 0000000000..539fa40455 --- /dev/null +++ b/platform/android/ifaddrs_android.h @@ -0,0 +1,46 @@ +/* + * libjingle + * Copyright 2013, Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef TALK_BASE_IFADDRS_ANDROID_H_ +#define TALK_BASE_IFADDRS_ANDROID_H_ +#include <stdio.h> +#include <sys/socket.h> +// Implementation of getifaddrs for Android. +// Fills out a list of ifaddr structs (see below) which contain information +// about every network interface available on the host. +// See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function). +struct ifaddrs { + struct ifaddrs* ifa_next; + char* ifa_name; + unsigned int ifa_flags; + struct sockaddr* ifa_addr; + struct sockaddr* ifa_netmask; + // Real ifaddrs has broadcast, point to point and data members. + // We don't need them (yet?). +}; +int getifaddrs(struct ifaddrs** result); +void freeifaddrs(struct ifaddrs* addrs); +#endif // TALK_BASE_IFADDRS_ANDROID_H_ diff --git a/platform/android/java/src/com/android/godot/Godot.java b/platform/android/java/src/com/android/godot/Godot.java index 35ecdc818e..bd973ce49b 100644 --- a/platform/android/java/src/com/android/godot/Godot.java +++ b/platform/android/java/src/com/android/godot/Godot.java @@ -65,6 +65,9 @@ import java.io.InputStream; public class Godot extends Activity implements SensorEventListener { + + static final int MAX_SINGLETONS = 64; + static public class SingletonBase { protected void registerClass(String p_name, String[] p_methods) { @@ -104,8 +107,21 @@ public class Godot extends Activity implements SensorEventListener } + + Godot.singletons[Godot.singleton_count++]=this; + } + + protected void onMainActivityResult(int requestCode, int resultCode, Intent data) { + + + } + + protected void onMainResume() { + + } + public void registerMethods() {} } @@ -133,6 +149,12 @@ public class Godot extends Activity implements SensorEventListener //setTitle(title); } + + static SingletonBase singletons[] = new SingletonBase[MAX_SINGLETONS]; + static int singleton_count=0; + + + public interface ResultCallback { public void callback(int requestCode, int resultCode, Intent data); }; @@ -147,6 +169,11 @@ public class Godot extends Activity implements SensorEventListener result_callback.callback(requestCode, resultCode, data); result_callback = null; }; + + for(int i=0;i<singleton_count;i++) { + + singletons[i].onMainActivityResult(requestCode,resultCode,data); + } }; public void onVideoInit(boolean use_gl2) { @@ -271,6 +298,12 @@ public class Godot extends Activity implements SensorEventListener mView.onResume(); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); GodotLib.focusin(); + + for(int i=0;i<singleton_count;i++) { + + singletons[i].onMainResume(); + } + } @Override public void onSensorChanged(SensorEvent event) { diff --git a/platform/android/java/src/com/android/godot/GodotPaymentV3.java b/platform/android/java/src/com/android/godot/GodotPaymentV3.java index 23f5bf34d3..dba4a9a774 100644 --- a/platform/android/java/src/com/android/godot/GodotPaymentV3.java +++ b/platform/android/java/src/com/android/godot/GodotPaymentV3.java @@ -1,7 +1,10 @@ package com.android.godot; +import org.json.JSONObject; + import android.app.Activity; +import android.util.Log; public class GodotPaymentV3 extends Godot.SingletonBase { @@ -13,14 +16,17 @@ public class GodotPaymentV3 extends Godot.SingletonBase { private String accessToken; private String purchaseValidationUrlPrefix; + + private String transactionId; - public void purchase( String _sku) { + public void purchase( String _sku, String _transactionId) { final String sku = _sku; + final String transactionId = _transactionId; activity.getPaymentsManager().setBaseSingleton(this); activity.runOnUiThread(new Runnable() { @Override public void run() { - activity.getPaymentsManager().requestPurchase(sku); + activity.getPaymentsManager().requestPurchase(sku, transactionId); } }); }; @@ -38,22 +44,31 @@ public class GodotPaymentV3 extends Godot.SingletonBase { public GodotPaymentV3(Activity p_activity) { - registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix"}); + registerClass("GodotPayments", new String[] {"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature"}); activity=(Godot) p_activity; } + private String signature; + public String getSignature(){ + return this.signature; + } + - public void callbackSuccess(String ticket){ - GodotLib.callobject(purchaseCallbackId, "purchase_success", new Object[]{ticket}); + public void callbackSuccess(String ticket, String signature){ + Log.d(this.getClass().getName(), "PRE-Send callback to purchase success"); + GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature}); + Log.d(this.getClass().getName(), "POST-Send callback to purchase success"); } public void callbackFail(){ - GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{}); + GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{}); +// GodotLib.callobject(purchaseCallbackId, "purchase_fail", new Object[]{}); } public void callbackCancel(){ - GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{}); + GodotLib.calldeferred(purchaseCallbackId, "purchase_cancel", new Object[]{}); +// GodotLib.callobject(purchaseCallbackId, "purchase_cancel", new Object[]{}); } public int getPurchaseCallbackId() { @@ -84,4 +99,12 @@ public class GodotPaymentV3 extends Godot.SingletonBase { this.accessToken = accessToken; } + public void setTransactionId(String transactionId){ + this.transactionId = transactionId; + } + + public String getTransactionId(){ + return this.transactionId; + } + } diff --git a/platform/android/java/src/com/android/godot/payments/ConsumeTask.java b/platform/android/java/src/com/android/godot/payments/ConsumeTask.java index 855bc0578d..c983960770 100644 --- a/platform/android/java/src/com/android/godot/payments/ConsumeTask.java +++ b/platform/android/java/src/com/android/godot/payments/ConsumeTask.java @@ -56,8 +56,7 @@ abstract public class ConsumeTask { protected void onPostExecute(String param){ if(param == null){ - - success(new PaymentsCache(context).getConsumableValue("ticket", sku)); + success( new PaymentsCache(context).getConsumableValue("ticket", sku) ); }else{ error(param); } diff --git a/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java b/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java index a32ecf2895..a810ac40ae 100644 --- a/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java @@ -34,7 +34,8 @@ abstract public class HandlePurchaseTask { String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA"); Log.d("XXX", "Purchase data:" + purchaseData); -// String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE"); + String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE"); + Log.d("XXX", "Purchase signature:" + dataSignature); if (resultCode == Activity.RESULT_OK) { @@ -57,12 +58,13 @@ abstract public class HandlePurchaseTask { error("Untrusted callback"); return; } - + Log.d("XXX", "Este es el product ID:" + productId); + pc.setConsumableValue("ticket_signautre", productId, dataSignature); pc.setConsumableValue("ticket", productId, purchaseData); pc.setConsumableFlag("block", productId, true); pc.setConsumableValue("token", productId, purchaseToken); - success(productId); + success(productId, dataSignature); return; } catch (JSONException e) { error(e.getMessage()); @@ -72,7 +74,7 @@ abstract public class HandlePurchaseTask { } } - abstract protected void success(String ticket); + abstract protected void success(String ticket, String signature); abstract protected void error(String message); abstract protected void canceled(); diff --git a/platform/android/java/src/com/android/godot/payments/PaymentsCache.java b/platform/android/java/src/com/android/godot/payments/PaymentsCache.java index ba84097732..7337acc0b8 100644 --- a/platform/android/java/src/com/android/godot/payments/PaymentsCache.java +++ b/platform/android/java/src/com/android/godot/payments/PaymentsCache.java @@ -2,6 +2,7 @@ package com.android.godot.payments; import android.content.Context; import android.content.SharedPreferences; +import android.util.Log; public class PaymentsCache { @@ -30,12 +31,14 @@ public class PaymentsCache { SharedPreferences sharedPref = context.getSharedPreferences("consumables_" + set, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); editor.putString(sku, value); + Log.d("XXX", "Setting asset: consumables_" + set + ":" + sku); editor.commit(); } public String getConsumableValue(String set, String sku){ SharedPreferences sharedPref = context.getSharedPreferences( "consumables_" + set, Context.MODE_PRIVATE); + Log.d("XXX", "Getting asset: consumables_" + set + ":" + sku); return sharedPref.getString(sku, null); } diff --git a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java index e8c487dbd8..d85a8ea8ea 100644 --- a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java @@ -6,6 +6,7 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; +import android.util.Log; import com.android.godot.Godot; import com.android.godot.GodotPaymentV3; @@ -63,7 +64,7 @@ public class PaymentsManager { } }; - public void requestPurchase(String sku){ + public void requestPurchase(String sku, String transactionId){ new PurchaseTask(mService, Godot.getInstance()) { @Override @@ -76,7 +77,7 @@ public class PaymentsManager { protected void canceled() { godotPaymentV3.callbackCancel(); } - }.purchase(sku); + }.purchase(sku, transactionId); } @@ -84,13 +85,14 @@ public class PaymentsManager { new HandlePurchaseTask(activity){ @Override - protected void success(final String sku) { + protected void success(final String sku, final String signature) { new ConsumeTask(mService, activity) { @Override protected void success(String ticket) { // godotPaymentV3.callbackSuccess(""); - godotPaymentV3.callbackSuccess(ticket); + Log.d("XXX", "calling success:" + signature); + godotPaymentV3.callbackSuccess(ticket, signature); } @Override @@ -131,7 +133,7 @@ public class PaymentsManager { @Override protected void success(String ticket) { - godotPaymentV3.callbackSuccess(ticket); + godotPaymentV3.callbackSuccess(ticket, null); } diff --git a/platform/android/java/src/com/android/godot/payments/PurchaseTask.java b/platform/android/java/src/com/android/godot/payments/PurchaseTask.java index f5d8a0298a..0856b4e900 100644 --- a/platform/android/java/src/com/android/godot/payments/PurchaseTask.java +++ b/platform/android/java/src/com/android/godot/payments/PurchaseTask.java @@ -31,7 +31,7 @@ abstract public class PurchaseTask { private boolean isLooping = false; - public void purchase(final String sku){ + public void purchase(final String sku, final String transactionId){ Log.d("XXX", "Starting purchase for: " + sku); PaymentsCache pc = new PaymentsCache(context); Boolean isBlocked = pc.getConsumableFlag("block", sku); @@ -40,7 +40,7 @@ abstract public class PurchaseTask { // error("Awaiting payment confirmation"); // return; // } - final String hash = Crypt.createRandomHash() + Crypt.createRandomHash(); + final String hash = transactionId; Bundle buyIntentBundle; try { @@ -76,7 +76,7 @@ abstract public class PurchaseTask { return; } isLooping=true; - PurchaseTask.this.purchase(sku); + PurchaseTask.this.purchase(sku, transactionId); } diff --git a/platform/android/sign.sh b/platform/android/sign.sh index 8f760e6312..830da05a37 100755 --- a/platform/android/sign.sh +++ b/platform/android/sign.sh @@ -1,6 +1,6 @@ #!/bin/bash -jarsigner -digestalg SHA1 -sigalg MD5withRSA -verbose -keystore /home/luis/Downloads/carnavalguachin.keystore -storepass 12345678 "$1" momoselacome +jarsigner -digestalg SHA1 -sigalg MD5withRSA -verbose -keystore my-release-key.keystore "$1" reduz echo "" echo "" diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index a02891e817..ec6e4c98f1 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -21,7 +21,8 @@ def get_opts(): return [ ('IPHONEPLATFORM', 'name of the iphone platform', 'iPhoneOS'), ('IPHONEPATH', 'the path to iphone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'), - ('IPHONESDK', 'path to the iphone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/'), + ('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS7.0'), + ('IPHONESDK', 'path to the iphone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/${IOS_SDK_VERSION}.sdk/'), ('game_center', 'Support for game center', 'yes'), ('store_kit', 'Support for in-app store', 'yes'), ('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'), @@ -37,6 +38,7 @@ def get_flags(): ('tools', 'yes'), ('nedmalloc', 'no'), ('webp', 'yes'), + ('openssl','builtin'), #use builtin openssl ] @@ -81,7 +83,7 @@ def configure(env): '-framework', 'AudioToolbox', '-framework', 'SystemConfiguration', '-framework', 'Security', - '-framework', 'AdSupport', + #'-framework', 'AdSupport', '-framework', 'MediaPlayer', ]) diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index c482c36a30..500c7c7174 100755 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -50,6 +50,7 @@ static String keyboard_text; static GLView* _instance = NULL; static bool video_found_error = false; +static bool video_playing = false; static float video_previous_volume = 0.0f; void _show_keyboard(String p_existing) { @@ -91,24 +92,29 @@ bool _play_video(String p_path, float p_volume) { [_instance addSubview:_instance.moviePlayerController.view]; [_instance.moviePlayerController play]; + video_playing = true; + return true; } bool _is_video_playing() { //NSInteger playback_state = _instance.moviePlayerController.playbackState; - if (video_found_error) - return false; - return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying); + return video_playing || _instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying; + //if (video_found_error) + // return false; + //return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying); } void _pause_video() { [_instance.moviePlayerController pause]; + video_playing = false; } void _stop_video() { [_instance.moviePlayerController stop]; [_instance.moviePlayerController.view removeFromSuperview]; [[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume]; + video_playing = false; } @implementation GLView @@ -549,6 +555,7 @@ static void clear_touches() { [_instance.moviePlayerController.view removeFromSuperview]; [[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume]; + video_playing = false; } @end diff --git a/platform/windows/detect.py b/platform/windows/detect.py index d1c5e96d32..7f71332517 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -117,7 +117,7 @@ def configure(env): env.Append(CCFLAGS=['/DGLES2_ENABLED'])
env.Append(CCFLAGS=['/DGLES1_ENABLED'])
env.Append(CCFLAGS=['/DGLEW_ENABLED'])
- env.Append(LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32','wsock32', 'shell32','advapi32'])
+ env.Append(LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI', 'wsock32', 'shell32','advapi32'])
env.Append(LIBPATH=[os.getenv("WindowsSdkDir")+"/Lib"])
if (os.getenv("DXSDK_DIR")):
@@ -196,7 +196,7 @@ def configure(env): env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows'])
env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLES1_ENABLED','-DGLEW_ENABLED'])
- env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','wsock32','kernel32'])
+ env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32'])
#'d3dx9d'
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
env.Append(LINKFLAGS=['-g'])
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 2cb8247799..14d31b864c 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -480,7 +480,7 @@ unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) { return state; } -void OS_X11::handle_key_event(XKeyEvent *p_event) { +void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { // X11 functions don't know what const is @@ -591,17 +591,9 @@ void OS_X11::handle_key_event(XKeyEvent *p_event) { // To detect them, i use XPeekEvent and check that their // difference in time is below a treshold. - bool echo=false; - - if (xkeyevent->type == KeyPress) { - - // saved the time of the last keyrelease to see - // if it's the same as this keypress. - if (xkeyevent->time==last_keyrelease_time) - echo=true; - } else { - + if (xkeyevent->type != KeyPress) { + // make sure there are events pending, // so this call won't block. if (XPending(x11_display)>0) { @@ -615,17 +607,21 @@ void OS_X11::handle_key_event(XKeyEvent *p_event) { // not very helpful today. ::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time); - if (peek_event.type == KeyPress && tresh<5 ) - echo=true; + if (peek_event.type == KeyPress && tresh<5 ) { + KeySym rk; + nbytes=XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL); + if (rk==keysym_keycode) { + XEvent event; + XNextEvent(x11_display, &event); //erase next event + handle_key_event( (XKeyEvent*)&event,true ); + return; //ignore current, echo next + } + } // use the time from peek_event so it always works - last_keyrelease_time=peek_event.xkey.time; - } else { - last_keyrelease_time=xkeyevent->time; } - // save the time to check for echo when keypress happens - + // save the time to check for echo when keypress happens } @@ -643,7 +639,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event) { event.key.scancode=keycode; event.key.unicode=unicode; - event.key.echo=echo; + event.key.echo=p_echo; if (event.key.scancode==KEY_BACKTAB) { //make it consistent accross platforms. @@ -1017,7 +1013,7 @@ String OS_X11::get_name() { Error OS_X11::shell_open(String p_uri) { - + return ERR_UNAVAILABLE; } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 491b8fa00d..77ef37f6f4 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -90,7 +90,7 @@ class OS_X11 : public OS_Unix { MouseMode mouse_mode; Point2i center; - void handle_key_event(XKeyEvent *p_event); + void handle_key_event(XKeyEvent *p_event,bool p_echo=false); void process_xevents(); virtual void delete_main_loop(); IP_Unix *ip_unix; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index a94b2347fc..dea2411f1d 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -447,7 +447,7 @@ float CanvasItem::get_self_opacity() const { void CanvasItem::set_blend_mode(BlendMode p_blend_mode) { - ERR_FAIL_INDEX(p_blend_mode,4); + ERR_FAIL_INDEX(p_blend_mode,5); blend_mode=p_blend_mode; VisualServer::get_singleton()->canvas_item_set_blend_mode(canvas_item,VS::MaterialBlendMode(blend_mode)); @@ -794,7 +794,7 @@ void CanvasItem::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/behind_parent"), _SCS("set_draw_behind_parent"),_SCS("is_draw_behind_parent_enabled") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility - ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); + ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") ); //exporting these two things doesn't really make much sense i think //ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") ); //ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled")); @@ -810,6 +810,7 @@ void CanvasItem::_bind_methods() { BIND_CONSTANT( BLEND_MODE_ADD ); BIND_CONSTANT( BLEND_MODE_SUB ); BIND_CONSTANT( BLEND_MODE_MUL ); + BIND_CONSTANT( BLEND_MODE_PREMULT_ALPHA ); BIND_CONSTANT( NOTIFICATION_DRAW); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 1c104c5fc2..604eef0527 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -49,7 +49,8 @@ public: BLEND_MODE_MIX, //default BLEND_MODE_ADD, BLEND_MODE_SUB, - BLEND_MODE_MUL + BLEND_MODE_MUL, + BLEND_MODE_PREMULT_ALPHA }; private: diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 637a816112..2ddfa1078b 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -158,7 +158,7 @@ void Material::_bind_methods() { for(int i=0;i<HINT_MAX;i++) ADD_PROPERTYI( PropertyInfo( Variant::BOOL, String()+"hints/"+_hint_names[i] ),_SCS("set_hint"),_SCS("get_hint"),_hint_indices[i]); - ADD_PROPERTY( PropertyInfo( Variant::INT, "params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub" ), _SCS("set_blend_mode"),_SCS("get_blend_mode")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "params/blend_mode",PROPERTY_HINT_ENUM,"Mix,Add,Sub,PMAlpha" ), _SCS("set_blend_mode"),_SCS("get_blend_mode")); ADD_PROPERTY( PropertyInfo( Variant::REAL, "params/line_width",PROPERTY_HINT_RANGE,"0.1,32.0,0.1" ), _SCS("set_line_width"),_SCS("get_line_width")); @@ -189,6 +189,8 @@ void Material::_bind_methods() { BIND_CONSTANT( BLEND_MODE_MIX ); BIND_CONSTANT( BLEND_MODE_ADD ); BIND_CONSTANT( BLEND_MODE_SUB ); + BIND_CONSTANT( BLEND_MODE_MUL ); + BIND_CONSTANT( BLEND_MODE_PREMULT_ALPHA ); } diff --git a/scene/resources/material.h b/scene/resources/material.h index 7bd8b70fa4..1f2afb70b9 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -75,6 +75,7 @@ public: BLEND_MODE_MUL = VS::MATERIAL_BLEND_MODE_MUL, BLEND_MODE_ADD = VS::MATERIAL_BLEND_MODE_ADD, BLEND_MODE_SUB = VS::MATERIAL_BLEND_MODE_SUB, + BLEND_MODE_PREMULT_ALPHA = VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA, }; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index baf6fa9d8d..5402a28d92 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -302,6 +302,16 @@ void ImageTexture::fix_alpha_edges() { } } +void ImageTexture::premultiply_alpha() { + + if (format==Image::FORMAT_RGBA /*&& !(flags&FLAG_CUBEMAP)*/) { + + Image img = get_data(); + img.premultiply_alpha(); + set_data(img); + } +} + bool ImageTexture::has_alpha() const { return ( format==Image::FORMAT_GRAYSCALE_ALPHA || format==Image::FORMAT_INDEXED_ALPHA || format==Image::FORMAT_RGBA ); @@ -386,8 +396,10 @@ void ImageTexture::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_lossy_storage_quality","quality"),&ImageTexture::set_lossy_storage_quality); ObjectTypeDB::bind_method(_MD("get_lossy_storage_quality"),&ImageTexture::get_lossy_storage_quality); ObjectTypeDB::bind_method(_MD("fix_alpha_edges"),&ImageTexture::fix_alpha_edges); + ObjectTypeDB::bind_method(_MD("premultiply_alpha"),&ImageTexture::premultiply_alpha); ObjectTypeDB::bind_method(_MD("set_size_override","size"),&ImageTexture::set_size_override); ObjectTypeDB::set_method_flags(get_type_static(),_SCS("fix_alpha_edges"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); + ObjectTypeDB::set_method_flags(get_type_static(),_SCS("premultiply_alpha"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); ObjectTypeDB::bind_method(_MD("_reload_hook","rid"),&ImageTexture::_reload_hook); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 6259362882..b780d70e1a 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -143,6 +143,7 @@ public: float get_lossy_storage_quality() const; void fix_alpha_edges(); + void premultiply_alpha(); void set_size_override(const Size2& p_size); diff --git a/servers/visual_server.h b/servers/visual_server.h index 1e540a6753..e1793a230e 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -199,7 +199,8 @@ public: MATERIAL_BLEND_MODE_MIX, //default MATERIAL_BLEND_MODE_ADD, MATERIAL_BLEND_MODE_SUB, - MATERIAL_BLEND_MODE_MUL + MATERIAL_BLEND_MODE_MUL, + MATERIAL_BLEND_MODE_PREMULT_ALPHA }; diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 916bd59360..4da712c7b3 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -44,6 +44,7 @@ static const char *flag_names[]={ "No MipMaps", "Repeat", "Filter (Magnifying)", + "Premultiply Alpha", NULL }; @@ -55,6 +56,7 @@ static const char *flag_short_names[]={ "NoMipMap", "Repeat", "Filter", + "PMAlpha", NULL }; @@ -919,6 +921,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc image.fix_alpha_edges(); } + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + if (shrink>1) { @@ -972,6 +979,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc image.fix_alpha_edges(); } + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + int orig_w=image.get_width(); int orig_h=image.get_height(); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index b2950a889c..fcc1bd2d0c 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -91,7 +91,8 @@ public: IMAGE_FLAG_COMPRESS_EXTRA=8, // used for pvrtc2 IMAGE_FLAG_NO_MIPMAPS=16, //normal for 2D games IMAGE_FLAG_REPEAT=32, //usually disabled in 2D - IMAGE_FLAG_FILTER=64 //almost always enabled + IMAGE_FLAG_FILTER=64, //almost always enabled + IMAGE_FLAG_PREMULT_ALPHA=128//almost always enabled }; virtual String get_name() const; diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp index b1e42e3369..77f9d1ed78 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.cpp +++ b/tools/editor/plugins/baked_light_editor_plugin.cpp @@ -134,6 +134,8 @@ public: void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb, Octant *p_octant, const AABB& p_aabb,const Color& p_light); + void _plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light); + void _throw_ray(const Vector3& p_from, const Vector3& p_to,const Color& p_light,float *p_att_curve,float p_att_curve_len,int p_bounces); @@ -165,7 +167,7 @@ public: } BakedLightBaker() { - octree_depth=8; + octree_depth=6; octree=NULL; bvh=NULL; leaf_list=NULL; @@ -408,7 +410,7 @@ void BakedLightBaker::_make_bvh() { void BakedLightBaker::_octree_insert(const AABB& p_aabb,Octant *p_octant,Triangle* p_triangle, int p_depth) { if (p_octant->leaf) { - +#if 0 if (p_aabb.has_point(p_triangle->vertices[0]) && p_aabb.has_point(p_triangle->vertices[1]) &&p_aabb.has_point(p_triangle->vertices[2])) { //face is completely enclosed, add area p_octant->surface_area+=Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).get_area(); @@ -433,12 +435,18 @@ void BakedLightBaker::_octree_insert(const AABB& p_aabb,Octant *p_octant,Triangl p.d=-p_aabb.pos[i]; poly=Geometry::clip_polygon(poly,p); } + + //calculate area + float clipped_area=0; for(int i=2;i<poly.size();i++) { - p_octant->surface_area+=Face3(poly[0],poly[i-1],poly[i]).get_area(); + clipped_area+=Face3(poly[0],poly[i-1],poly[i]).get_area(); } - } + print_line(itos(poly.size())+" Base: "+rtos(Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).get_area())+" clipped: "+rtos(clipped_area)); + p_octant->surface_area+=clipped_area; + } +#endif } else { @@ -500,7 +508,7 @@ void BakedLightBaker::_make_octree() { octree_aabb=base; cell_size=base.size.x; - for(int i=0;i<=octree_depth;i++) + for(int i=0;i<octree_depth;i++) cell_size/=2.0; octree = memnew( Octant ); @@ -526,7 +534,7 @@ void BakedLightBaker::_plot_light(const Vector3& p_plot_pos,const AABB& p_plot_a float d = p_plot_pos.distance_to(center); if (d>r) return; //oh crap! outside radius - float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. + float intensity = 1.0;// - (d/r)*(d/r); //not gauss but.. p_octant->light_accum[0]+=p_light.r*intensity; p_octant->light_accum[1]+=p_light.g*intensity; p_octant->light_accum[2]+=p_light.b*intensity; @@ -558,6 +566,42 @@ void BakedLightBaker::_plot_light(const Vector3& p_plot_pos,const AABB& p_plot_a } } +void BakedLightBaker::_plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light) { + + + if (p_octant->leaf) { + + p_octant->light_accum[0]+=p_light.r; + p_octant->light_accum[1]+=p_light.g; + p_octant->light_accum[2]+=p_light.b; + + } else { + + for(int i=0;i<8;i++) { + + if (!p_octant->children[i]) + continue; + + AABB aabb=p_aabb; + aabb.size*=0.5; + if (i&1) + aabb.pos.x+=aabb.size.x; + if (i&2) + aabb.pos.y+=aabb.size.y; + if (i&4) + aabb.pos.z+=aabb.size.z; + + + if (!aabb.has_point(p_plot_pos)) + continue; + + _plot_light_point(p_plot_pos,p_octant->children[i],aabb,p_light); + + } + + } +} + void BakedLightBaker::_throw_ray(const Vector3& p_begin, const Vector3& p_end,const Color& p_light,float *p_att_curve,float p_att_curve_len,int p_bounces) { @@ -692,6 +736,7 @@ void BakedLightBaker::_throw_ray(const Vector3& p_begin, const Vector3& p_end,co aabb.size=Vector3(2,2,2)*cell_size*plot_size; _plot_light(r_point,aabb,octree,octree_aabb,p_light); +// _plot_light_point(r_point,octree,octree_aabb,p_light); } @@ -772,9 +817,21 @@ void BakedLightBaker::bake(Node* p_node) { +void BakedLightEditor::_end_baking() { + + if (!bake_thread) + return; + + bake_thread_exit=true; + Thread::wait_to_finish(bake_thread); + bake_thread=NULL; + bake_thread_exit=false; +} + void BakedLightEditor::_node_removed(Node *p_node) { if(p_node==node) { + _end_baking(); node=NULL; p_node->remove_child(preview); preview->set_mesh(Ref<Mesh>()); @@ -784,6 +841,79 @@ void BakedLightEditor::_node_removed(Node *p_node) { } +void BakedLightEditor::_bake_thread_func(void *arg) { + + BakedLightEditor *ble = (BakedLightEditor*)arg; + + while(!ble->bake_thread_exit) { + + ble->baker->throw_rays(1000); + } + +} + + + +void BakedLightEditor::_notification(int p_option) { + + + if (p_option==NOTIFICATION_PROCESS) { + + if (bake_thread) { + + update_timeout-=get_process_delta_time(); + if (update_timeout<0) { + + + + float norm = baker->get_normalization(); + float max_lum=0; + { + DVector<Color>::Write cw=colors.write(); + BakedLightBaker::Octant *oct = baker->leaf_list; + int vert_idx=0; + + while(oct) { + + Color color; + + + color.r=oct->light_accum[0]/norm; + color.g=oct->light_accum[1]/norm; + color.b=oct->light_accum[2]/norm; + float lum = color.get_v(); + //if (lum<0.05) + // color.a=0; + if (lum>max_lum) + max_lum=lum; + + for (int i=0;i<36;i++) { + + + cw[vert_idx++]=color; + } + + oct=oct->next_leaf; + + } + } + + + Array a; + a.resize(Mesh::ARRAY_MAX); + a[Mesh::ARRAY_VERTEX]=vertices; + a[Mesh::ARRAY_COLOR]=colors; + while(mesh->get_surface_count()) + mesh->surface_remove(0); + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); + mesh->surface_set_material(0,material); + + update_timeout=1; + } + } + } +} + void BakedLightEditor::_menu_option(int p_option) { @@ -797,13 +927,9 @@ void BakedLightEditor::_menu_option(int p_option) { preview->set_mesh(Ref<Mesh>()); baker->base_inv=node->get_global_transform().affine_inverse(); baker->bake(node); - baker->throw_rays(100000); - float norm = baker->get_normalization(); - float max_lum=0; print_line("CELLS: "+itos(baker->cell_count)); - DVector<Color> colors; - DVector<Vector3> vertices; + print_line("cell size: "+rtos(baker->cell_size)); colors.resize(baker->cell_count*36); vertices.resize(baker->cell_count*36); @@ -817,12 +943,6 @@ void BakedLightEditor::_menu_option(int p_option) { while(oct) { Color color; - color.r=oct->light_accum[0]/norm; - color.g=oct->light_accum[1]/norm; - color.b=oct->light_accum[2]/norm; - float lum = color.get_v(); - if (lum>max_lum) - max_lum=lum; for (int i=0;i<6;i++) { @@ -845,7 +965,7 @@ void BakedLightEditor::_menu_option(int p_option) { } for(int j=0;j<4;j++) { - face_points[j]*=baker->cell_size; + face_points[j]*=baker->cell_size*0.5; face_points[j]+=Vector3(oct->offset[0],oct->offset[1],oct->offset[2]); } @@ -873,25 +993,20 @@ void BakedLightEditor::_menu_option(int p_option) { } - print_line("max lum: "+rtos(max_lum)); Array a; a.resize(Mesh::ARRAY_MAX); a[Mesh::ARRAY_VERTEX]=vertices; a[Mesh::ARRAY_COLOR]=colors; + while(mesh->get_surface_count()) + mesh->surface_remove(0); + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); + mesh->surface_set_material(0,material); - Ref<FixedMaterial> matcol = memnew( FixedMaterial ); - matcol->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); - matcol->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); - matcol->set_flag(FixedMaterial::FLAG_UNSHADED,true); - matcol->set_flag(FixedMaterial::FLAG_DOUBLE_SIDED,true); - matcol->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1)); - Ref<Mesh> m = memnew( Mesh ); - m->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); - m->surface_set_material(0,matcol); - preview->set_mesh(m); - - - + bake_thread_exit=false; + update_timeout=0; + set_process(true); + bake_thread=Thread::create(_bake_thread_func,this); + preview->set_mesh(mesh); } break; @@ -914,6 +1029,7 @@ void BakedLightEditor::edit(BakedLight *p_baked_light) { } node=p_baked_light; + _end_baking(); if (node) node->add_child(preview); @@ -943,6 +1059,19 @@ BakedLightEditor::BakedLightEditor() { node=NULL; baker = memnew( BakedLightBaker ); preview = memnew( MeshInstance ); + bake_thread=NULL; + update_timeout=0; + + material = Ref<FixedMaterial> ( memnew( FixedMaterial ) ); + material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); + material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); + material->set_flag(FixedMaterial::FLAG_UNSHADED,true); + material->set_flag(FixedMaterial::FLAG_DOUBLE_SIDED,true); + material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1)); + + mesh = Ref<Mesh>( memnew( Mesh )); + + } BakedLightEditor::~BakedLightEditor() { diff --git a/tools/editor/plugins/baked_light_editor_plugin.h b/tools/editor/plugins/baked_light_editor_plugin.h index 698d3f825f..9424503a16 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.h +++ b/tools/editor/plugins/baked_light_editor_plugin.h @@ -19,6 +19,15 @@ class BakedLightEditor : public Control { OBJ_TYPE(BakedLightEditor, Control ); + float update_timeout; + DVector<Color> colors; + DVector<Vector3> vertices; + Ref<Mesh> mesh; + Ref<FixedMaterial> material; + + Thread *bake_thread; + bool bake_thread_exit; + MeshInstance *preview; BakedLightBaker *baker; AcceptDialog *err_dialog; @@ -32,12 +41,15 @@ class BakedLightEditor : public Control { MENU_OPTION_CLEAR }; + static void _bake_thread_func(void *arg); + void _end_baking(); void _menu_option(int); friend class BakedLightEditorPlugin; protected: void _node_removed(Node *p_node); static void _bind_methods(); + void _notification(int p_what); public: void edit(BakedLight *p_baked_light); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 5f87b791f7..6540ae9288 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -608,7 +608,14 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { if (b.button_index==BUTTON_WHEEL_DOWN) { + float prev_zoom=zoom; zoom=zoom*0.95; + { + Point2 ofs(b.x,b.y); + ofs = ofs/prev_zoom - ofs/zoom; + h_scroll->set_val( h_scroll->get_val() + ofs.x ); + v_scroll->set_val( v_scroll->get_val() + ofs.y ); + } _update_scroll(0); viewport->update(); return; @@ -616,7 +623,15 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { if (b.button_index==BUTTON_WHEEL_UP) { + float prev_zoom=zoom; zoom=zoom*(1.0/0.95); + { + Point2 ofs(b.x,b.y); + ofs = ofs/prev_zoom - ofs/zoom; + h_scroll->set_val( h_scroll->get_val() + ofs.x ); + v_scroll->set_val( v_scroll->get_val() + ofs.y ); + } + _update_scroll(0); viewport->update(); return; diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 83cf753692..31ccc79d2a 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -688,6 +688,26 @@ void ScriptEditor::_menu_option(int p_option) { current->get_text_edit()->query_code_comple(); } break; + case EDIT_AUTO_INDENT: { + + TextEdit *te = current->get_text_edit(); + String text = te->get_text(); + Ref<Script> scr = current->get_edited_script(); + if (scr.is_null()) + return; + int begin,end; + if (te->is_selection_active()) { + begin=te->get_selection_from_line(); + end=te->get_selection_to_line(); + } else { + begin=0; + end=te->get_line_count()-1; + } + scr->get_language()->auto_indent_code(text,begin,end); + te->set_text(text); + + + } break; case SEARCH_FIND: { find_replace_dialog->set_text_edit(current->get_text_edit()); @@ -1321,6 +1341,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { edit_menu->get_popup()->add_item("Select All",EDIT_SELECT_ALL,KEY_MASK_CMD|KEY_A); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_CMD|KEY_SPACE); + edit_menu->get_popup()->add_item("Auto Indent",EDIT_AUTO_INDENT,KEY_MASK_CMD|KEY_I); edit_menu->get_popup()->connect("item_pressed", this,"_menu_option"); diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 97f1702f8f..69b8739d67 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -122,6 +122,7 @@ class ScriptEditor : public VBoxContainer { EDIT_PASTE, EDIT_SELECT_ALL, EDIT_COMPLETE, + EDIT_AUTO_INDENT, SEARCH_FIND, SEARCH_FIND_NEXT, SEARCH_REPLACE, diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 2087345888..2197902933 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1566,6 +1566,7 @@ CustomPropertyEditor::CustomPropertyEditor() { add_child(checks20[i]); checks20[i]->hide(); checks20[i]->connect("pressed",this,"_action_pressed",make_binds(i)); + checks20[i]->set_tooltip("Bit "+itos(i)+", val "+itos(1<<i)+"."); } text_edit = memnew( TextEdit ); |