diff options
Diffstat (limited to 'platform')
30 files changed, 915 insertions, 418 deletions
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/detect.py b/platform/android/detect.py index cd7f0d8de5..c9b21626c3 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -25,8 +25,9 @@ def get_opts(): #android 2.3 ('ndk_platform', 'compile for platform: (2.2,2.3)',"2.2"), ('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"), - ('android_stl','enable STL support in android port (for modules)','no'), - ('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no') + ('android_stl','enable STL support in android port (for modules)','no'), + ('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no'), + ('x86','compile for x86','no') ] @@ -52,6 +53,9 @@ def create(env): def configure(env): + if env['x86']=='yes': + env['NDK_TARGET']='x86-4.8' + if env['PLATFORM'] == 'win32': import methods env.Tool('gcc') @@ -67,8 +71,12 @@ def configure(env): env.Append(CPPPATH=['#platform/android']) - env['OBJSUFFIX'] = ".android.o" - env['LIBSUFFIX'] = ".android.a" + if env['x86']=='yes': + env['OBJSUFFIX'] = ".android.ox" + env['LIBSUFFIX'] = ".android.ax" + else: + env['OBJSUFFIX'] = ".android.o" + env['LIBSUFFIX'] = ".android.a" env['PROGSUFFIX'] = ".android" env['SHLIBSUFFIX'] = ".so" @@ -89,23 +97,36 @@ def configure(env): env['ENV']['PATH'] = gcc_path+":"+env['ENV']['PATH'] - - env['CC'] = gcc_path+'/arm-linux-androideabi-gcc' - env['CXX'] = gcc_path+'/arm-linux-androideabi-g++' - env['AR'] = gcc_path+"/arm-linux-androideabi-ar" - env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib" - env['AS'] = gcc_path+"/arm-linux-androideabi-as" + if env['x86']=='yes': + env['CC'] = gcc_path+'/i686-linux-android-gcc' + env['CXX'] = gcc_path+'/i686-linux-android-g++' + env['AR'] = gcc_path+"/i686-linux-android-ar" + env['RANLIB'] = gcc_path+"/i686-linux-android-ranlib" + env['AS'] = gcc_path+"/i686-linux-android-as" + else: + env['CC'] = gcc_path+'/arm-linux-androideabi-gcc' + env['CXX'] = gcc_path+'/arm-linux-androideabi-g++' + env['AR'] = gcc_path+"/arm-linux-androideabi-ar" + env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib" + env['AS'] = gcc_path+"/arm-linux-androideabi-as" + + if env['x86']=='yes': + env['ARCH'] = 'arch-x86' + else: + env['ARCH'] = 'arch-arm' import string #include path - gcc_include=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/arch-arm/usr/include" - ld_sysroot=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/arch-arm" + gcc_include=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/"+env['ARCH'] +"/usr/include" + ld_sysroot=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/"+env['ARCH'] #glue_include=env["ANDROID_NDK_ROOT"]+"/sources/android/native_app_glue" - ld_path=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/arch-arm/usr/lib" + ld_path=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/"+env['ARCH']+"/usr/lib" env.Append(CPPPATH=[gcc_include]) # env['CCFLAGS'] = string.split('-DNO_THREADS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ') print("********* armv6", env['armv6']) - if env["armv6"]!="no": + if env['x86']=='yes': + env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED') + elif env["armv6"]!="no": env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED') else: env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED') @@ -146,7 +167,7 @@ def configure(env): env.Append(CCFLAGS=['-D_DEBUG', '-g1', '-Wall', '-O0', '-DDEBUG_ENABLED']) env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']) - if env["armv6"] == "no": + if env["armv6"] == "no" and env['x86'] != 'yes': env['neon_enabled']=True env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT']) # env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT']) @@ -165,7 +186,10 @@ def configure(env): env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/include"]) env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"]) - env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"]) + if env['x86']=='yes': + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/x86"]) + else: + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"]) env.Append(LIBS=['gabi++_static']) env.Append(CCFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST']) @@ -173,4 +197,3 @@ def configure(env): env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } ) - diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 0c8a5785f8..f32e16e7d8 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -179,6 +179,32 @@ bool DirAccessJAndroid::file_exists(String p_file){ return exists; } +bool DirAccessJAndroid::dir_exists(String p_dir) { + + JNIEnv *env = ThreadAndroid::get_env(); + + String sd; + if (current_dir=="") + sd=p_dir; + else + sd=current_dir+"/"+p_dir; + + String path=fix_path(sd).simplify_path(); + if (path.begins_with("/")) + path=path.substr(1,path.length()); + else if (path.begins_with("res://")) + path=path.substr(6,path.length()); + + jstring js = env->NewStringUTF(path.utf8().get_data()); + int res = env->CallIntMethod(io,_dir_open,js); + if (res<=0) + return false; + + env->CallVoidMethod(io,_dir_close,res); + env->DeleteLocalRef(js); + + return true; +} Error DirAccessJAndroid::make_dir(String p_dir){ diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index b6e3fe393f..958ea34891 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -70,6 +70,7 @@ public: virtual bool file_exists(String p_file); + virtual bool dir_exists(String p_dir); virtual Error make_dir(String p_dir); diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 3b6a62898e..d1ee7087e7 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -189,6 +189,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int orientation; String release_keystore; + String release_password; String release_username; struct APKExportData { @@ -241,11 +242,11 @@ public: virtual int get_device_count() const; virtual String get_device_name(int p_device) const; virtual String get_device_info(int p_device) const; - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return !p_debug; } virtual String get_binary_extension() const { return "apk"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -285,6 +286,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& release_keystore=p_value; else if (n=="keystore/release_user") release_username=p_value; + else if (n=="keystore/release_password") + release_password=p_value; else if (n=="apk_expansion/enable") apk_expansion=p_value; else if (n=="apk_expansion/SALT") @@ -343,6 +346,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) r_ret=release_keystore; else if (n=="keystore/release_user") r_ret=release_username; + else if (n=="keystore/release_password") + r_ret=release_password; else if (n=="apk_expansion/enable") r_ret=apk_expansion; else if (n=="apk_expansion/SALT") @@ -968,7 +973,7 @@ Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata,const String& -Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_apk; @@ -1088,34 +1093,51 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_de ep.step("Adding Files..",1); - Error err=OK; Vector<String> cl = cmdline.strip_edges().split(" "); - if (apk_expansion) { - String apkfname="main."+itos(version_code)+"."+package+".obb"; - String fullpath=p_path.get_base_dir().plus_file(apkfname); - FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE); - if (!pf) { - EditorNode::add_io_error("Could not write expansion package file: "+apkfname); - return OK; + if (p_dumb) { + + String host = EditorSettings::get_singleton()->get("file_server/host"); + int port = EditorSettings::get_singleton()->get("file_server/post"); + String passwd = EditorSettings::get_singleton()->get("file_server/password"); + cl.push_back("-rfs"); + cl.push_back(host+":"+itos(port)); + if (passwd!="") { + cl.push_back("-rfs_pass"); + cl.push_back(passwd); } - err = save_pack(pf); - memdelete(pf); - cl.push_back("-main_pack"); - cl.push_back(apkfname); - cl.push_back("-main_pack_md5"); - cl.push_back(FileAccess::get_md5(fullpath)); - cl.push_back("-main_pack_cfg"); - cl.push_back(apk_expansion_salt+","+apk_expansion_pkey); + } else { + //all files - APKExportData ed; - ed.ep=&ep; - ed.apk=apk; + if (apk_expansion) { - err = export_project_files(save_apk_file,&ed,false); + String apkfname="main."+itos(version_code)+"."+package+".obb"; + String fullpath=p_path.get_base_dir().plus_file(apkfname); + FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE); + if (!pf) { + EditorNode::add_io_error("Could not write expansion package file: "+apkfname); + return OK; + } + err = save_pack(pf); + memdelete(pf); + cl.push_back("-main_pack"); + cl.push_back(apkfname); + cl.push_back("-main_pack_md5"); + cl.push_back(FileAccess::get_md5(fullpath)); + cl.push_back("-main_pack_cfg"); + cl.push_back(apk_expansion_salt+","+apk_expansion_pkey); + + } else { + + APKExportData ed; + ed.ep=&ep; + ed.apk=apk; + + err = export_project_files(save_apk_file,&ed,false); + } } if (cl.size()) { @@ -1179,7 +1201,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_de } else { keystore=release_keystore; - password=p_password; + password=release_password; user=release_username; ep.step("Signing Release APK..",103); @@ -1388,7 +1410,7 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) { } -Error EditorExportPlatformAndroid::run(int p_device) { +Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) { ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER); device_lock->lock(); @@ -1407,7 +1429,7 @@ Error EditorExportPlatformAndroid::run(int p_device) { ep.step("Exporting APK",0); String export_to=EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpexport.apk"; - Error err = export_project(export_to,true); + Error err = export_project(export_to,true,p_dumb); if (err) { device_lock->unlock(); return err; 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..9cadeb4231 100644 --- a/platform/android/java/src/com/android/godot/Godot.java +++ b/platform/android/java/src/com/android/godot/Godot.java @@ -62,9 +62,13 @@ import android.widget.FrameLayout; import com.android.godot.input.*; import java.io.InputStream; +import javax.microedition.khronos.opengles.GL10; 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 +108,23 @@ public class Godot extends Activity implements SensorEventListener } + + Godot.singletons[Godot.singleton_count++]=this; } + protected void onMainActivityResult(int requestCode, int resultCode, Intent data) { + + + } + + protected void onMainPause() {} + protected void onMainResume() {} + protected void onMainDestroy() {} + + protected void onGLDrawFrame(GL10 gl) {} + protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // singletons will always miss first onGLSurfaceChanged call + //protected void onGLSurfaceCreated(GL10 gl, EGLConfig config) {} // singletons won't be ready until first GodotLib.step() + public void registerMethods() {} } @@ -125,6 +144,7 @@ public class Godot extends Activity implements SensorEventListener private Sensor mAccelerometer; public FrameLayout layout; + public RelativeLayout adLayout; static public GodotIO io; @@ -133,6 +153,11 @@ 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 +172,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) { @@ -170,6 +200,12 @@ public class Godot extends Activity implements SensorEventListener edittext.setView(mView); io.setEdit(edittext); + + // Ad layout + adLayout = new RelativeLayout(this); + adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); + layout.addView(adLayout); + } private static Godot _self; @@ -179,46 +215,46 @@ public class Godot extends Activity implements SensorEventListener } - private String[] getCommandLine() { - - InputStream is; - try { - is = getAssets().open("/_cl_"); - byte[] len = new byte[4]; - int r = is.read(len); - if (r<4) { - System.out.printf("**ERROR** Wrong cmdline length.\n"); - return new String[0]; - } - int argc=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0])); - String[] cmdline = new String[argc]; - for(int i=0;i<argc;i++) { - r = is.read(len); - if (r<4) { - System.out.printf("**ERROR** Wrong cmdline param lenght.\n"); - return new String[0]; - } - int strlen=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0])); - if (strlen>65535) { - System.out.printf("**ERROR** Wrong command len\n"); - return new String[0]; - } - byte[] arg = new byte[strlen]; - r = is.read(arg); - if (r!=strlen) { - cmdline[i]=new String(arg,"UTF-8"); - } - - } - - return cmdline; - } catch (Exception e) { - - return new String[0]; - } - - - } + private String[] getCommandLine() { + + InputStream is; + try { + is = getAssets().open("/_cl_"); + byte[] len = new byte[4]; + int r = is.read(len); + if (r<4) { + System.out.printf("**ERROR** Wrong cmdline length.\n"); + return new String[0]; + } + int argc=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0])); + String[] cmdline = new String[argc]; + for(int i=0;i<argc;i++) { + r = is.read(len); + if (r<4) { + System.out.printf("**ERROR** Wrong cmdline param lenght.\n"); + return new String[0]; + } + int strlen=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0])); + if (strlen>65535) { + System.out.printf("**ERROR** Wrong command len\n"); + return new String[0]; + } + byte[] arg = new byte[strlen]; + r = is.read(arg); + if (r!=strlen) { + cmdline[i]=new String(arg,"UTF-8"); + } + + } + + return cmdline; + } catch (Exception e) { + + return new String[0]; + } + + + } @Override protected void onCreate(Bundle icicle) { @@ -255,6 +291,9 @@ public class Godot extends Activity implements SensorEventListener @Override protected void onDestroy(){ if(mPaymentsManager != null ) mPaymentsManager.destroy(); + for(int i=0;i<singleton_count;i++) { + singletons[i].onMainDestroy(); + } super.onDestroy(); } @@ -264,6 +303,9 @@ public class Godot extends Activity implements SensorEventListener mSensorManager.unregisterListener(this); GodotLib.focusout(); + for(int i=0;i<singleton_count;i++) { + singletons[i].onMainPause(); + } } @Override protected void onResume() { @@ -271,6 +313,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) { @@ -363,31 +411,31 @@ public class Godot extends Activity implements SensorEventListener return true; } - @Override public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) { - String s = event.getCharacters(); - if (s == null || s.length() == 0) - return super.onKeyMultiple(inKeyCode, repeatCount, event); - - final char[] cc = s.toCharArray(); - int cnt = 0; - for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0); - if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event); - final Activity me = this; - queueEvent(new Runnable() { - // This method will be called on the rendering thread: - public void run() { - for (int i = 0, n = cc.length; i < n; i++) { - int keyCode; - if ((keyCode = cc[i]) != 0) { - // Simulate key down and up... - GodotLib.key(0, keyCode, true); - GodotLib.key(0, keyCode, false); - } - } - } - }); - return true; - } + @Override public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) { + String s = event.getCharacters(); + if (s == null || s.length() == 0) + return super.onKeyMultiple(inKeyCode, repeatCount, event); + + final char[] cc = s.toCharArray(); + int cnt = 0; + for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0); + if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event); + final Activity me = this; + queueEvent(new Runnable() { + // This method will be called on the rendering thread: + public void run() { + for (int i = 0, n = cc.length; i < n; i++) { + int keyCode; + if ((keyCode = cc[i]) != 0) { + // Simulate key down and up... + GodotLib.key(0, keyCode, true); + GodotLib.key(0, keyCode, false); + } + } + } + }); + return true; + } private void queueEvent(Runnable runnable) { // TODO Auto-generated method stub 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/GodotView.java b/platform/android/java/src/com/android/godot/GodotView.java index 1993be8d2c..f02cc00c28 100644 --- a/platform/android/java/src/com/android/godot/GodotView.java +++ b/platform/android/java/src/com/android/godot/GodotView.java @@ -62,13 +62,14 @@ import javax.microedition.khronos.opengles.GL10; * bit depths). Failure to do so would result in an EGL_BAD_MATCH error. */ public class GodotView extends GLSurfaceView { - private static String TAG = "GodotView"; - private static final boolean DEBUG = false; - private static Context ctx; - private static GodotIO io; - private static boolean firsttime=true; - private static boolean use_gl2=false; + private static String TAG = "GodotView"; + private static final boolean DEBUG = false; + private static Context ctx; + + private static GodotIO io; + private static boolean firsttime=true; + private static boolean use_gl2=false; private Godot activity; @@ -113,37 +114,37 @@ public class GodotView extends GLSurfaceView { return super.onKeyDown(keyCode, event); } - private void init(boolean translucent, int depth, int stencil) { + private void init(boolean translucent, int depth, int stencil) { - this.setFocusableInTouchMode(true); - /* By default, GLSurfaceView() creates a RGB_565 opaque surface. - * If we want a translucent one, we should change the surface's - * format here, using PixelFormat.TRANSLUCENT for GL Surfaces - * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. - */ - if (translucent) { - this.getHolder().setFormat(PixelFormat.TRANSLUCENT); - } + this.setFocusableInTouchMode(true); + /* By default, GLSurfaceView() creates a RGB_565 opaque surface. + * If we want a translucent one, we should change the surface's + * format here, using PixelFormat.TRANSLUCENT for GL Surfaces + * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. + */ + if (translucent) { + this.getHolder().setFormat(PixelFormat.TRANSLUCENT); + } - /* Setup the context factory for 2.0 rendering. - * See ContextFactory class definition below - */ - setEGLContextFactory(new ContextFactory()); - - /* We need to choose an EGLConfig that matches the format of - * our surface exactly. This is going to be done in our - * custom config chooser. See ConfigChooser class definition - * below. - */ - setEGLConfigChooser( translucent ? - new ConfigChooser(8, 8, 8, 8, depth, stencil) : - new ConfigChooser(5, 6, 5, 0, depth, stencil) ); - - /* Set the renderer responsible for frame rendering */ - setRenderer(new Renderer()); - } + /* Setup the context factory for 2.0 rendering. + * See ContextFactory class definition below + */ + setEGLContextFactory(new ContextFactory()); + + /* We need to choose an EGLConfig that matches the format of + * our surface exactly. This is going to be done in our + * custom config chooser. See ConfigChooser class definition + * below. + */ + setEGLConfigChooser( translucent ? + new ConfigChooser(8, 8, 8, 8, depth, stencil) : + new ConfigChooser(5, 6, 5, 0, depth, stencil) ); + + /* Set the renderer responsible for frame rendering */ + setRenderer(new Renderer()); + } - private static class ContextFactory implements GLSurfaceView.EGLContextFactory { + private static class ContextFactory implements GLSurfaceView.EGLContextFactory { private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { if (use_gl2) @@ -151,11 +152,11 @@ public class GodotView extends GLSurfaceView { else Log.w(TAG, "creating OpenGL ES 1.1 context :"); - checkEglError("Before eglCreateContext", egl); - int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null); - checkEglError("After eglCreateContext", egl); - return context; + checkEglError("Before eglCreateContext", egl); + int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null); + checkEglError("After eglCreateContext", egl); + return context; } public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { @@ -170,225 +171,231 @@ public class GodotView extends GLSurfaceView { } } - private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { - - public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { - mRedSize = r; - mGreenSize = g; - mBlueSize = b; - mAlphaSize = a; - mDepthSize = depth; - mStencilSize = stencil; - } + private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { - /* This EGL config specification is used to specify 2.0 rendering. - * We use a minimum size of 4 bits for red/green/blue, but will - * perform actual matching in chooseConfig() below. - */ - private static int EGL_OPENGL_ES2_BIT = 4; - private static int[] s_configAttribs2 = - { - EGL10.EGL_RED_SIZE, 4, - EGL10.EGL_GREEN_SIZE, 4, - EGL10.EGL_BLUE_SIZE, 4, - // EGL10.EGL_DEPTH_SIZE, 16, - // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL10.EGL_NONE - }; - private static int[] s_configAttribs = - { - EGL10.EGL_RED_SIZE, 4, - EGL10.EGL_GREEN_SIZE, 4, - EGL10.EGL_BLUE_SIZE, 4, - // EGL10.EGL_DEPTH_SIZE, 16, - // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, - EGL10.EGL_NONE - }; + public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + mRedSize = r; + mGreenSize = g; + mBlueSize = b; + mAlphaSize = a; + mDepthSize = depth; + mStencilSize = stencil; + } - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + /* This EGL config specification is used to specify 2.0 rendering. + * We use a minimum size of 4 bits for red/green/blue, but will + * perform actual matching in chooseConfig() below. + */ + private static int EGL_OPENGL_ES2_BIT = 4; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + // EGL10.EGL_DEPTH_SIZE, 16, + // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + private static int[] s_configAttribs = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + // EGL10.EGL_DEPTH_SIZE, 16, + // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, + EGL10.EGL_NONE + }; + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + + /* Get the number of minimally matching EGL configurations + */ + int[] num_config = new int[1]; + egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config); + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + + /* Allocate then read the array of minimally matching EGL configs + */ + EGLConfig[] configs = new EGLConfig[numConfigs]; + egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config); + + if (DEBUG) { + printConfigs(egl, display, configs); + } + /* Now return the "best" one + */ + return chooseConfig(egl, display, configs); + } - /* Get the number of minimally matching EGL configurations - */ - int[] num_config = new int[1]; - egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config); + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + for(EGLConfig config : configs) { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + + // We need at least mDepthSize and mStencilSize bits + if (d < mDepthSize || s < mStencilSize) + continue; + + // We want an *exact* match for red/green/blue/alpha + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + + if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) + return config; + } + return null; + } - int numConfigs = num_config[0]; + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { - if (numConfigs <= 0) { - throw new IllegalArgumentException("No configs match configSpec"); - } + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } - /* Allocate then read the array of minimally matching EGL configs - */ - EGLConfig[] configs = new EGLConfig[numConfigs]; - egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config); + private void printConfigs(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + int numConfigs = configs.length; + Log.w(TAG, String.format("%d configurations", numConfigs)); + for (int i = 0; i < numConfigs; i++) { + Log.w(TAG, String.format("Configuration %d:\n", i)); + printConfig(egl, display, configs[i]); + } + } - if (DEBUG) { - printConfigs(egl, display, configs); - } - /* Now return the "best" one - */ - return chooseConfig(egl, display, configs); - } + private void printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int[] attributes = { + EGL10.EGL_BUFFER_SIZE, + EGL10.EGL_ALPHA_SIZE, + EGL10.EGL_BLUE_SIZE, + EGL10.EGL_GREEN_SIZE, + EGL10.EGL_RED_SIZE, + EGL10.EGL_DEPTH_SIZE, + EGL10.EGL_STENCIL_SIZE, + EGL10.EGL_CONFIG_CAVEAT, + EGL10.EGL_CONFIG_ID, + EGL10.EGL_LEVEL, + EGL10.EGL_MAX_PBUFFER_HEIGHT, + EGL10.EGL_MAX_PBUFFER_PIXELS, + EGL10.EGL_MAX_PBUFFER_WIDTH, + EGL10.EGL_NATIVE_RENDERABLE, + EGL10.EGL_NATIVE_VISUAL_ID, + EGL10.EGL_NATIVE_VISUAL_TYPE, + 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, + EGL10.EGL_SAMPLES, + EGL10.EGL_SAMPLE_BUFFERS, + EGL10.EGL_SURFACE_TYPE, + EGL10.EGL_TRANSPARENT_TYPE, + EGL10.EGL_TRANSPARENT_RED_VALUE, + EGL10.EGL_TRANSPARENT_GREEN_VALUE, + EGL10.EGL_TRANSPARENT_BLUE_VALUE, + 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, + 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, + 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, + 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, + EGL10.EGL_LUMINANCE_SIZE, + EGL10.EGL_ALPHA_MASK_SIZE, + EGL10.EGL_COLOR_BUFFER_TYPE, + EGL10.EGL_RENDERABLE_TYPE, + 0x3042 // EGL10.EGL_CONFORMANT + }; + String[] names = { + "EGL_BUFFER_SIZE", + "EGL_ALPHA_SIZE", + "EGL_BLUE_SIZE", + "EGL_GREEN_SIZE", + "EGL_RED_SIZE", + "EGL_DEPTH_SIZE", + "EGL_STENCIL_SIZE", + "EGL_CONFIG_CAVEAT", + "EGL_CONFIG_ID", + "EGL_LEVEL", + "EGL_MAX_PBUFFER_HEIGHT", + "EGL_MAX_PBUFFER_PIXELS", + "EGL_MAX_PBUFFER_WIDTH", + "EGL_NATIVE_RENDERABLE", + "EGL_NATIVE_VISUAL_ID", + "EGL_NATIVE_VISUAL_TYPE", + "EGL_PRESERVED_RESOURCES", + "EGL_SAMPLES", + "EGL_SAMPLE_BUFFERS", + "EGL_SURFACE_TYPE", + "EGL_TRANSPARENT_TYPE", + "EGL_TRANSPARENT_RED_VALUE", + "EGL_TRANSPARENT_GREEN_VALUE", + "EGL_TRANSPARENT_BLUE_VALUE", + "EGL_BIND_TO_TEXTURE_RGB", + "EGL_BIND_TO_TEXTURE_RGBA", + "EGL_MIN_SWAP_INTERVAL", + "EGL_MAX_SWAP_INTERVAL", + "EGL_LUMINANCE_SIZE", + "EGL_ALPHA_MASK_SIZE", + "EGL_COLOR_BUFFER_TYPE", + "EGL_RENDERABLE_TYPE", + "EGL_CONFORMANT" + }; + int[] value = new int[1]; + for (int i = 0; i < attributes.length; i++) { + int attribute = attributes[i]; + String name = names[i]; + if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { + Log.w(TAG, String.format(" %s: %d\n", name, value[0])); + } else { + // Log.w(TAG, String.format(" %s: failed\n", name)); + while (egl.eglGetError() != EGL10.EGL_SUCCESS); + } + } + } - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, - EGLConfig[] configs) { - for(EGLConfig config : configs) { - int d = findConfigAttrib(egl, display, config, - EGL10.EGL_DEPTH_SIZE, 0); - int s = findConfigAttrib(egl, display, config, - EGL10.EGL_STENCIL_SIZE, 0); - - // We need at least mDepthSize and mStencilSize bits - if (d < mDepthSize || s < mStencilSize) - continue; - - // We want an *exact* match for red/green/blue/alpha - int r = findConfigAttrib(egl, display, config, - EGL10.EGL_RED_SIZE, 0); - int g = findConfigAttrib(egl, display, config, - EGL10.EGL_GREEN_SIZE, 0); - int b = findConfigAttrib(egl, display, config, - EGL10.EGL_BLUE_SIZE, 0); - int a = findConfigAttrib(egl, display, config, - EGL10.EGL_ALPHA_SIZE, 0); - - if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) - return config; - } - return null; + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + private int[] mValue = new int[1]; } - private int findConfigAttrib(EGL10 egl, EGLDisplay display, - EGLConfig config, int attribute, int defaultValue) { - - if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { - return mValue[0]; - } - return defaultValue; - } + private static class Renderer implements GLSurfaceView.Renderer { - private void printConfigs(EGL10 egl, EGLDisplay display, - EGLConfig[] configs) { - int numConfigs = configs.length; - Log.w(TAG, String.format("%d configurations", numConfigs)); - for (int i = 0; i < numConfigs; i++) { - Log.w(TAG, String.format("Configuration %d:\n", i)); - printConfig(egl, display, configs[i]); - } - } - private void printConfig(EGL10 egl, EGLDisplay display, - EGLConfig config) { - int[] attributes = { - EGL10.EGL_BUFFER_SIZE, - EGL10.EGL_ALPHA_SIZE, - EGL10.EGL_BLUE_SIZE, - EGL10.EGL_GREEN_SIZE, - EGL10.EGL_RED_SIZE, - EGL10.EGL_DEPTH_SIZE, - EGL10.EGL_STENCIL_SIZE, - EGL10.EGL_CONFIG_CAVEAT, - EGL10.EGL_CONFIG_ID, - EGL10.EGL_LEVEL, - EGL10.EGL_MAX_PBUFFER_HEIGHT, - EGL10.EGL_MAX_PBUFFER_PIXELS, - EGL10.EGL_MAX_PBUFFER_WIDTH, - EGL10.EGL_NATIVE_RENDERABLE, - EGL10.EGL_NATIVE_VISUAL_ID, - EGL10.EGL_NATIVE_VISUAL_TYPE, - 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, - EGL10.EGL_SAMPLES, - EGL10.EGL_SAMPLE_BUFFERS, - EGL10.EGL_SURFACE_TYPE, - EGL10.EGL_TRANSPARENT_TYPE, - EGL10.EGL_TRANSPARENT_RED_VALUE, - EGL10.EGL_TRANSPARENT_GREEN_VALUE, - EGL10.EGL_TRANSPARENT_BLUE_VALUE, - 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, - 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, - 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, - 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, - EGL10.EGL_LUMINANCE_SIZE, - EGL10.EGL_ALPHA_MASK_SIZE, - EGL10.EGL_COLOR_BUFFER_TYPE, - EGL10.EGL_RENDERABLE_TYPE, - 0x3042 // EGL10.EGL_CONFORMANT - }; - String[] names = { - "EGL_BUFFER_SIZE", - "EGL_ALPHA_SIZE", - "EGL_BLUE_SIZE", - "EGL_GREEN_SIZE", - "EGL_RED_SIZE", - "EGL_DEPTH_SIZE", - "EGL_STENCIL_SIZE", - "EGL_CONFIG_CAVEAT", - "EGL_CONFIG_ID", - "EGL_LEVEL", - "EGL_MAX_PBUFFER_HEIGHT", - "EGL_MAX_PBUFFER_PIXELS", - "EGL_MAX_PBUFFER_WIDTH", - "EGL_NATIVE_RENDERABLE", - "EGL_NATIVE_VISUAL_ID", - "EGL_NATIVE_VISUAL_TYPE", - "EGL_PRESERVED_RESOURCES", - "EGL_SAMPLES", - "EGL_SAMPLE_BUFFERS", - "EGL_SURFACE_TYPE", - "EGL_TRANSPARENT_TYPE", - "EGL_TRANSPARENT_RED_VALUE", - "EGL_TRANSPARENT_GREEN_VALUE", - "EGL_TRANSPARENT_BLUE_VALUE", - "EGL_BIND_TO_TEXTURE_RGB", - "EGL_BIND_TO_TEXTURE_RGBA", - "EGL_MIN_SWAP_INTERVAL", - "EGL_MAX_SWAP_INTERVAL", - "EGL_LUMINANCE_SIZE", - "EGL_ALPHA_MASK_SIZE", - "EGL_COLOR_BUFFER_TYPE", - "EGL_RENDERABLE_TYPE", - "EGL_CONFORMANT" - }; - int[] value = new int[1]; - for (int i = 0; i < attributes.length; i++) { - int attribute = attributes[i]; - String name = names[i]; - if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { - Log.w(TAG, String.format(" %s: %d\n", name, value[0])); - } else { - // Log.w(TAG, String.format(" %s: failed\n", name)); - while (egl.eglGetError() != EGL10.EGL_SUCCESS); + public void onDrawFrame(GL10 gl) { + GodotLib.step(); + for(int i=0;i<Godot.singleton_count;i++) { + Godot.singletons[i].onGLDrawFrame(gl); + } } - } - } - - // Subclasses can adjust these values: - protected int mRedSize; - protected int mGreenSize; - protected int mBlueSize; - protected int mAlphaSize; - protected int mDepthSize; - protected int mStencilSize; - private int[] mValue = new int[1]; - } - - private static class Renderer implements GLSurfaceView.Renderer { + public void onSurfaceChanged(GL10 gl, int width, int height) { - public void onDrawFrame(GL10 gl) { - GodotLib.step(); - } - - public void onSurfaceChanged(GL10 gl, int width, int height) { - - GodotLib.resize(width, height,!firsttime); - firsttime=false; - } + GodotLib.resize(width, height,!firsttime); + firsttime=false; + for(int i=0;i<Godot.singleton_count;i++) { + Godot.singletons[i].onGLSurfaceChanged(gl, width, height); + } + } - public void onSurfaceCreated(GL10 gl, EGLConfig config) { - GodotLib.newcontext(); + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + GodotLib.newcontext(); + } } - } } 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/java_bind.cpp b/platform/android/java_bind.cpp new file mode 100644 index 0000000000..33ecfcffb6 --- /dev/null +++ b/platform/android/java_bind.cpp @@ -0,0 +1,5 @@ +#include "java_bind.h" + +JavaBind::JavaBind() +{ +} diff --git a/platform/android/java_bind.h b/platform/android/java_bind.h new file mode 100644 index 0000000000..ca6b4650d3 --- /dev/null +++ b/platform/android/java_bind.h @@ -0,0 +1,10 @@ +#ifndef JAVA_BIND_H +#define JAVA_BIND_H + +class JavaBind +{ +public: + JavaBind(); +}; + +#endif // JAVA_BIND_H diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 5bf2fc5a73..b11994eef0 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -153,6 +153,14 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar v.l=arr; } break; + case Variant::RAW_ARRAY: { + DVector<uint8_t> array = *p_arg; + jbyteArray arr = env->NewByteArray(array.size()); + DVector<uint8_t>::Read r = array.read(); + env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast<const signed char*>(r.ptr())); + v.l=arr; + + } break; case Variant::REAL_ARRAY: { DVector<float> array = *p_arg; @@ -244,6 +252,19 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { return sarr; }; + if (name == "[B") { + + jbyteArray arr = (jbyteArray)obj; + int fCount = env->GetArrayLength(arr); + DVector<uint8_t> sarr; + sarr.resize(fCount); + + DVector<uint8_t>::Write w = sarr.write(); + env->GetByteArrayRegion(arr,0,fCount,reinterpret_cast<signed char*>(w.ptr())); + w = DVector<uint8_t>::Write(); + return sarr; + }; + if (name == "java.lang.Float" || name == "java.lang.Double") { jclass nclass = env->FindClass("java/lang/Number"); @@ -354,6 +375,7 @@ public: virtual Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) { //print_line("attempt to call "+String(p_method)); + ERR_FAIL_COND_V(!instance,Variant()); r_error.error=Variant::CallError::CALL_OK; @@ -519,7 +541,10 @@ public: } - JNISingleton() {} + JNISingleton() { + instance=NULL; + + } }; @@ -1342,6 +1367,7 @@ static Variant::Type get_jni_type(const String& p_type) { {"double", Variant::REAL}, {"java.lang.String",Variant::STRING}, {"[I",Variant::INT_ARRAY}, + {"[B",Variant::RAW_ARRAY}, {"[F",Variant::REAL_ARRAY}, {"[java.lang.String",Variant::STRING_ARRAY}, {"com.android.godot.Dictionary", Variant::DICTIONARY}, @@ -1377,6 +1403,7 @@ static const char* get_jni_sig(const String& p_type) { {"java.lang.String","Ljava/lang/String;"}, {"com.android.godot.Dictionary", "Lcom/android/godot/Dictionary;"}, {"[I","[I"}, + {"[B","[B"}, {"[F","[F"}, {"[java.lang.String","[Ljava/lang/String;"}, {NULL,"V"} 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/bb10/export/export.cpp b/platform/bb10/export/export.cpp index 0a19e71f08..5edcf39396 100644 --- a/platform/bb10/export/export.cpp +++ b/platform/bb10/export/export.cpp @@ -67,11 +67,11 @@ public: virtual int get_device_count() const; virtual String get_device_name(int p_device) const; virtual String get_device_info(int p_device) const; - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return !p_debug; } virtual String get_binary_extension() const { return "bar"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -270,7 +270,7 @@ void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) { -Error EditorExportPlatformBB10::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, bool p_dumb) { EditorProgress ep("export","Exporting for BlackBerry 10",104); @@ -632,7 +632,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) { } -Error EditorExportPlatformBB10::run(int p_device) { +Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) { ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER); diff --git a/platform/flash/dir_access_flash.cpp b/platform/flash/dir_access_flash.cpp index a0f1679243..4b8992f9d6 100644 --- a/platform/flash/dir_access_flash.cpp +++ b/platform/flash/dir_access_flash.cpp @@ -156,6 +156,26 @@ bool DirAccessFlash::file_exists(String p_file) { return success; }; +bool DirAccessFlash::dir_exists(String p_dir) { + + GLOBAL_LOCK_FUNCTION + + + if (p_dir.is_rel_path()) + p_dir=current_dir+"/"+p_dir; + else + p_dir=fix_path(p_dir); + + struct stat flags; + bool success = (stat(p_dir.utf8().get_data(),&flags)==0); + + if (success && S_ISDIR(flags.st_mode)) { + return true; + } + + return false; +}; + size_t DirAccessFlash::get_space_left() { return 0; diff --git a/platform/flash/dir_access_flash.h b/platform/flash/dir_access_flash.h index 09e0b844ce..1378a6e56f 100644 --- a/platform/flash/dir_access_flash.h +++ b/platform/flash/dir_access_flash.h @@ -45,6 +45,7 @@ public: Error make_dir(String p_dir); bool file_exists(String p_file); + bool dir_exists(String p_dir); size_t get_space_left(); 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/javascript/export/export.cpp b/platform/javascript/export/export.cpp index cd2e24216a..928d128799 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -77,11 +77,11 @@ public: virtual int get_device_count() const { return show_run?1:0; }; virtual String get_device_name(int p_device) const { return "Run in Browser"; } virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; } - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return false; } virtual String get_binary_extension() const { return "html"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -194,7 +194,7 @@ struct JSExportData { -Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_template; @@ -299,7 +299,7 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p } -Error EditorExportPlatformJavaScript::run(int p_device) { +Error EditorExportPlatformJavaScript::run(int p_device, bool p_dumb) { String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html"; Error err = export_project(path,true,""); diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index f55e901794..087a648700 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -57,11 +57,11 @@ public: virtual int get_device_count() const { return 0; }; virtual String get_device_name(int p_device) const { return String(); } virtual String get_device_info(int p_device) const { return String(); } - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return false; } virtual String get_binary_extension() const { return "zip"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -245,7 +245,7 @@ void EditorExportPlatformOSX::_fix_plist(Vector<uint8_t>& plist,const String& p_ } } -Error EditorExportPlatformOSX::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_pkg; @@ -437,7 +437,7 @@ Error EditorExportPlatformOSX::export_project(const String& p_path,bool p_debug, } -Error EditorExportPlatformOSX::run(int p_device) { +Error EditorExportPlatformOSX::run(int p_device, bool p_dumb) { return OK; } diff --git a/platform/windows/detect.py b/platform/windows/detect.py index d1c5e96d32..0e21540e13 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")):
@@ -143,10 +143,12 @@ def configure(env): mingw_prefix=""
if (env["force_32_bits"]!="no"):
- env['OBJSUFFIX'] = ".32"+env['OBJSUFFIX']
- env['LIBSUFFIX'] = ".32"+env['LIBSUFFIX']
- env.Append(CCFLAGS=['-m32'])
- env.Append(LINKFLAGS=['-m32'])
+ env['OBJSUFFIX'] = ".32"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = ".32"+env['LIBSUFFIX']
+ env.Append(CCFLAGS=['-m32'])
+ env.Append(LINKFLAGS=['-m32'])
+ env.Append(LINKFLAGS=['-static-libgcc'])
+ env.Append(LINKFLAGS=['-static-libstdc++'])
@@ -196,7 +198,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/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index 7b35bcc7ad..e77ca6feaa 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -86,6 +86,9 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_ho closesocket(sockfd);
ERR_FAIL_V(FAILED);
};
+ }
+ else {
+ return ERR_ALREADY_IN_USE;
};
if (listen_sockfd != INVALID_SOCKET) {
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 6470f09850..e7d9a4d691 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -494,7 +494,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 @@ -605,17 +605,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) { @@ -629,17 +621,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 } @@ -657,7 +653,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. @@ -1031,7 +1027,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; |