summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/bind/core_bind.cpp7
-rw-r--r--core/bind/core_bind.h10
-rw-r--r--core/image.cpp25
-rw-r--r--core/image.h1
-rw-r--r--core/io/file_access_encrypted.cpp5
-rw-r--r--core/io/ip.cpp13
-rw-r--r--core/io/ip.h3
-rw-r--r--core/os/file_access.cpp2
-rw-r--r--core/os/input.cpp2
-rw-r--r--core/os/main_loop.cpp2
-rw-r--r--core/script_language.h1
-rw-r--r--demos/2d/platformer/stage.xml12
-rw-r--r--[-rwxr-xr-x]doc/make_doc.sh0
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp5
-rw-r--r--drivers/gles2/shaders/canvas.glsl3
-rw-r--r--drivers/unix/ip_unix.cpp99
-rw-r--r--drivers/unix/ip_unix.h2
-rw-r--r--modules/gdscript/gd_compiler.cpp10
-rw-r--r--modules/gdscript/gd_editor.cpp64
-rw-r--r--modules/gdscript/gd_parser.cpp23
-rw-r--r--modules/gdscript/gd_parser.h2
-rw-r--r--modules/gdscript/gd_script.cpp3
-rw-r--r--modules/gdscript/gd_script.h8
-rw-r--r--platform/android/SCsub1
-rw-r--r--platform/android/ifaddrs_android.cpp221
-rw-r--r--platform/android/ifaddrs_android.h46
-rw-r--r--platform/android/java/src/com/android/godot/Godot.java33
-rw-r--r--platform/android/java/src/com/android/godot/GodotPaymentV3.java37
-rw-r--r--platform/android/java/src/com/android/godot/payments/ConsumeTask.java3
-rw-r--r--platform/android/java/src/com/android/godot/payments/HandlePurchaseTask.java10
-rw-r--r--platform/android/java/src/com/android/godot/payments/PaymentsCache.java3
-rw-r--r--platform/android/java/src/com/android/godot/payments/PaymentsManager.java12
-rw-r--r--platform/android/java/src/com/android/godot/payments/PurchaseTask.java6
-rwxr-xr-xplatform/android/sign.sh2
-rw-r--r--platform/iphone/detect.py6
-rwxr-xr-xplatform/iphone/gl_view.mm13
-rw-r--r--platform/windows/detect.py4
-rw-r--r--platform/x11/os_x11.cpp36
-rw-r--r--platform/x11/os_x11.h2
-rw-r--r--scene/2d/canvas_item.cpp5
-rw-r--r--scene/2d/canvas_item.h3
-rw-r--r--scene/resources/material.cpp4
-rw-r--r--scene/resources/material.h1
-rw-r--r--scene/resources/texture.cpp12
-rw-r--r--scene/resources/texture.h1
-rw-r--r--servers/visual_server.h3
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.cpp12
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.h3
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.cpp193
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.h12
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp15
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp21
-rw-r--r--tools/editor/plugins/script_editor_plugin.h1
-rw-r--r--tools/editor/property_editor.cpp1
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 );