summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/SCsub31
-rw-r--r--platform/android/SCsub3
-rw-r--r--platform/android/build.gradle.template2
-rw-r--r--platform/android/detect.py2
-rw-r--r--platform/android/export/export.cpp231
-rw-r--r--platform/android/globals/global_defaults.cpp8
-rw-r--r--platform/android/godot_android.cpp11
-rw-r--r--platform/android/java/src/org/godotengine/godot/Dictionary.java7
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java812
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java18
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java55
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotIO.java273
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotLib.java56
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java25
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java261
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/GodotEditText.java61
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java3
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java204
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java144
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java352
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java38
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java20
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java30
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java45
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java87
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java38
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java46
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java36
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/Crypt.java46
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java31
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java207
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/RequestParams.java34
-rw-r--r--platform/android/java_class_wrapper.cpp2
-rw-r--r--platform/android/java_glue.cpp4
-rw-r--r--platform/android/os_android.cpp43
-rw-r--r--platform/android/os_android.h9
-rw-r--r--platform/android/power_android.cpp6
-rw-r--r--platform/haiku/SCsub2
-rw-r--r--platform/haiku/detect.py2
-rw-r--r--platform/haiku/haiku_application.cpp4
-rw-r--r--platform/haiku/haiku_direct_window.cpp4
-rw-r--r--platform/haiku/haiku_gl_view.cpp4
-rw-r--r--platform/haiku/os_haiku.cpp40
-rw-r--r--platform/haiku/os_haiku.h4
-rw-r--r--platform/haiku/power_haiku.cpp6
-rw-r--r--platform/iphone/SCsub12
-rw-r--r--platform/iphone/app_delegate.mm136
-rw-r--r--platform/iphone/detect.py21
-rw-r--r--platform/iphone/export/export.cpp468
-rw-r--r--platform/iphone/game_center.mm14
-rw-r--r--platform/iphone/globals/global_defaults.cpp7
-rw-r--r--platform/iphone/in_app_store.mm11
-rw-r--r--platform/iphone/os_iphone.cpp98
-rw-r--r--platform/iphone/os_iphone.h10
-rw-r--r--platform/iphone/platform_config.h2
-rw-r--r--platform/iphone/power_iphone.cpp6
-rw-r--r--platform/javascript/SCsub28
-rw-r--r--platform/javascript/api/api.cpp (renamed from platform/windows/packet_peer_udp_winsock.h)71
-rw-r--r--platform/javascript/api/api.h (renamed from platform/windows/stream_peer_winsock.h)66
-rw-r--r--platform/javascript/api/javascript_eval.h (renamed from platform/javascript/javascript_eval.h)3
-rw-r--r--platform/javascript/detect.py18
-rw-r--r--platform/javascript/dom_keys.h12
-rw-r--r--platform/javascript/engine.js219
-rw-r--r--platform/javascript/export/export.cpp140
-rw-r--r--platform/javascript/http_client_javascript.cpp39
-rw-r--r--platform/javascript/javascript_eval.cpp71
-rw-r--r--platform/javascript/javascript_main.cpp1
-rw-r--r--platform/javascript/os_javascript.cpp53
-rw-r--r--platform/javascript/os_javascript.h14
-rw-r--r--platform/javascript/power_javascript.cpp6
-rw-r--r--platform/javascript/pre.js (renamed from platform/javascript/pre_wasm.js)1
-rw-r--r--platform/javascript/pre_asmjs.js3
-rw-r--r--platform/osx/SCsub12
-rw-r--r--platform/osx/detect.py15
-rw-r--r--platform/osx/export/export.cpp12
-rw-r--r--platform/osx/os_osx.h11
-rw-r--r--platform/osx/os_osx.mm129
-rw-r--r--platform/osx/power_osx.cpp6
-rw-r--r--platform/register_platform_apis.h (renamed from platform/windows/tcp_server_winsock.h)30
-rw-r--r--platform/server/SCsub2
-rw-r--r--platform/server/os_server.cpp2
-rw-r--r--platform/server/os_server.h1
-rw-r--r--platform/uwp/SCsub5
-rw-r--r--platform/uwp/app.cpp18
-rw-r--r--platform/uwp/app.h1
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--platform/uwp/export/export.cpp32
-rw-r--r--platform/uwp/gl_context_egl.cpp14
-rw-r--r--platform/uwp/joypad_uwp.cpp6
-rw-r--r--platform/uwp/logo.pngbin1882 -> 1519 bytes
-rw-r--r--platform/uwp/os_uwp.cpp29
-rw-r--r--platform/uwp/os_uwp.h3
-rw-r--r--platform/uwp/power_uwp.cpp6
-rw-r--r--platform/windows/SCsub18
-rw-r--r--platform/windows/context_gl_win.cpp19
-rw-r--r--platform/windows/context_gl_win.h13
-rw-r--r--platform/windows/crash_handler_win.cpp8
-rw-r--r--platform/windows/detect.py20
-rw-r--r--platform/windows/export/export.cpp126
-rw-r--r--platform/windows/godot_res.rc8
-rw-r--r--platform/windows/os_windows.cpp189
-rw-r--r--platform/windows/os_windows.h20
-rw-r--r--platform/windows/packet_peer_udp_winsock.cpp293
-rw-r--r--platform/windows/power_windows.cpp6
-rw-r--r--platform/windows/stream_peer_winsock.cpp371
-rw-r--r--platform/windows/tcp_server_winsock.cpp183
-rw-r--r--platform/x11/SCsub9
-rw-r--r--platform/x11/context_gl_x11.cpp4
-rw-r--r--platform/x11/detect.py17
-rw-r--r--platform/x11/export/export.cpp3
-rw-r--r--platform/x11/os_x11.cpp297
-rw-r--r--platform/x11/os_x11.h20
-rw-r--r--platform/x11/power_x11.cpp6
113 files changed, 3315 insertions, 3528 deletions
diff --git a/platform/SCsub b/platform/SCsub
new file mode 100644
index 0000000000..e624f8e90f
--- /dev/null
+++ b/platform/SCsub
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+from compat import open_utf8
+
+Import('env')
+platform_sources = []
+
+# Register platform-exclusive APIs
+reg_apis_inc = '#include "register_platform_apis.h"\n'
+reg_apis = 'void register_platform_apis() {\n'
+unreg_apis = 'void unregister_platform_apis() {\n'
+for platform in env.platform_apis:
+ platform_dir = env.Dir(platform)
+ platform_sources.append(platform_dir.File('api/api.cpp'))
+ reg_apis += '\tregister_' + platform + '_api();\n'
+ unreg_apis += '\tunregister_' + platform + '_api();\n'
+ reg_apis_inc += '#include "' + platform + '/api/api.h"\n'
+reg_apis_inc += '\n'
+reg_apis += '}\n\n'
+unreg_apis += '}\n'
+f = open_utf8('register_platform_apis.gen.cpp', 'w')
+f.write(reg_apis_inc)
+f.write(reg_apis)
+f.write(unreg_apis)
+f.close()
+platform_sources.append('register_platform_apis.gen.cpp')
+
+lib = env.add_library('platform', platform_sources)
+env.Prepend(LIBS=lib)
+
+Export('env')
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 7fa0262359..0cd91276ef 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -144,8 +144,7 @@ manifest = manifest.replace("$$ADD_APPATTRIBUTE_CHUNKS$$", env.android_appattrib
pp_baseout.write(manifest)
-env_android.SharedLibrary("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"])
-
+lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"])
lib_arch_dir = ''
if env['android_arch'] == 'armv6':
diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template
index 7cb6cf860a..4a44d1c5f9 100644
--- a/platform/android/build.gradle.template
+++ b/platform/android/build.gradle.template
@@ -31,7 +31,7 @@ android {
disable 'MissingTranslation'
}
- compileSdkVersion 23
+ compileSdkVersion 26
buildToolsVersion "26.0.1"
useLibrary 'org.apache.http.legacy'
diff --git a/platform/android/detect.py b/platform/android/detect.py
index a3ada5cf51..bc67f6e6dc 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -205,7 +205,7 @@ def configure(env):
env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"])
env.Append(CPPFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split())
- env.Append(CPPFLAGS='-DNO_STATVFS -DGLES2_ENABLED'.split())
+ env.Append(CPPFLAGS='-DNO_STATVFS -DGLES_ENABLED'.split())
env['neon_enabled'] = False
if env['android_arch'] == 'x86':
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 79be1501a7..6ca687d057 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -192,6 +192,19 @@ static const char *android_perms[] = {
NULL
};
+struct LauncherIcon {
+ char *option_id;
+ char *export_path;
+};
+
+static const LauncherIcon launcher_icons[] = {
+ { "launcher_icons/xxxhdpi_192x192", "res/drawable-xxxhdpi-v4/icon.png" },
+ { "launcher_icons/xxhdpi_144x144", "res/drawable-xxhdpi-v4/icon.png" },
+ { "launcher_icons/xhdpi_96x96", "res/drawable-xhdpi-v4/icon.png" },
+ { "launcher_icons/hdpi_72x72", "res/drawable-hdpi-v4/icon.png" },
+ { "launcher_icons/mdpi_48x48", "res/drawable-mdpi-v4/icon.png" }
+};
+
class EditorExportAndroid : public EditorExportPlatform {
GDCLASS(EditorExportAndroid, EditorExportPlatform)
@@ -370,7 +383,7 @@ class EditorExportAndroid : public EditorExportPlatform {
}
if (aname == "") {
- aname = _MKSTR(VERSION_NAME);
+ aname = VERSION_NAME;
}
return aname;
@@ -467,52 +480,72 @@ class EditorExportAndroid : public EditorExportPlatform {
return zipfi;
}
- static Set<String> get_abis() {
- Set<String> abis;
- abis.insert("armeabi");
- abis.insert("armeabi-v7a");
- abis.insert("arm64-v8a");
- abis.insert("x86");
- abis.insert("x86_64");
- abis.insert("mips");
- abis.insert("mips64");
+ static Vector<String> get_abis() {
+ // mips and armv6 are dead (especially for games), so not including them
+ Vector<String> abis;
+ abis.push_back("armeabi-v7a");
+ abis.push_back("arm64-v8a");
+ abis.push_back("x86");
+ abis.push_back("x86_64");
return abis;
}
- static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
- APKExportData *ed = (APKExportData *)p_userdata;
- String dst_path = p_path;
- static Set<String> android_abis = get_abis();
-
- if (dst_path.ends_with(".so")) {
- String abi = dst_path.get_base_dir().get_file().strip_edges(); // parent dir name
- if (android_abis.has(abi)) {
- dst_path = "lib/" + abi + "/" + dst_path.get_file();
- } else {
- String err = "Dynamic libraries must be located in the folder named after Android ABI they were compiled for. " +
- p_path + " does not follow this convention.";
- ERR_PRINT(err.utf8().get_data());
- return ERR_FILE_BAD_PATH;
- }
- } else {
- dst_path = dst_path.replace_first("res://", "assets/");
- }
-
+ static Error store_in_apk(APKExportData *ed, const String &p_path, const Vector<uint8_t> &p_data, int compression_method = Z_DEFLATED) {
zip_fileinfo zipfi = get_zip_fileinfo();
-
zipOpenNewFileInZip(ed->apk,
- dst_path.utf8().get_data(),
+ p_path.utf8().get_data(),
&zipfi,
NULL,
0,
NULL,
0,
NULL,
- _should_compress_asset(p_path, p_data) ? Z_DEFLATED : 0,
+ compression_method,
Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(ed->apk, p_data.ptr(), p_data.size());
zipCloseFileInZip(ed->apk);
+
+ return OK;
+ }
+
+ static Error save_apk_so(void *p_userdata, const SharedObject &p_so) {
+ if (!p_so.path.get_file().begins_with("lib")) {
+ String err = "Android .so file names must start with \"lib\", but got: " + p_so.path;
+ ERR_PRINT(err.utf8().get_data());
+ return FAILED;
+ }
+ APKExportData *ed = (APKExportData *)p_userdata;
+ Vector<String> abis = get_abis();
+ bool exported = false;
+ for (int i = 0; i < p_so.tags.size(); ++i) {
+ // shared objects can be fat (compatible with multiple ABIs)
+ int start_pos = 0;
+ int abi_index = abis.find(p_so.tags[i]);
+ if (abi_index != -1) {
+ exported = true;
+ start_pos = abi_index + 1;
+ String abi = abis[abi_index];
+ String dst_path = "lib/" + abi + "/" + p_so.path.get_file();
+ Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
+ Error store_err = store_in_apk(ed, dst_path, array);
+ ERR_FAIL_COND_V(store_err, store_err);
+ }
+ }
+ if (!exported) {
+ String abis_string = String(" ").join(abis);
+ String err = "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + abis_string;
+ ERR_PRINT(err.utf8().get_data());
+ return FAILED;
+ }
+ return OK;
+ }
+
+ static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
+ APKExportData *ed = (APKExportData *)p_userdata;
+ String dst_path = p_path.replace_first("res://", "assets/");
+
+ store_in_apk(ed, dst_path, p_data, _should_compress_asset(p_path, p_data) ? Z_DEFLATED : 0);
ed->ep->step("File: " + p_path, 3 + p_file * 100 / p_total);
return OK;
}
@@ -935,6 +968,18 @@ class EditorExportAndroid : public EditorExportPlatform {
//printf("end\n");
}
+ static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset) {
+ Vector<String> abis = get_abis();
+ Vector<String> enabled_abis;
+ for (int i = 0; i < abis.size(); ++i) {
+ bool is_enabled = p_preset->get("architectures/" + abis[i]);
+ if (is_enabled) {
+ enabled_abis.push_back(abis[i]);
+ }
+ }
+ return enabled_abis;
+ }
+
public:
enum {
MAX_USER_PERMISSIONS = 20
@@ -945,16 +990,22 @@ public:
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
- int api = p_preset->get("graphics/api");
+ // Reenable when a GLES 2.0 backend is readded
+ /*int api = p_preset->get("graphics/api");
if (api == 0)
r_features->push_back("etc");
- else
- r_features->push_back("etc2");
+ else*/
+ r_features->push_back("etc2");
+
+ Vector<String> abis = get_enabled_abis(p_preset);
+ for (int i = 0; i < abis.size(); ++i) {
+ r_features->push_back(abis[i]);
+ }
}
virtual void get_export_options(List<ExportOption> *r_options) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1));
+ /*r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1));*/
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
@@ -964,16 +1015,18 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name"), "org.godotengine.$genname"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/icon", PROPERTY_HINT_FILE, "png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architecture/arm"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architecture/x86"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "screen/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_normal"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
+
+ for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "png"), ""));
+ }
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "keystore"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
@@ -981,6 +1034,13 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/SALT"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/public_key", PROPERTY_HINT_MULTILINE_TEXT), ""));
+ Vector<String> abis = get_abis();
+ for (int i = 0; i < abis.size(); ++i) {
+ String abi = abis[i];
+ bool is_default = (abi == "armeabi-v7a");
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + abi), is_default));
+ }
+
const char **perms = android_perms;
while (*perms) {
@@ -1066,7 +1126,7 @@ public:
if (use_reverse)
p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST;
- String export_to = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport.apk";
+ String export_to = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk");
Error err = export_project(p_preset, true, export_to, p_debug_flags);
if (err) {
device_lock->unlock();
@@ -1245,7 +1305,7 @@ public:
return valid;
}
- virtual String get_binary_extension() const {
+ virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const {
return "apk";
}
@@ -1291,13 +1351,9 @@ public:
zlib_filefunc_def io2 = io;
FileAccess *dst_f = NULL;
io2.opaque = &dst_f;
- String unaligned_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport-unaligned.apk";
+ String unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk");
zipFile unaligned_apk = zipOpen2(unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2);
- bool export_x86 = p_preset->get("architecture/x86");
- bool export_arm = p_preset->get("architecture/arm");
- bool export_arm64 = p_preset->get("architecture/arm64");
-
bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer");
bool immersive = p_preset->get("screen/immersive_mode");
@@ -1317,6 +1373,8 @@ public:
String release_username = p_preset->get("keystore/release_user");
String release_password = p_preset->get("keystore/release_password");
+ Vector<String> enabled_abis = get_enabled_abis(p_preset);
+
while (ret == UNZ_OK) {
//get filename
@@ -1333,7 +1391,7 @@ public:
//read
unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptr(), data.size());
+ unzReadCurrentFile(pkg, data.ptrw(), data.size());
unzCloseCurrentFile(pkg);
//write
@@ -1349,23 +1407,20 @@ public:
}
if (file == "res/drawable/icon.png") {
-
- String icon = p_preset->get("package/icon");
- icon = icon.strip_edges();
bool found = false;
-
- if (icon != "" && icon.ends_with(".png")) {
-
- FileAccess *f = FileAccess::open(icon, FileAccess::READ);
- if (f) {
-
- data.resize(f->get_len());
- f->get_buffer(data.ptr(), data.size());
- memdelete(f);
- found = true;
+ for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
+ String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges();
+ if (icon_path != "" && icon_path.ends_with(".png")) {
+ FileAccess *f = FileAccess::open(icon_path, FileAccess::READ);
+ if (f) {
+ data.resize(f->get_len());
+ f->get_buffer(data.ptrw(), data.size());
+ memdelete(f);
+ found = true;
+ break;
+ }
}
}
-
if (!found) {
String appicon = ProjectSettings::get_singleton()->get("application/config/icon");
@@ -1373,32 +1428,32 @@ public:
FileAccess *f = FileAccess::open(appicon, FileAccess::READ);
if (f) {
data.resize(f->get_len());
- f->get_buffer(data.ptr(), data.size());
+ f->get_buffer(data.ptrw(), data.size());
memdelete(f);
}
}
}
}
- if (file == "lib/x86/*.so" && !export_x86) {
- skip = true;
- }
-
- if (file.match("lib/armeabi*/*.so") && !export_arm) {
- skip = true;
- }
-
- if (file.match("lib/arm64*/*.so") && !export_arm64) {
- skip = true;
+ if (file.ends_with(".so")) {
+ bool enabled = false;
+ for (int i = 0; i < enabled_abis.size(); ++i) {
+ if (file.begins_with("lib/" + enabled_abis[i] + "/")) {
+ enabled = true;
+ break;
+ }
+ }
+ if (!enabled) {
+ skip = true;
+ }
}
if (file.begins_with("META-INF") && _signed) {
skip = true;
}
- print_line("ADDING: " + file);
-
if (!skip) {
+ print_line("ADDING: " + file);
// Respect decision on compression made by AAPT for the export template
const bool uncompressed = info.compression_method == 0;
@@ -1472,7 +1527,20 @@ public:
ed.ep = &ep;
ed.apk = unaligned_apk;
- err = export_project_files(p_preset, save_apk_file, &ed);
+ err = export_project_files(p_preset, save_apk_file, &ed, save_apk_so);
+ }
+
+ if (!err) {
+ APKExportData ed;
+ ed.ep = &ep;
+ ed.apk = unaligned_apk;
+ for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
+ String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges();
+ if (icon_path != "" && icon_path.ends_with(".png") && FileAccess::exists(icon_path)) {
+ Vector<uint8_t> data = FileAccess::get_file_as_array(icon_path);
+ store_in_apk(&ed, launcher_icons[i].export_path, data);
+ }
+ }
}
}
@@ -1489,12 +1557,15 @@ public:
encode_uint32(cl.size(), &clf[0]);
for (int i = 0; i < cl.size(); i++) {
+ print_line(itos(i) + " param: " + cl[i]);
CharString txt = cl[i].utf8();
int base = clf.size();
- clf.resize(base + 4 + txt.length());
- encode_uint32(txt.length(), &clf[base]);
- copymem(&clf[base + 4], txt.ptr(), txt.length());
- print_line(itos(i) + " param: " + cl[i]);
+ int length = txt.length();
+ if (!length)
+ continue;
+ clf.resize(base + 4 + length);
+ encode_uint32(length, &clf[base]);
+ copymem(&clf[base + 4], txt.ptr(), length);
}
zip_fileinfo zipfi = get_zip_fileinfo();
@@ -1635,7 +1706,7 @@ public:
int method, level;
unzOpenCurrentFile2(tmp_unaligned, &method, &level, 1); // raw read
long file_offset = unzGetCurrentFileZStreamPos64(tmp_unaligned);
- unzReadCurrentFile(tmp_unaligned, data.ptr(), data.size());
+ unzReadCurrentFile(tmp_unaligned, data.ptrw(), data.size());
unzCloseCurrentFile(tmp_unaligned);
// align
diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp
index c73b578154..0e1c17e9c8 100644
--- a/platform/android/globals/global_defaults.cpp
+++ b/platform/android/globals/global_defaults.cpp
@@ -31,12 +31,4 @@
#include "project_settings.h"
void register_android_global_defaults() {
-
- /* GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false);
- GLOBAL_DEF("rasterizer.Android/fp16_framebuffer",false);
- GLOBAL_DEF("display.Android/driver","GLES2");
- //GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
-
- ProjectSettings::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES2"));
- */
}
diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp
index 9d056bca7c..f9bcbadc24 100644
--- a/platform/android/godot_android.cpp
+++ b/platform/android/godot_android.cpp
@@ -29,24 +29,23 @@
/*************************************************************************/
#ifdef ANDROID_NATIVE_ACTIVITY
-#include <errno.h>
-#include <jni.h>
-
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-
#include "engine.h"
#include "file_access_android.h"
#include "main/main.h"
#include "os_android.h"
#include "project_settings.h"
+
+#include <EGL/egl.h>
#include <android/log.h>
#include <android/sensor.h>
#include <android/window.h>
#include <android_native_app_glue.h>
+#include <errno.h>
+#include <jni.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "godot", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "godot", __VA_ARGS__))
diff --git a/platform/android/java/src/org/godotengine/godot/Dictionary.java b/platform/android/java/src/org/godotengine/godot/Dictionary.java
index ed91fedd85..2bc9c083aa 100644
--- a/platform/android/java/src/org/godotengine/godot/Dictionary.java
+++ b/platform/android/java/src/org/godotengine/godot/Dictionary.java
@@ -32,7 +32,6 @@ package org.godotengine.godot;
import java.util.HashMap;
import java.util.Set;
-
public class Dictionary extends HashMap<String, Object> {
protected String[] keys_cache;
@@ -40,7 +39,7 @@ public class Dictionary extends HashMap<String, Object> {
public String[] get_keys() {
String[] ret = new String[size()];
- int i=0;
+ int i = 0;
Set<String> keys = keySet();
for (String key : keys) {
@@ -54,7 +53,7 @@ public class Dictionary extends HashMap<String, Object> {
public Object[] get_values() {
Object[] ret = new Object[size()];
- int i=0;
+ int i = 0;
Set<String> keys = keySet();
for (String key : keys) {
@@ -71,7 +70,7 @@ public class Dictionary extends HashMap<String, Object> {
public void set_values(Object[] vals) {
- int i=0;
+ int i = 0;
for (String key : keys_cache) {
put(key, vals[i]);
i++;
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 41dcba5c2c..3939ceb2e7 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -90,35 +90,34 @@ import android.os.Bundle;
import android.os.Messenger;
import android.os.SystemClock;
-
-public class Godot extends Activity implements SensorEventListener, IDownloaderClient
-{
+public class Godot extends Activity implements SensorEventListener, IDownloaderClient {
static final int MAX_SINGLETONS = 64;
private IStub mDownloaderClientStub;
- private IDownloaderService mRemoteService;
- private TextView mStatusText;
- private TextView mProgressFraction;
- private TextView mProgressPercent;
- private TextView mAverageSpeed;
- private TextView mTimeRemaining;
- private ProgressBar mPB;
-
- private View mDashboard;
- private View mCellMessage;
-
- private Button mPauseButton;
- private Button mWiFiSettingsButton;
-
- private boolean use_32_bits=false;
- private boolean use_immersive=false;
- private boolean mStatePaused;
- private int mState;
- private boolean keep_screen_on=true;
+ private IDownloaderService mRemoteService;
+ private TextView mStatusText;
+ private TextView mProgressFraction;
+ private TextView mProgressPercent;
+ private TextView mAverageSpeed;
+ private TextView mTimeRemaining;
+ private ProgressBar mPB;
+
+ private View mDashboard;
+ private View mCellMessage;
+
+ private Button mPauseButton;
+ private Button mWiFiSettingsButton;
+
+ private boolean use_32_bits = false;
+ private boolean use_immersive = false;
+ private boolean mStatePaused;
+ private int mState;
+ private boolean keep_screen_on = true;
static private Intent mCurrentIntent;
- @Override public void onNewIntent(Intent intent) {
+ @Override
+ public void onNewIntent(Intent intent) {
mCurrentIntent = intent;
}
@@ -127,43 +126,43 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
private void setState(int newState) {
- if (mState != newState) {
- mState = newState;
- mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState));
- }
- }
-
- private void setButtonPausedState(boolean paused) {
- mStatePaused = paused;
- int stringResourceID = paused ? com.godot.game.R.string.text_button_resume :
- com.godot.game.R.string.text_button_pause;
- mPauseButton.setText(stringResourceID);
- }
+ if (mState != newState) {
+ mState = newState;
+ mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState));
+ }
+ }
+
+ private void setButtonPausedState(boolean paused) {
+ mStatePaused = paused;
+ int stringResourceID = paused ? com.godot.game.R.string.text_button_resume :
+ com.godot.game.R.string.text_button_pause;
+ mPauseButton.setText(stringResourceID);
+ }
static public class SingletonBase {
protected void registerClass(String p_name, String[] p_methods) {
- GodotLib.singleton(p_name,this);
+ GodotLib.singleton(p_name, this);
Class clazz = getClass();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
- boolean found=false;
- Log.d("XXX","METHOD: %s\n" + method.getName());
+ boolean found = false;
+ Log.d("XXX", "METHOD: %s\n" + method.getName());
for (String s : p_methods) {
- Log.d("XXX", "METHOD CMP WITH: %s\n" + s);
+ Log.d("XXX", "METHOD CMP WITH: %s\n" + s);
if (s.equals(method.getName())) {
- found=true;
- Log.d("XXX","METHOD CMP VALID");
+ found = true;
+ Log.d("XXX", "METHOD CMP VALID");
break;
}
}
if (!found)
continue;
- Log.d("XXX","METHOD FOUND: %s\n" + method.getName());
+ Log.d("XXX", "METHOD FOUND: %s\n" + method.getName());
List<String> ptr = new ArrayList<String>();
@@ -175,17 +174,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
String[] pt = new String[ptr.size()];
ptr.toArray(pt);
- GodotLib.method(p_name,method.getName(),method.getReturnType().getName(),pt);
-
-
+ GodotLib.method(p_name, method.getName(), method.getReturnType().getName(), pt);
}
- Godot.singletons[Godot.singleton_count++]=this;
+ Godot.singletons[Godot.singleton_count++] = this;
}
protected void onMainActivityResult(int requestCode, int resultCode, Intent data) {
-
-
}
protected void onMainPause() {}
@@ -200,22 +195,20 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
public void registerMethods() {}
}
-/*
+ /*
protected List<SingletonBase> singletons = new ArrayList<SingletonBase>();
protected void instanceSingleton(SingletonBase s) {
s.registerMethods();
singletons.add(s);
}
-
-*/
+ */
private String[] command_line;
private boolean use_apk_expansion;
public GodotView mView;
- private boolean godot_initialized=false;
-
+ private boolean godot_initialized = false;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
@@ -226,36 +219,34 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
public FrameLayout layout;
public RelativeLayout adLayout;
-
static public GodotIO io;
public static void setWindowTitle(String title) {
//setTitle(title);
}
-
static SingletonBase singletons[] = new SingletonBase[MAX_SINGLETONS];
- static int singleton_count=0;
-
+ static int singleton_count = 0;
public interface ResultCallback {
public void callback(int requestCode, int resultCode, Intent data);
- };
+ }
public ResultCallback result_callback;
private PaymentsManager mPaymentsManager = null;
- @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {
- if(requestCode == PaymentsManager.REQUEST_CODE_FOR_PURCHASE){
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == PaymentsManager.REQUEST_CODE_FOR_PURCHASE) {
mPaymentsManager.processPurchaseResponse(resultCode, data);
- }else if (result_callback != null) {
+ } else if (result_callback != null) {
result_callback.callback(requestCode, resultCode, data);
result_callback = null;
};
- for(int i=0;i<singleton_count;i++) {
+ for (int i = 0; i < singleton_count; i++) {
- singletons[i].onMainActivityResult(requestCode,resultCode,data);
+ singletons[i].onMainActivityResult(requestCode, resultCode, data);
}
};
@@ -265,38 +256,38 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
//setContentView(mView);
layout = new FrameLayout(this);
- layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
+ layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
setContentView(layout);
// GodotEditText layout
GodotEditText edittext = new GodotEditText(this);
- edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
- // ...add to FrameLayout
- layout.addView(edittext);
+ edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+ // ...add to FrameLayout
+ layout.addView(edittext);
- mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this);
- layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
+ mView = new GodotView(getApplication(), io, use_gl2, use_32_bits, this);
+ layout.addView(mView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
edittext.setView(mView);
io.setEdit(edittext);
final Godot godot = this;
mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- Point fullSize = new Point();
- godot.getWindowManager().getDefaultDisplay().getSize(fullSize);
- Rect gameSize = new Rect();
- godot.mView.getWindowVisibleDisplayFrame(gameSize);
-
- final int keyboardHeight = fullSize.y - gameSize.bottom;
- Log.d("GODOT", "setVirtualKeyboardHeight: " + keyboardHeight);
- GodotLib.setVirtualKeyboardHeight(keyboardHeight);
- }
+ @Override
+ public void onGlobalLayout() {
+ Point fullSize = new Point();
+ godot.getWindowManager().getDefaultDisplay().getSize(fullSize);
+ Rect gameSize = new Rect();
+ godot.mView.getWindowVisibleDisplayFrame(gameSize);
+
+ final int keyboardHeight = fullSize.y - gameSize.bottom;
+ Log.d("GODOT", "setVirtualKeyboardHeight: " + keyboardHeight);
+ GodotLib.setVirtualKeyboardHeight(keyboardHeight);
+ }
});
// Ad layout
adLayout = new RelativeLayout(this);
- adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
+ adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout.addView(adLayout);
final String[] current_command_line = command_line;
@@ -313,12 +304,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
});
}
});
-
}
public void setKeepScreenOn(final boolean p_enabled) {
keep_screen_on = p_enabled;
- if (mView != null){
+ if (mView != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -335,12 +325,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
AlertDialog.Builder builder = new AlertDialog.Builder(getInstance());
builder.setMessage(message).setTitle(title);
builder.setPositiveButton(
- "OK",
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
+ "OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
AlertDialog dialog = builder.create();
dialog.show();
}
@@ -349,91 +339,86 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private static Godot _self;
- public static Godot getInstance(){
+ public static Godot getInstance() {
return Godot._self;
}
-
private String[] getCommandLine() {
- InputStream is;
- try {
- is = getAssets().open("_cl_");
- byte[] len = new byte[4];
- int r = is.read(len);
- if (r<4) {
- Log.d("XXX","**ERROR** Wrong cmdline length.\n");
- Log.d("GODOT", "**ERROR** Wrong cmdline length.\n");
- return new String[0];
- }
- int argc=((int)(len[3]&0xFF)<<24) | ((int)(len[2]&0xFF)<<16) | ((int)(len[1]&0xFF)<<8) | ((int)(len[0]&0xFF));
- String[] cmdline = new String[argc];
-
- for(int i=0;i<argc;i++) {
- r = is.read(len);
- if (r<4) {
-
- Log.d("GODOT", "**ERROR** Wrong cmdline param length.\n");
- return new String[0];
- }
- int strlen=((int)(len[3]&0xFF)<<24) | ((int)(len[2]&0xFF)<<16) | ((int)(len[1]&0xFF)<<8) | ((int)(len[0]&0xFF));
- if (strlen>65535) {
- Log.d("GODOT", "**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");
- }
+ InputStream is;
+ try {
+ is = getAssets().open("_cl_");
+ byte[] len = new byte[4];
+ int r = is.read(len);
+ if (r < 4) {
+ Log.d("XXX", "**ERROR** Wrong cmdline length.\n");
+ Log.d("GODOT", "**ERROR** Wrong cmdline length.\n");
+ return new String[0];
+ }
+ int argc = ((int)(len[3] & 0xFF) << 24) | ((int)(len[2] & 0xFF) << 16) | ((int)(len[1] & 0xFF) << 8) | ((int)(len[0] & 0xFF));
+ String[] cmdline = new String[argc];
+
+ for (int i = 0; i < argc; i++) {
+ r = is.read(len);
+ if (r < 4) {
+
+ Log.d("GODOT", "**ERROR** Wrong cmdline param length.\n");
+ return new String[0];
+ }
+ int strlen = ((int)(len[3] & 0xFF) << 24) | ((int)(len[2] & 0xFF) << 16) | ((int)(len[1] & 0xFF) << 8) | ((int)(len[0] & 0xFF));
+ if (strlen > 65535) {
+ Log.d("GODOT", "**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) {
- e.printStackTrace();
- Log.d("GODOT", "**ERROR** Exception " + e.getClass().getName() + ":" + e.getMessage());
+ e.printStackTrace();
+ Log.d("GODOT", "**ERROR** Exception " + e.getClass().getName() + ":" + e.getMessage());
return new String[0];
}
-
-
}
-
String expansion_pack_path;
-
private void initializeGodot() {
- if (expansion_pack_path!=null) {
+ if (expansion_pack_path != null) {
String[] new_cmdline;
- int cll=0;
- if (command_line!=null) {
- Log.d("GODOT", "initializeGodot: command_line: is not null" );
- new_cmdline = new String[ command_line.length + 2 ];
- cll=command_line.length;
- for(int i=0;i<command_line.length;i++) {
- new_cmdline[i]=command_line[i];
+ int cll = 0;
+ if (command_line != null) {
+ Log.d("GODOT", "initializeGodot: command_line: is not null");
+ new_cmdline = new String[command_line.length + 2];
+ cll = command_line.length;
+ for (int i = 0; i < command_line.length; i++) {
+ new_cmdline[i] = command_line[i];
}
} else {
- Log.d("GODOT", "initializeGodot: command_line: is null" );
- new_cmdline = new String[ 2 ];
+ Log.d("GODOT", "initializeGodot: command_line: is null");
+ new_cmdline = new String[2];
}
- new_cmdline[cll]="--main_pack";
- new_cmdline[cll+1]=expansion_pack_path;
- command_line=new_cmdline;
+ new_cmdline[cll] = "--main_pack";
+ new_cmdline[cll + 1] = expansion_pack_path;
+ command_line = new_cmdline;
}
io = new GodotIO(this);
io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
- GodotLib.io=io;
- Log.d("GODOT", "command_line is null? " + ((command_line == null)?"yes":"no"));
+ GodotLib.io = io;
+ Log.d("GODOT", "command_line is null? " + ((command_line == null) ? "yes" : "no"));
/*if(command_line != null){
Log.d("GODOT", "Command Line:");
for(int w=0;w <command_line.length;w++){
Log.d("GODOT"," " + command_line[w]);
}
}*/
- mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+ mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
@@ -449,18 +434,15 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mPaymentsManager = PaymentsManager.createManager(this).initService();
- godot_initialized=true;
-
+ godot_initialized = true;
}
@Override
public void onServiceConnected(Messenger m) {
- mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
- mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
+ mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
+ mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
}
-
-
@Override
protected void onCreate(Bundle icicle) {
@@ -474,59 +456,58 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
//check for apk expansion API
if (true) {
- boolean md5mismatch = false;
+ boolean md5mismatch = false;
command_line = getCommandLine();
- String main_pack_md5=null;
- String main_pack_key=null;
+ String main_pack_md5 = null;
+ String main_pack_key = null;
List<String> new_args = new LinkedList<String>();
+ for (int i = 0; i < command_line.length; i++) {
- for(int i=0;i<command_line.length;i++) {
-
- boolean has_extra = i< command_line.length -1;
+ boolean has_extra = i < command_line.length - 1;
if (command_line[i].equals("--use_depth_32")) {
- use_32_bits=true;
+ use_32_bits = true;
} else if (command_line[i].equals("--use_immersive")) {
- use_immersive=true;
- if(Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+
+ use_immersive = true;
+ if (Build.VERSION.SDK_INT >= 19.0) { // check if the application runs on an android 4.4+
window.getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
- | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | // hide nav bar
+ View.SYSTEM_UI_FLAG_FULLSCREEN | // hide status bar
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
UiChangeListener();
}
} else if (command_line[i].equals("--use_apk_expansion")) {
- use_apk_expansion=true;
+ use_apk_expansion = true;
} else if (has_extra && command_line[i].equals("--apk_expansion_md5")) {
- main_pack_md5=command_line[i+1];
+ main_pack_md5 = command_line[i + 1];
i++;
} else if (has_extra && command_line[i].equals("--apk_expansion_key")) {
- main_pack_key=command_line[i+1];
+ main_pack_key = command_line[i + 1];
SharedPreferences prefs = getSharedPreferences("app_data_keys", MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("store_public_key", main_pack_key);
editor.commit();
i++;
- } else if (command_line[i].trim().length()!=0){
+ } else if (command_line[i].trim().length() != 0) {
new_args.add(command_line[i]);
}
}
- if (new_args.isEmpty()){
- command_line=null;
- }else{
+ if (new_args.isEmpty()) {
+ command_line = null;
+ } else {
command_line = new_args.toArray(new String[new_args.size()]);
- }
- if (use_apk_expansion && main_pack_md5!=null && main_pack_key!=null) {
+ }
+ if (use_apk_expansion && main_pack_md5 != null && main_pack_key != null) {
//check that environment is ok!
- if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED )) {
+ if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Log.d("GODOT", "**ERROR! No media mounted!");
//show popup and die
}
@@ -534,7 +515,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
// Build the full path to the app's expansion files
try {
expansion_pack_path = Helpers.getSaveFilePath(getApplicationContext());
- expansion_pack_path+="/"+"main."+getPackageManager().getPackageInfo(getPackageName(), 0).versionCode+"."+this.getPackageName()+".obb";
+ expansion_pack_path += "/main." + getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + "." + this.getPackageName() + ".obb";
} catch (Exception e) {
e.printStackTrace();
}
@@ -542,20 +523,20 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
File f = new File(expansion_pack_path);
boolean pack_valid = true;
- Log.d("GODOT","**PACK** - Path "+expansion_pack_path);
+ Log.d("GODOT", "**PACK** - Path " + expansion_pack_path);
if (!f.exists()) {
- pack_valid=false;
- Log.d("GODOT","**PACK** - File does not exist");
+ pack_valid = false;
+ Log.d("GODOT", "**PACK** - File does not exist");
- } else if( obbIsCorrupted(expansion_pack_path, main_pack_md5)){
+ } else if (obbIsCorrupted(expansion_pack_path, main_pack_md5)) {
Log.d("GODOT", "**PACK** - Expansion pack (obb) is corrupted");
pack_valid = false;
- try{
- f.delete();
- }catch(Exception e){
- Log.d("GODOT", "**PACK** - Error deleting corrupted expansion pack (obb)");
+ try {
+ f.delete();
+ } catch (Exception e) {
+ Log.d("GODOT", "**PACK** - Error deleting corrupted expansion pack (obb)");
}
}
@@ -564,12 +545,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
Intent notifierIntent = new Intent(this, this.getClass());
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ Intent.FLAG_ACTIVITY_CLEAR_TOP);
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
- notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
+ notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- int startResult;
+ int startResult;
try {
Log.d("GODOT", "INITIALIZING DOWNLOAD");
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
@@ -578,36 +559,34 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
GodotDownloaderService.class);
Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult);
- if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
- Log.d("GODOT", "DOWNLOAD REQUIRED");
- // This is where you do set up to display the download
- // progress (next step)
- mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
- GodotDownloaderService.class);
-
- setContentView(com.godot.game.R.layout.downloading_expansion);
- mPB = (ProgressBar) findViewById(com.godot.game.R.id.progressBar);
- mStatusText = (TextView) findViewById(com.godot.game.R.id.statusText);
- mProgressFraction = (TextView) findViewById(com.godot.game.R.id.progressAsFraction);
- mProgressPercent = (TextView) findViewById(com.godot.game.R.id.progressAsPercentage);
- mAverageSpeed = (TextView) findViewById(com.godot.game.R.id.progressAverageSpeed);
- mTimeRemaining = (TextView) findViewById(com.godot.game.R.id.progressTimeRemaining);
- mDashboard = findViewById(com.godot.game.R.id.downloaderDashboard);
- mCellMessage = findViewById(com.godot.game.R.id.approveCellular);
- mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton);
- mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton);
-
- return;
- } else{
- Log.d("GODOT", "NO DOWNLOAD REQUIRED");
- }
+ if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
+ Log.d("GODOT", "DOWNLOAD REQUIRED");
+ // This is where you do set up to display the download
+ // progress (next step)
+ mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
+ GodotDownloaderService.class);
+
+ setContentView(com.godot.game.R.layout.downloading_expansion);
+ mPB = (ProgressBar)findViewById(com.godot.game.R.id.progressBar);
+ mStatusText = (TextView)findViewById(com.godot.game.R.id.statusText);
+ mProgressFraction = (TextView)findViewById(com.godot.game.R.id.progressAsFraction);
+ mProgressPercent = (TextView)findViewById(com.godot.game.R.id.progressAsPercentage);
+ mAverageSpeed = (TextView)findViewById(com.godot.game.R.id.progressAverageSpeed);
+ mTimeRemaining = (TextView)findViewById(com.godot.game.R.id.progressTimeRemaining);
+ mDashboard = findViewById(com.godot.game.R.id.downloaderDashboard);
+ mCellMessage = findViewById(com.godot.game.R.id.approveCellular);
+ mPauseButton = (Button)findViewById(com.godot.game.R.id.pauseButton);
+ mWiFiSettingsButton = (Button)findViewById(com.godot.game.R.id.wifiSettingsButton);
+
+ return;
+ } else {
+ Log.d("GODOT", "NO DOWNLOAD REQUIRED");
+ }
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
Log.d("GODOT", "Error downloading expansion package:" + e.getMessage());
}
-
}
-
}
}
@@ -615,28 +594,26 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
initializeGodot();
-
//instanceSingleton( new GodotFacebook(this) );
-
-
}
+ @Override
+ protected void onDestroy() {
- @Override protected void onDestroy(){
-
- if(mPaymentsManager != null ) mPaymentsManager.destroy();
- for(int i=0;i<singleton_count;i++) {
+ if (mPaymentsManager != null) mPaymentsManager.destroy();
+ for (int i = 0; i < singleton_count; i++) {
singletons[i].onMainDestroy();
}
super.onDestroy();
}
- @Override protected void onPause() {
+ @Override
+ protected void onPause() {
super.onPause();
- if (!godot_initialized){
+ if (!godot_initialized) {
if (null != mDownloaderClientStub) {
- mDownloaderClientStub.disconnect(this);
- }
+ mDownloaderClientStub.disconnect(this);
+ }
return;
}
mView.onPause();
@@ -648,17 +625,18 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
});
mSensorManager.unregisterListener(this);
- for(int i=0;i<singleton_count;i++) {
+ for (int i = 0; i < singleton_count; i++) {
singletons[i].onMainPause();
}
}
- @Override protected void onResume() {
+ @Override
+ protected void onResume() {
super.onResume();
- if (!godot_initialized){
+ if (!godot_initialized) {
if (null != mDownloaderClientStub) {
- mDownloaderClientStub.connect(this);
- }
+ mDownloaderClientStub.connect(this);
+ }
return;
}
@@ -674,59 +652,58 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
- if(use_immersive && Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+
+ if (use_immersive && Build.VERSION.SDK_INT >= 19.0) { // check if the application runs on an android 4.4+
Window window = getWindow();
window.getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
- | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | // hide nav bar
+ View.SYSTEM_UI_FLAG_FULLSCREEN | // hide status bar
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
- for(int i=0;i<singleton_count;i++) {
+ for (int i = 0; i < singleton_count; i++) {
singletons[i].onMainResume();
}
-
-
-
}
public void UiChangeListener() {
final View decorView = getWindow().getDecorView();
- decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() {
+ decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
decorView.setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
});
}
- @Override public void onSensorChanged(SensorEvent event) {
- Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayRotation = display.getRotation();
float[] adjustedValues = new float[3];
final int axisSwap[][] = {
- { 1, -1, 0, 1 }, // ROTATION_0
- {-1, -1, 1, 0 }, // ROTATION_90
- {-1, 1, 0, 1 }, // ROTATION_180
- { 1, 1, 1, 0 } }; // ROTATION_270
+ { 1, -1, 0, 1 }, // ROTATION_0
+ { -1, -1, 1, 0 }, // ROTATION_90
+ { -1, 1, 0, 1 }, // ROTATION_180
+ { 1, 1, 1, 0 }
+ }; // ROTATION_270
final int[] as = axisSwap[displayRotation];
- adjustedValues[0] = (float)as[0] * event.values[ as[2] ];
- adjustedValues[1] = (float)as[1] * event.values[ as[3] ];
- adjustedValues[2] = event.values[2];
+ adjustedValues[0] = (float)as[0] * event.values[as[2]];
+ adjustedValues[1] = (float)as[1] * event.values[as[3]];
+ adjustedValues[2] = event.values[2];
final float x = adjustedValues[0];
final float y = adjustedValues[1];
@@ -738,27 +715,28 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
@Override
public void run() {
if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) {
- GodotLib.accelerometer(-x,y,-z);
+ GodotLib.accelerometer(-x, y, -z);
}
if (typeOfSensor == Sensor.TYPE_GRAVITY) {
- GodotLib.gravity(-x,y,-z);
+ GodotLib.gravity(-x, y, -z);
}
if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) {
- GodotLib.magnetometer(-x,y,-z);
+ GodotLib.magnetometer(-x, y, -z);
}
if (typeOfSensor == Sensor.TYPE_GYROSCOPE) {
- GodotLib.gyroscope(x,-y,z);
+ GodotLib.gyroscope(x, -y, z);
}
}
});
}
}
- @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) {
+ @Override
+ public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
-/*
+ /*
@Override public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
@@ -772,12 +750,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return false;
}
-*/
+ */
- @Override public void onBackPressed() {
+ @Override
+ public void onBackPressed() {
boolean shouldQuit = true;
- for(int i=0;i<singleton_count;i++) {
+ for (int i = 0; i < singleton_count; i++) {
if (singletons[i].onMainBackPressed()) {
shouldQuit = false;
}
@@ -799,71 +778,68 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
System.exit(0);
}
+ private boolean obbIsCorrupted(String f, String main_pack_md5) {
+ try {
- private boolean obbIsCorrupted(String f, String main_pack_md5){
-
- try {
-
- InputStream fis = new FileInputStream(f);
+ InputStream fis = new FileInputStream(f);
- // Create MD5 Hash
- byte[] buffer = new byte[16384];
-
- MessageDigest complete = MessageDigest.getInstance("MD5");
- int numRead;
- do {
- numRead = fis.read(buffer);
- if (numRead > 0) {
- complete.update(buffer, 0, numRead);
- }
- } while (numRead != -1);
+ // Create MD5 Hash
+ byte[] buffer = new byte[16384];
+ MessageDigest complete = MessageDigest.getInstance("MD5");
+ int numRead;
+ do {
+ numRead = fis.read(buffer);
+ if (numRead > 0) {
+ complete.update(buffer, 0, numRead);
+ }
+ } while (numRead != -1);
- fis.close();
- byte[] messageDigest = complete.digest();
+ fis.close();
+ byte[] messageDigest = complete.digest();
- // Create Hex String
- StringBuffer hexString = new StringBuffer();
- for (int i=0; i<messageDigest.length; i++) {
- String s = Integer.toHexString(0xFF & messageDigest[i]);
+ // Create Hex String
+ StringBuffer hexString = new StringBuffer();
+ for (int i = 0; i < messageDigest.length; i++) {
+ String s = Integer.toHexString(0xFF & messageDigest[i]);
- if (s.length()==1) {
- s="0"+s;
- }
- hexString.append(s);
- }
- String md5str = hexString.toString();
+ if (s.length() == 1) {
+ s = "0" + s;
+ }
+ hexString.append(s);
+ }
+ String md5str = hexString.toString();
- //Log.d("GODOT","**PACK** - My MD5: "+hexString+" - APK md5: "+main_pack_md5);
- if (!md5str.equals(main_pack_md5)) {
- Log.d("GODOT","**PACK MD5 MISMATCH???** - MD5 Found: "+md5str+" "+Integer.toString(md5str.length())+" - MD5 Expected: "+main_pack_md5+" "+Integer.toString(main_pack_md5.length()));
- return true;
- }
- return false;
- } catch (Exception e) {
- e.printStackTrace();
- Log.d("GODOT","**PACK FAIL**");
- return true;
- }
+ //Log.d("GODOT","**PACK** - My MD5: "+hexString+" - APK md5: "+main_pack_md5);
+ if (!md5str.equals(main_pack_md5)) {
+ Log.d("GODOT", "**PACK MD5 MISMATCH???** - MD5 Found: " + md5str + " " + Integer.toString(md5str.length()) + " - MD5 Expected: " + main_pack_md5 + " " + Integer.toString(main_pack_md5.length()));
+ return true;
+ }
+ return false;
+ } catch (Exception e) {
+ e.printStackTrace();
+ Log.d("GODOT", "**PACK FAIL**");
+ return true;
+ }
}
//@Override public boolean dispatchTouchEvent (MotionEvent event) {
public boolean gotTouchEvent(final MotionEvent event) {
super.onTouchEvent(event);
- final int evcount=event.getPointerCount();
- if (evcount==0)
+ final int evcount = event.getPointerCount();
+ if (evcount == 0)
return true;
if (mView != null) {
- final int[] arr = new int[event.getPointerCount()*3];
+ final int[] arr = new int[event.getPointerCount() * 3];
- for(int i=0;i<event.getPointerCount();i++) {
+ for (int i = 0; i < event.getPointerCount(); i++) {
- arr[i*3+0]=(int)event.getPointerId(i);
- arr[i*3+1]=(int)event.getX(i);
- arr[i*3+2]=(int)event.getY(i);
+ arr[i * 3 + 0] = (int)event.getPointerId(i);
+ arr[i * 3 + 1] = (int)event.getX(i);
+ arr[i * 3 + 2] = (int)event.getY(i);
}
//System.out.printf("gaction: %d\n",event.getAction());
@@ -871,13 +847,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mView.queueEvent(new Runnable() {
@Override
public void run() {
- switch(action) {
+ switch (action) {
case MotionEvent.ACTION_DOWN: {
- GodotLib.touch(0,0,evcount,arr);
+ GodotLib.touch(0, 0, evcount, arr);
//System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
} break;
case MotionEvent.ACTION_MOVE: {
- GodotLib.touch(1,0,evcount,arr);
+ GodotLib.touch(1, 0, evcount, arr);
/*
for(int i=0;i<event.getPointerCount();i++) {
System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
@@ -887,17 +863,17 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
case MotionEvent.ACTION_POINTER_UP: {
final int indexPointUp = event.getActionIndex();
final int pointer_idx = event.getPointerId(indexPointUp);
- GodotLib.touch(4,pointer_idx,evcount,arr);
+ GodotLib.touch(4, pointer_idx, evcount, arr);
//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
} break;
case MotionEvent.ACTION_POINTER_DOWN: {
int pointer_idx = event.getActionIndex();
- GodotLib.touch(3,pointer_idx,evcount,arr);
+ GodotLib.touch(3, pointer_idx, evcount, arr);
//System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
} break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
- GodotLib.touch(2,0,evcount,arr);
+ GodotLib.touch(2, 0, evcount, arr);
/*
for(int i=0;i<event.getPointerCount();i++) {
System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
@@ -911,14 +887,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
return true;
}
- @Override public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
+ @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);
+ 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() {
@@ -939,7 +917,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private void queueEvent(Runnable runnable) {
// TODO Auto-generated method stub
-
}
public PaymentsManager getPaymentsManager() {
@@ -952,7 +929,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
}
*/
-
// Audio
/**
@@ -960,110 +936,106 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
* to show the state as being indeterminate at times. This sample can be
* considered a guideline.
*/
- @Override
- public void onDownloadStateChanged(int newState) {
- Log.d("GODOT", "onDownloadStateChanged:" + newState);
- setState(newState);
- boolean showDashboard = true;
- boolean showCellMessage = false;
- boolean paused;
- boolean indeterminate;
- switch (newState) {
- case IDownloaderClient.STATE_IDLE:
- Log.d("GODOT", "STATE IDLE");
- // STATE_IDLE means the service is listening, so it's
- // safe to start making calls via mRemoteService.
- paused = false;
- indeterminate = true;
- break;
- case IDownloaderClient.STATE_CONNECTING:
- case IDownloaderClient.STATE_FETCHING_URL:
- Log.d("GODOT", "STATE CONNECTION / FETCHING URL");
- showDashboard = true;
- paused = false;
- indeterminate = true;
- break;
- case IDownloaderClient.STATE_DOWNLOADING:
- Log.d("GODOT", "STATE DOWNLOADING");
- paused = false;
- showDashboard = true;
- indeterminate = false;
- break;
-
- case IDownloaderClient.STATE_FAILED_CANCELED:
- case IDownloaderClient.STATE_FAILED:
- case IDownloaderClient.STATE_FAILED_FETCHING_URL:
- case IDownloaderClient.STATE_FAILED_UNLICENSED:
- Log.d("GODOT", "MANY TYPES OF FAILING");
- paused = true;
- showDashboard = false;
- indeterminate = false;
- break;
- case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
- case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
- Log.d("GODOT", "PAUSED FOR SOME STUPID REASON");
- showDashboard = false;
- paused = true;
- indeterminate = false;
- showCellMessage = true;
- break;
-
- case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
- Log.d("GODOT", "PAUSED BY STUPID USER");
- paused = true;
- indeterminate = false;
- break;
- case IDownloaderClient.STATE_PAUSED_ROAMING:
- case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
- Log.d("GODOT", "PAUSED BY ROAMING WTF!?");
- paused = true;
- indeterminate = false;
- break;
- case IDownloaderClient.STATE_COMPLETED:
- Log.d("GODOT", "COMPLETED");
- showDashboard = false;
- paused = false;
- indeterminate = false;
-// validateXAPKZipFiles();
- initializeGodot();
- return;
- default:
- Log.d("GODOT", "DEFAULT ????");
- paused = true;
- indeterminate = true;
- showDashboard = true;
- }
- int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE;
- if (mDashboard.getVisibility() != newDashboardVisibility) {
- mDashboard.setVisibility(newDashboardVisibility);
- }
- int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE;
- if (mCellMessage.getVisibility() != cellMessageVisibility) {
- mCellMessage.setVisibility(cellMessageVisibility);
- }
-
- mPB.setIndeterminate(indeterminate);
- setButtonPausedState(paused);
- }
+ @Override
+ public void onDownloadStateChanged(int newState) {
+ Log.d("GODOT", "onDownloadStateChanged:" + newState);
+ setState(newState);
+ boolean showDashboard = true;
+ boolean showCellMessage = false;
+ boolean paused;
+ boolean indeterminate;
+ switch (newState) {
+ case IDownloaderClient.STATE_IDLE:
+ Log.d("GODOT", "DOWNLOAD STATE IDLE");
+ // STATE_IDLE means the service is listening, so it's
+ // safe to start making calls via mRemoteService.
+ paused = false;
+ indeterminate = true;
+ break;
+ case IDownloaderClient.STATE_CONNECTING:
+ case IDownloaderClient.STATE_FETCHING_URL:
+ Log.d("GODOT", "DOWNLOAD STATE CONNECTION / FETCHING URL");
+ showDashboard = true;
+ paused = false;
+ indeterminate = true;
+ break;
+ case IDownloaderClient.STATE_DOWNLOADING:
+ Log.d("GODOT", "DOWNLOAD STATE DOWNLOADING");
+ paused = false;
+ showDashboard = true;
+ indeterminate = false;
+ break;
+
+ case IDownloaderClient.STATE_FAILED_CANCELED:
+ case IDownloaderClient.STATE_FAILED:
+ case IDownloaderClient.STATE_FAILED_FETCHING_URL:
+ case IDownloaderClient.STATE_FAILED_UNLICENSED:
+ Log.d("GODOT", "DOWNLOAD STATE: FAILED, CANCELLED, UNLICENSED OR FAILED TO FETCH URL");
+ paused = true;
+ showDashboard = false;
+ indeterminate = false;
+ break;
+ case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
+ case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
+ Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY MISSING CELLULAR PERMISSION");
+ showDashboard = false;
+ paused = true;
+ indeterminate = false;
+ showCellMessage = true;
+ break;
+
+ case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
+ Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY USER");
+ paused = true;
+ indeterminate = false;
+ break;
+ case IDownloaderClient.STATE_PAUSED_ROAMING:
+ case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
+ Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY ROAMING OR SDCARD UNAVAILABLE");
+ paused = true;
+ indeterminate = false;
+ break;
+ case IDownloaderClient.STATE_COMPLETED:
+ Log.d("GODOT", "DOWNLOAD STATE: COMPLETED");
+ showDashboard = false;
+ paused = false;
+ indeterminate = false;
+ // validateXAPKZipFiles();
+ initializeGodot();
+ return;
+ default:
+ Log.d("GODOT", "DOWNLOAD STATE: DEFAULT");
+ paused = true;
+ indeterminate = true;
+ showDashboard = true;
+ }
+ int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE;
+ if (mDashboard.getVisibility() != newDashboardVisibility) {
+ mDashboard.setVisibility(newDashboardVisibility);
+ }
+ int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE;
+ if (mCellMessage.getVisibility() != cellMessageVisibility) {
+ mCellMessage.setVisibility(cellMessageVisibility);
+ }
+ mPB.setIndeterminate(indeterminate);
+ setButtonPausedState(paused);
+ }
@Override
public void onDownloadProgress(DownloadProgressInfo progress) {
mAverageSpeed.setText(getString(com.godot.game.R.string.kilobytes_per_second,
- Helpers.getSpeedString(progress.mCurrentSpeed)));
- mTimeRemaining.setText(getString(com.godot.game.R.string.time_remaining,
- Helpers.getTimeRemaining(progress.mTimeRemaining)));
-
- progress.mOverallTotal = progress.mOverallTotal;
- mPB.setMax((int) (progress.mOverallTotal >> 8));
- mPB.setProgress((int) (progress.mOverallProgress >> 8));
- mProgressPercent.setText(Long.toString(progress.mOverallProgress
- * 100 /
- progress.mOverallTotal) + "%");
- mProgressFraction.setText(Helpers.getDownloadProgressString
- (progress.mOverallProgress,
- progress.mOverallTotal));
-
+ Helpers.getSpeedString(progress.mCurrentSpeed)));
+ mTimeRemaining.setText(getString(com.godot.game.R.string.time_remaining,
+ Helpers.getTimeRemaining(progress.mTimeRemaining)));
+
+ progress.mOverallTotal = progress.mOverallTotal;
+ mPB.setMax((int)(progress.mOverallTotal >> 8));
+ mPB.setProgress((int)(progress.mOverallProgress >> 8));
+ mProgressPercent.setText(Long.toString(progress.mOverallProgress * 100 /
+ progress.mOverallTotal) +
+ "%");
+ mProgressFraction.setText(Helpers.getDownloadProgressString(progress.mOverallProgress,
+ progress.mOverallTotal));
}
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
index 2c668dd586..568c7a4140 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
@@ -46,14 +46,14 @@ import android.util.Log;
*/
public class GodotDownloaderAlarmReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.d("GODOT", "Alarma recivida");
- try {
- DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, GodotDownloaderService.class);
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- Log.d("GODOT", "Exception: " + e.getClass().getName() + ":" + e.getMessage());
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d("GODOT", "Alarma recivida");
+ try {
+ DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, GodotDownloaderService.class);
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ Log.d("GODOT", "Exception: " + e.getClass().getName() + ":" + e.getMessage());
+ }
}
- }
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
index 97ba7826fb..b8b3b925c5 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
@@ -40,46 +40,45 @@ import com.google.android.vending.expansion.downloader.impl.DownloaderService;
* DownloaderService from the Downloader library.
*/
public class GodotDownloaderService extends DownloaderService {
- // stuff for LVL -- MODIFY FOR YOUR APPLICATION!
- private static final String BASE64_PUBLIC_KEY = "REPLACE THIS WITH YOUR PUBLIC KEY";
- // used by the preference obfuscater
- private static final byte[] SALT = new byte[] {
- 1, 43, -12, -1, 54, 98,
- -100, -12, 43, 2, -8, -4, 9, 5, -106, -108, -33, 45, -1, 84
- };
+ // stuff for LVL -- MODIFY FOR YOUR APPLICATION!
+ private static final String BASE64_PUBLIC_KEY = "REPLACE THIS WITH YOUR PUBLIC KEY";
+ // used by the preference obfuscater
+ private static final byte[] SALT = new byte[] {
+ 1, 43, -12, -1, 54, 98,
+ -100, -12, 43, 2, -8, -4, 9, 5, -106, -108, -33, 45, -1, 84
+ };
- /**
+ /**
* This public key comes from your Android Market publisher account, and it
* used by the LVL to validate responses from Market on your behalf.
*/
- @Override
- public String getPublicKey() {
- SharedPreferences prefs = getApplicationContext().getSharedPreferences("app_data_keys", Context.MODE_PRIVATE);
- Log.d("GODOT", "getting public key:" + prefs.getString("store_public_key", null));
- return prefs.getString("store_public_key", null);
-
- //return BASE64_PUBLIC_KEY;
- }
+ @Override
+ public String getPublicKey() {
+ SharedPreferences prefs = getApplicationContext().getSharedPreferences("app_data_keys", Context.MODE_PRIVATE);
+ Log.d("GODOT", "getting public key:" + prefs.getString("store_public_key", null));
+ return prefs.getString("store_public_key", null);
- /**
+ //return BASE64_PUBLIC_KEY;
+ }
+
+ /**
* This is used by the preference obfuscater to make sure that your
* obfuscated preferences are different than the ones used by other
* applications.
*/
- @Override
- public byte[] getSALT() {
- return SALT;
- }
+ @Override
+ public byte[] getSALT() {
+ return SALT;
+ }
- /**
+ /**
* Fill this in with the class name for your alarm receiver. We do this
* because receivers must be unique across all of Android (it's a good idea
* to make sure that your receiver is in your unique package)
*/
- @Override
- public String getAlarmReceiverClassName() {
- Log.d("GODOT", "getAlarmReceiverClassName()");
- return GodotDownloaderAlarmReceiver.class.getName();
- }
-
+ @Override
+ public String getAlarmReceiverClassName() {
+ Log.d("GODOT", "getAlarmReceiverClassName()");
+ return GodotDownloaderAlarmReceiver.class.getName();
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotIO.java b/platform/android/java/src/org/godotengine/godot/GodotIO.java
index 989fd2b609..12a2467a29 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotIO.java
@@ -56,7 +56,6 @@ import org.godotengine.godot.input.*;
public class GodotIO {
-
AssetManager am;
Godot activity;
GodotEditText edit;
@@ -64,35 +63,32 @@ public class GodotIO {
Context applicationContext;
MediaPlayer mediaPlayer;
- final int SCREEN_LANDSCAPE=0;
- final int SCREEN_PORTRAIT=1;
- final int SCREEN_REVERSE_LANDSCAPE=2;
- final int SCREEN_REVERSE_PORTRAIT=3;
- final int SCREEN_SENSOR_LANDSCAPE=4;
- final int SCREEN_SENSOR_PORTRAIT=5;
- final int SCREEN_SENSOR=6;
+ final int SCREEN_LANDSCAPE = 0;
+ final int SCREEN_PORTRAIT = 1;
+ final int SCREEN_REVERSE_LANDSCAPE = 2;
+ final int SCREEN_REVERSE_PORTRAIT = 3;
+ final int SCREEN_SENSOR_LANDSCAPE = 4;
+ final int SCREEN_SENSOR_PORTRAIT = 5;
+ final int SCREEN_SENSOR = 6;
/////////////////////////
/// FILES
/////////////////////////
- public int last_file_id=1;
+ public int last_file_id = 1;
class AssetData {
-
- public boolean eof=false;
+ public boolean eof = false;
public String path;
public InputStream is;
public int len;
public int pos;
}
+ HashMap<Integer, AssetData> streams;
- HashMap<Integer,AssetData> streams;
-
-
- public int file_open(String path,boolean write) {
+ public int file_open(String path, boolean write) {
//System.out.printf("file_open: Attempt to Open %s\n",path);
@@ -100,7 +96,6 @@ public class GodotIO {
if (write)
return -1;
-
AssetData ad = new AssetData();
try {
@@ -113,76 +108,73 @@ public class GodotIO {
}
try {
- ad.len=ad.is.available();
+ ad.len = ad.is.available();
} catch (Exception e) {
- System.out.printf("Exception availabling on file_open: %s\n",path);
+ System.out.printf("Exception availabling on file_open: %s\n", path);
return -1;
}
- ad.path=path;
- ad.pos=0;
+ ad.path = path;
+ ad.pos = 0;
++last_file_id;
- streams.put(last_file_id,ad);
+ streams.put(last_file_id, ad);
return last_file_id;
}
public int file_get_size(int id) {
if (!streams.containsKey(id)) {
- System.out.printf("file_get_size: Invalid file id: %d\n",id);
+ System.out.printf("file_get_size: Invalid file id: %d\n", id);
return -1;
}
return streams.get(id).len;
-
}
- public void file_seek(int id,int bytes) {
+ public void file_seek(int id, int bytes) {
if (!streams.containsKey(id)) {
- System.out.printf("file_get_size: Invalid file id: %d\n",id);
+ System.out.printf("file_get_size: Invalid file id: %d\n", id);
return;
}
//seek sucks
AssetData ad = streams.get(id);
- if (bytes>ad.len)
- bytes=ad.len;
- if (bytes<0)
- bytes=0;
+ if (bytes > ad.len)
+ bytes = ad.len;
+ if (bytes < 0)
+ bytes = 0;
try {
- if (bytes > (int)ad.pos) {
- int todo=bytes-(int)ad.pos;
- while(todo>0) {
- todo-=ad.is.skip(todo);
- }
- ad.pos=bytes;
- } else if (bytes<(int)ad.pos) {
+ if (bytes > (int)ad.pos) {
+ int todo = bytes - (int)ad.pos;
+ while (todo > 0) {
+ todo -= ad.is.skip(todo);
+ }
+ ad.pos = bytes;
+ } else if (bytes < (int)ad.pos) {
- ad.is=am.open(ad.path);
+ ad.is = am.open(ad.path);
- ad.pos=bytes;
- int todo=bytes;
- while(todo>0) {
- todo-=ad.is.skip(todo);
+ ad.pos = bytes;
+ int todo = bytes;
+ while (todo > 0) {
+ todo -= ad.is.skip(todo);
+ }
}
- }
- ad.eof=false;
+ ad.eof = false;
} catch (IOException e) {
- System.out.printf("Exception on file_seek: %s\n",e);
+ System.out.printf("Exception on file_seek: %s\n", e);
return;
}
-
-
}
public int file_tell(int id) {
if (!streams.containsKey(id)) {
- System.out.printf("file_read: Can't tell eof for invalid file id: %d\n",id);
+ System.out.printf("file_read: Can't tell eof for invalid file id: %d\n", id);
return 0;
}
@@ -192,7 +184,7 @@ public class GodotIO {
public boolean file_eof(int id) {
if (!streams.containsKey(id)) {
- System.out.printf("file_read: Can't check eof for invalid file id: %d\n",id);
+ System.out.printf("file_read: Can't check eof for invalid file id: %d\n", id);
return false;
}
@@ -203,73 +195,65 @@ public class GodotIO {
public byte[] file_read(int id, int bytes) {
if (!streams.containsKey(id)) {
- System.out.printf("file_read: Can't read invalid file id: %d\n",id);
+ System.out.printf("file_read: Can't read invalid file id: %d\n", id);
return new byte[0];
}
-
AssetData ad = streams.get(id);
if (ad.pos + bytes > ad.len) {
- bytes=ad.len-ad.pos;
- ad.eof=true;
+ bytes = ad.len - ad.pos;
+ ad.eof = true;
}
-
- if (bytes==0) {
+ if (bytes == 0) {
return new byte[0];
}
-
-
- byte[] buf1=new byte[bytes];
- int r=0;
+ byte[] buf1 = new byte[bytes];
+ int r = 0;
try {
r = ad.is.read(buf1);
} catch (IOException e) {
- System.out.printf("Exception on file_read: %s\n",e);
+ System.out.printf("Exception on file_read: %s\n", e);
return new byte[bytes];
}
- if (r==0) {
+ if (r == 0) {
return new byte[0];
}
- ad.pos+=r;
+ ad.pos += r;
- if (r<bytes) {
+ if (r < bytes) {
- byte[] buf2=new byte[r];
- for(int i=0;i<r;i++)
- buf2[i]=buf1[i];
+ byte[] buf2 = new byte[r];
+ for (int i = 0; i < r; i++)
+ buf2[i] = buf1[i];
return buf2;
} else {
return buf1;
}
-
}
public void file_close(int id) {
if (!streams.containsKey(id)) {
- System.out.printf("file_close: Can't close invalid file id: %d\n",id);
+ System.out.printf("file_close: Can't close invalid file id: %d\n", id);
return;
}
streams.remove(id);
-
}
-
/////////////////////////
/// DIRECTORIES
/////////////////////////
-
class AssetDir {
public String[] files;
@@ -277,49 +261,48 @@ public class GodotIO {
public String path;
}
- public int last_dir_id=1;
+ public int last_dir_id = 1;
- HashMap<Integer,AssetDir> dirs;
+ HashMap<Integer, AssetDir> dirs;
public int dir_open(String path) {
AssetDir ad = new AssetDir();
- ad.current=0;
- ad.path=path;
+ ad.current = 0;
+ ad.path = path;
try {
ad.files = am.list(path);
// no way to find path is directory or file exactly.
// but if ad.files.length==0, then it's an empty directory or file.
- if (ad.files.length==0) {
+ if (ad.files.length == 0) {
return -1;
}
} catch (IOException e) {
- System.out.printf("Exception on dir_open: %s\n",e);
+ System.out.printf("Exception on dir_open: %s\n", e);
return -1;
}
//System.out.printf("Opened dir: %s\n",path);
++last_dir_id;
- dirs.put(last_dir_id,ad);
+ dirs.put(last_dir_id, ad);
return last_dir_id;
-
}
public boolean dir_is_dir(int id) {
if (!dirs.containsKey(id)) {
- System.out.printf("dir_next: invalid dir id: %d\n",id);
+ System.out.printf("dir_next: invalid dir id: %d\n", id);
return false;
}
AssetDir ad = dirs.get(id);
//System.out.printf("go next: %d,%d\n",ad.current,ad.files.length);
int idx = ad.current;
- if (idx>0)
+ if (idx > 0)
idx--;
- if (idx>=ad.files.length)
+ if (idx >= ad.files.length)
return false;
String fname = ad.files[idx];
@@ -327,7 +310,7 @@ public class GodotIO {
if (ad.path.equals(""))
am.open(fname);
else
- am.open(ad.path+"/"+fname);
+ am.open(ad.path + "/" + fname);
return false;
} catch (Exception e) {
return true;
@@ -337,46 +320,41 @@ public class GodotIO {
public String dir_next(int id) {
if (!dirs.containsKey(id)) {
- System.out.printf("dir_next: invalid dir id: %d\n",id);
+ System.out.printf("dir_next: invalid dir id: %d\n", id);
return "";
}
AssetDir ad = dirs.get(id);
//System.out.printf("go next: %d,%d\n",ad.current,ad.files.length);
- if (ad.current>=ad.files.length) {
+ if (ad.current >= ad.files.length) {
ad.current++;
return "";
}
String r = ad.files[ad.current];
ad.current++;
return r;
-
}
public void dir_close(int id) {
if (!dirs.containsKey(id)) {
- System.out.printf("dir_close: invalid dir id: %d\n",id);
+ System.out.printf("dir_close: invalid dir id: %d\n", id);
return;
}
dirs.remove(id);
}
-
-
GodotIO(Godot p_activity) {
- am=p_activity.getAssets();
- activity=p_activity;
- streams=new HashMap<Integer,AssetData>();
- dirs=new HashMap<Integer,AssetDir>();
+ am = p_activity.getAssets();
+ activity = p_activity;
+ streams = new HashMap<Integer, AssetData>();
+ dirs = new HashMap<Integer, AssetDir>();
applicationContext = activity.getApplicationContext();
-
}
-
/////////////////////////
// AUDIO
/////////////////////////
@@ -400,7 +378,7 @@ public class GodotIO {
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
- channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
+ channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
audioStartThread();
@@ -412,10 +390,10 @@ public class GodotIO {
public void audioStartThread() {
mAudioThread = new Thread(new Runnable() {
- public void run() {
- mAudioTrack.play();
- GodotLib.audio();
- }
+ public void run() {
+ mAudioTrack.play();
+ GodotLib.audio();
+ }
});
// I'd take REALTIME if I could get it!
@@ -424,15 +402,15 @@ public class GodotIO {
}
public void audioWriteShortBuffer(short[] buffer) {
- for (int i = 0; i < buffer.length; ) {
+ for (int i = 0; i < buffer.length;) {
int result = mAudioTrack.write(buffer, i, buffer.length - i);
if (result > 0) {
i += result;
} else if (result == 0) {
try {
- Thread.sleep(1);
- } catch(InterruptedException e) {
- // Nom nom
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ // Nom nom
}
} else {
Log.w("Godot", "Godot audio: error return from write(short)");
@@ -441,18 +419,16 @@ public class GodotIO {
}
}
-
-
public void audioQuit() {
if (mAudioThread != null) {
try {
mAudioThread.join();
- } catch(Exception e) {
+ } catch (Exception e) {
Log.v("Godot", "Problem stopping audio thread: " + e);
}
mAudioThread = null;
- //Log.v("Godot", "Finished waiting for audio thread");
+ //Log.v("Godot", "Finished waiting for audio thread");
}
if (mAudioTrack != null) {
@@ -473,20 +449,18 @@ public class GodotIO {
// MISCELLANEOUS OS IO
/////////////////////////
-
-
public int openURI(String p_uri) {
try {
Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri);
String path = p_uri;
- String type="";
+ String type = "";
if (path.startsWith("/")) {
//absolute path to filesystem, prepend file://
- path="file://"+path;
+ path = "file://" + path;
if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) {
- type="image/*";
+ type = "image/*";
}
}
@@ -531,7 +505,7 @@ public class GodotIO {
}
public void showKeyboard(String p_existing_text) {
- if(edit != null)
+ if (edit != null)
edit.showKeyboard(p_existing_text);
//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -539,21 +513,21 @@ public class GodotIO {
};
public void hideKeyboard() {
- if(edit != null)
+ if (edit != null)
edit.hideKeyboard();
- InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
- View v = activity.getCurrentFocus();
- if (v != null) {
- inputMgr.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
- } else {
- inputMgr.hideSoftInputFromWindow(new View(activity).getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
- }
+ InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
+ View v = activity.getCurrentFocus();
+ if (v != null) {
+ inputMgr.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ } else {
+ inputMgr.hideSoftInputFromWindow(new View(activity).getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ }
};
public void setScreenOrientation(int p_orientation) {
- switch(p_orientation) {
+ switch (p_orientation) {
case SCREEN_LANDSCAPE: {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
@@ -576,16 +550,14 @@ public class GodotIO {
case SCREEN_SENSOR: {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
} break;
-
}
};
-
+
public void setEdit(GodotEditText _edit) {
edit = _edit;
}
- public void playVideo(String p_path)
- {
+ public void playVideo(String p_path) {
Uri filePath = Uri.parse(p_path);
mediaPlayer = new MediaPlayer();
@@ -594,11 +566,9 @@ public class GodotIO {
mediaPlayer.setDataSource(applicationContext, filePath);
mediaPlayer.prepare();
mediaPlayer.start();
+ } catch (IOException e) {
+ System.out.println("IOError while playing video");
}
- catch(IOException e)
- {
- System.out.println("IOError while playing video");
- }
}
public boolean isVideoPlaying() {
@@ -621,49 +591,47 @@ public class GodotIO {
}
}
-
- public static final int SYSTEM_DIR_DESKTOP=0;
- public static final int SYSTEM_DIR_DCIM=1;
- public static final int SYSTEM_DIR_DOCUMENTS=2;
- public static final int SYSTEM_DIR_DOWNLOADS=3;
- public static final int SYSTEM_DIR_MOVIES=4;
- public static final int SYSTEM_DIR_MUSIC=5;
- public static final int SYSTEM_DIR_PICTURES=6;
- public static final int SYSTEM_DIR_RINGTONES=7;
-
+ public static final int SYSTEM_DIR_DESKTOP = 0;
+ public static final int SYSTEM_DIR_DCIM = 1;
+ public static final int SYSTEM_DIR_DOCUMENTS = 2;
+ public static final int SYSTEM_DIR_DOWNLOADS = 3;
+ public static final int SYSTEM_DIR_MOVIES = 4;
+ public static final int SYSTEM_DIR_MUSIC = 5;
+ public static final int SYSTEM_DIR_PICTURES = 6;
+ public static final int SYSTEM_DIR_RINGTONES = 7;
public String getSystemDir(int idx) {
- String what="";
- switch(idx) {
+ String what = "";
+ switch (idx) {
case SYSTEM_DIR_DESKTOP: {
//what=Environment.DIRECTORY_DOCUMENTS;
- what=Environment.DIRECTORY_DOWNLOADS;
+ what = Environment.DIRECTORY_DOWNLOADS;
} break;
case SYSTEM_DIR_DCIM: {
- what=Environment.DIRECTORY_DCIM;
+ what = Environment.DIRECTORY_DCIM;
} break;
case SYSTEM_DIR_DOCUMENTS: {
- what=Environment.DIRECTORY_DOWNLOADS;
+ what = Environment.DIRECTORY_DOWNLOADS;
//what=Environment.DIRECTORY_DOCUMENTS;
} break;
case SYSTEM_DIR_DOWNLOADS: {
- what=Environment.DIRECTORY_DOWNLOADS;
+ what = Environment.DIRECTORY_DOWNLOADS;
} break;
case SYSTEM_DIR_MOVIES: {
- what=Environment.DIRECTORY_MOVIES;
+ what = Environment.DIRECTORY_MOVIES;
} break;
case SYSTEM_DIR_MUSIC: {
- what=Environment.DIRECTORY_MUSIC;
+ what = Environment.DIRECTORY_MUSIC;
} break;
case SYSTEM_DIR_PICTURES: {
- what=Environment.DIRECTORY_PICTURES;
+ what = Environment.DIRECTORY_PICTURES;
} break;
case SYSTEM_DIR_RINGTONES: {
- what=Environment.DIRECTORY_RINGTONES;
+ what = Environment.DIRECTORY_RINGTONES;
} break;
}
@@ -676,10 +644,9 @@ public class GodotIO {
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
- public static String unique_id="";
+ public static String unique_id = "";
public String getUniqueID() {
- return unique_id;
+ return unique_id;
}
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
index 6b84ad6555..873d30eb34 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java
@@ -33,43 +33,41 @@ package org.godotengine.godot;
public class GodotLib {
+ public static GodotIO io;
- public static GodotIO io;
+ static {
+ System.loadLibrary("godot_android");
+ }
- static {
- System.loadLibrary("godot_android");
- }
-
- /**
+ /**
* @param width the current view width
* @param height the current view height
*/
- public static native void initialize(Godot p_instance,boolean need_reload_hook,Object p_asset_manager, boolean use_apk_expansion);
- public static native void setup(String[] p_cmdline);
- public static native void resize(int width, int height,boolean reload);
- public static native void newcontext(boolean p_32_bits);
- public static native void back();
- public static native void step();
- public static native void touch(int what,int pointer,int howmany, int[] arr);
- public static native void accelerometer(float x, float y, float z);
- public static native void gravity(float x, float y, float z);
- public static native void magnetometer(float x, float y, float z);
- public static native void gyroscope(float x, float y, float z);
- public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
- public static native void joybutton(int p_device, int p_but, boolean p_pressed);
- public static native void joyaxis(int p_device, int p_axis, float p_value);
- public static native void joyhat(int p_device, int p_hat_x, int p_hat_y);
- public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
- public static native void focusin();
- public static native void focusout();
- public static native void audio();
- public static native void singleton(String p_name,Object p_object);
- public static native void method(String p_sname,String p_name,String p_ret,String[] p_params);
- public static native String getGlobal(String p_key);
+ public static native void initialize(Godot p_instance, boolean need_reload_hook, Object p_asset_manager, boolean use_apk_expansion);
+ public static native void setup(String[] p_cmdline);
+ public static native void resize(int width, int height, boolean reload);
+ public static native void newcontext(boolean p_32_bits);
+ public static native void back();
+ public static native void step();
+ public static native void touch(int what, int pointer, int howmany, int[] arr);
+ public static native void accelerometer(float x, float y, float z);
+ public static native void gravity(float x, float y, float z);
+ public static native void magnetometer(float x, float y, float z);
+ public static native void gyroscope(float x, float y, float z);
+ public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
+ public static native void joybutton(int p_device, int p_but, boolean p_pressed);
+ public static native void joyaxis(int p_device, int p_axis, float p_value);
+ public static native void joyhat(int p_device, int p_hat_x, int p_hat_y);
+ public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
+ public static native void focusin();
+ public static native void focusout();
+ public static native void audio();
+ public static native void singleton(String p_name, Object p_object);
+ public static native void method(String p_sname, String p_name, String p_ret, String[] p_params);
+ public static native String getGlobal(String p_key);
public static native void callobject(int p_ID, String p_method, Object[] p_params);
public static native void calldeferred(int p_ID, String p_method, Object[] p_params);
public static native void setVirtualKeyboardHeight(int p_height);
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
index 8fe79fdfc7..61d10ed9e4 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
@@ -40,7 +40,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-
public class GodotPaymentV3 extends Godot.SingletonBase {
private Godot activity;
@@ -67,8 +66,8 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
public GodotPaymentV3(Activity p_activity) {
- registerClass("GodotPayments", new String[]{"purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails"});
- activity = (Godot) p_activity;
+ registerClass("GodotPayments", new String[] { "purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails" });
+ activity = (Godot)p_activity;
mPaymentManager = activity.getPaymentsManager();
mPaymentManager.setBaseSingleton(this);
}
@@ -89,32 +88,32 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
}
public void callbackSuccess(String ticket, String signature, String sku) {
- GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[]{ticket, signature, sku});
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_success", new Object[] { ticket, signature, sku });
}
public void callbackSuccessProductMassConsumed(String ticket, String signature, String sku) {
Log.d(this.getClass().getName(), "callbackSuccessProductMassConsumed > " + ticket + "," + signature + "," + sku);
- GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[]{ticket, signature, sku});
+ GodotLib.calldeferred(purchaseCallbackId, "consume_success", new Object[] { ticket, signature, sku });
}
public void callbackSuccessNoUnconsumedPurchases() {
- GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[]{});
+ GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[] {});
}
public void callbackFailConsume() {
- GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[]{});
+ GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[] {});
}
public void callbackFail() {
- GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[]{});
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[] {});
}
public void callbackCancel() {
- GodotLib.calldeferred(purchaseCallbackId, "purchase_cancel", new Object[]{});
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_cancel", new Object[] {});
}
public void callbackAlreadyOwned(String sku) {
- GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[]{sku});
+ GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[] { sku });
}
public int getPurchaseCallbackId() {
@@ -161,7 +160,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
// callback for requestPurchased()
public void callbackPurchased(String receipt, String signature, String sku) {
- GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[]{receipt, signature, sku});
+ GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[] { receipt, signature, sku });
}
// consume item automatically after purchase. default is true.
@@ -210,10 +209,10 @@ public class GodotPaymentV3 extends Godot.SingletonBase {
}
public void completeSkuDetail() {
- GodotLib.calldeferred(purchaseCallbackId, "sku_details_complete", new Object[]{mSkuDetails});
+ GodotLib.calldeferred(purchaseCallbackId, "sku_details_complete", new Object[] { mSkuDetails });
}
public void errorSkuDetail(String errorMessage) {
- GodotLib.calldeferred(purchaseCallbackId, "sku_details_error", new Object[]{errorMessage});
+ GodotLib.calldeferred(purchaseCallbackId, "sku_details_error", new Object[] { errorMessage });
}
}
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index b807b952d4..b762aa021a 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -77,20 +77,19 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
private static Context ctx;
private static GodotIO io;
- private static boolean firsttime=true;
- private static boolean use_gl3=false;
- private static boolean use_32=false;
+ private static boolean firsttime = true;
+ private static boolean use_gl3 = false;
+ private static boolean use_32 = false;
private Godot activity;
-
private InputManagerCompat mInputManager;
- public GodotView(Context context,GodotIO p_io,boolean p_use_gl3, boolean p_use_32_bits, Godot p_activity) {
+ public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, Godot p_activity) {
super(context);
- ctx=context;
- io=p_io;
- use_gl3=p_use_gl3;
- use_32=p_use_32_bits;
+ ctx = context;
+ io = p_io;
+ use_gl3 = p_use_gl3;
+ use_32 = p_use_32_bits;
activity = p_activity;
@@ -101,14 +100,15 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
mInputManager = InputManagerCompat.Factory.getInputManager(this.getContext());
mInputManager.registerInputDeviceListener(this, null);
init(false, 16, 0);
- }
+ }
- public GodotView(Context context, boolean translucent, int depth, int stencil) {
+ public GodotView(Context context, boolean translucent, int depth, int stencil) {
super(context);
init(translucent, depth, stencil);
- }
+ }
- @Override public boolean onTouchEvent (MotionEvent event) {
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
return activity.gotTouchEvent(event);
};
@@ -196,16 +196,17 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
ArrayList<joystick> joy_devices = new ArrayList<joystick>();
private int find_joy_device(int device_id) {
- for (int i=0; i<joy_devices.size(); i++) {
+ for (int i = 0; i < joy_devices.size(); i++) {
if (joy_devices.get(i).device_id == device_id) {
- return i;
+ return i;
}
}
onInputDeviceAdded(device_id);
return joy_devices.size() - 1;
}
- @Override public void onInputDeviceAdded(int deviceId) {
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
joystick joy = new joystick();
joy.device_id = deviceId;
final int id = joy_devices.size();
@@ -219,8 +220,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
for (InputDevice.MotionRange range : ranges) {
if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
joy.hats.add(range);
- }
- else {
+ } else {
joy.axes.add(range);
}
}
@@ -231,9 +231,10 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
GodotLib.joyconnectionchanged(id, true, name);
}
});
- }
+ }
- @Override public void onInputDeviceRemoved(int deviceId) {
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
final int id = find_joy_device(deviceId);
joy_devices.remove(id);
queueEvent(new Runnable() {
@@ -244,10 +245,11 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
});
}
- @Override public void onInputDeviceChanged(int deviceId) {
-
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
}
- @Override public boolean onKeyUp(final int keyCode, KeyEvent event) {
+ @Override
+ public boolean onKeyUp(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
@@ -282,7 +284,8 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
return super.onKeyUp(keyCode, event);
};
- @Override public boolean onKeyDown(final int keyCode, KeyEvent event) {
+ @Override
+ public boolean onKeyDown(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
activity.onBackPressed();
@@ -326,7 +329,8 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
return super.onKeyDown(keyCode, event);
}
- @Override public boolean onGenericMotionEvent(MotionEvent event) {
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
@@ -335,7 +339,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
for (int i = 0; i < joy.axes.size(); i++) {
InputDevice.MotionRange range = joy.axes.get(i);
- final float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
+ final float value = (event.getAxisValue(range.getAxis()) - range.getMin()) / range.getRange() * 2.0f - 1.0f;
//Log.e(TAG, String.format("axis event: %d, value %f", i, value));
final int idx = i;
queueEvent(new Runnable() {
@@ -346,9 +350,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
});
}
- for (int i = 0; i < joy.hats.size(); i+=2) {
+ for (int i = 0; i < joy.hats.size(); i += 2) {
final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis()));
- final int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis()));
+ final int hatY = Math.round(event.getAxisValue(joy.hats.get(i + 1).getAxis()));
//Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY));
queueEvent(new Runnable() {
@Override
@@ -363,8 +367,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
return super.onGenericMotionEvent(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.
@@ -388,14 +391,14 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
*/
if (use_32) {
- setEGLConfigChooser( translucent ?
- new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(8, 8, 8, 8, 16, stencil)) :
- new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(5, 6, 5, 0, 16, stencil)) );
+ setEGLConfigChooser(translucent ?
+ new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(8, 8, 8, 8, 16, stencil)) :
+ new FallbackConfigChooser(8, 8, 8, 8, 24, stencil, new ConfigChooser(5, 6, 5, 0, 16, stencil)));
} else {
- setEGLConfigChooser( translucent ?
- new ConfigChooser(8, 8, 8, 8, 16, stencil) :
- new ConfigChooser(5, 6, 5, 0, 16, stencil) );
+ setEGLConfigChooser(translucent ?
+ new ConfigChooser(8, 8, 8, 8, 16, stencil) :
+ new ConfigChooser(5, 6, 5, 0, 16, stencil));
}
/* Set the renderer responsible for frame rendering */
@@ -403,33 +406,33 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
}
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_gl3)
- Log.w(TAG, "creating OpenGL ES 3.0 context :");
- else
- Log.w(TAG, "creating OpenGL ES 2.0 context :");
-
- checkEglError("Before eglCreateContext", egl);
- int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
- int[] attrib_list3 = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
- EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3?attrib_list3:attrib_list2);
- checkEglError("After eglCreateContext", egl);
- return context;
- }
+ private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+ if (use_gl3)
+ Log.w(TAG, "creating OpenGL ES 3.0 context :");
+ else
+ Log.w(TAG, "creating OpenGL ES 2.0 context :");
+
+ checkEglError("Before eglCreateContext", egl);
+ int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+ int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
+ EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
+ checkEglError("After eglCreateContext", egl);
+ return context;
+ }
- public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
- egl.eglDestroyContext(display, context);
+ public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+ egl.eglDestroyContext(display, context);
+ }
}
- }
- private static void checkEglError(String prompt, EGL10 egl) {
- int error;
- while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
- Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+ private static void checkEglError(String prompt, EGL10 egl) {
+ int error;
+ while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+ Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+ }
}
- }
- /* Fallback if 32bit View is not supported*/
+ /* Fallback if 32bit View is not supported*/
private static class FallbackConfigChooser extends ConfigChooser {
private ConfigChooser fallback;
@@ -438,17 +441,17 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
this.fallback = fallback;
}
- @Override
+ @Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
EGLConfig ec = super.chooseConfig(egl, display, configs);
if (ec == null) {
- Log.w(TAG, "Trying ConfigChooser fallback");
- ec = fallback.chooseConfig(egl, display, configs);
- use_32=false;
+ Log.w(TAG, "Trying ConfigChooser fallback");
+ ec = fallback.chooseConfig(egl, display, configs);
+ use_32 = false;
}
return ec;
- }
- }
+ }
+ }
private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
@@ -467,46 +470,46 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
*/
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
- };
+ {
+ 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_configAttribs3 =
- {
- 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, //apparently there is no EGL_OPENGL_ES3_BIT
- EGL10.EGL_NONE
- };
+ {
+ 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, //apparently there is no EGL_OPENGL_ES3_BIT
+ 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_gl3?s_configAttribs3:s_configAttribs2, null, 0, num_config);
+ egl.eglChooseConfig(display, use_gl3 ? s_configAttribs3 : s_configAttribs2, null, 0, num_config);
int numConfigs = num_config[0];
if (numConfigs <= 0) {
- throw new IllegalArgumentException("No configs match configSpec");
+ 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_gl3?s_configAttribs3:s_configAttribs2, configs, numConfigs, num_config);
+ egl.eglChooseConfig(display, use_gl3 ? s_configAttribs3 : s_configAttribs2, configs, numConfigs, num_config);
if (DEBUG) {
- printConfigs(egl, display, configs);
+ printConfigs(egl, display, configs);
}
/* Now return the "best" one
*/
@@ -514,54 +517,54 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
}
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;
+ 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;
}
private int findConfigAttrib(EGL10 egl, EGLDisplay display,
- EGLConfig config, int attribute, int defaultValue) {
+ EGLConfig config, int attribute, int defaultValue) {
if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
- return mValue[0];
+ return mValue[0];
}
return defaultValue;
}
private void printConfigs(EGL10 egl, EGLDisplay display,
- EGLConfig[] configs) {
+ 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]);
+ Log.w(TAG, String.format("Configuration %d:\n", i));
+ printConfig(egl, display, configs[i]);
}
}
private void printConfig(EGL10 egl, EGLDisplay display,
- EGLConfig config) {
+ EGLConfig config) {
int[] attributes = {
EGL10.EGL_BUFFER_SIZE,
EGL10.EGL_ALPHA_SIZE,
@@ -634,14 +637,15 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
};
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);
- }
+ 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)
+ ;
+ }
}
}
@@ -657,19 +661,18 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
private static class Renderer implements GLSurfaceView.Renderer {
-
public void onDrawFrame(GL10 gl) {
GodotLib.step();
- for(int i=0;i<Godot.singleton_count;i++) {
+ for (int i = 0; i < Godot.singleton_count; i++) {
Godot.singletons[i].onGLDrawFrame(gl);
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
- GodotLib.resize(width, height,!firsttime);
- firsttime=false;
- for(int i=0;i<Godot.singleton_count;i++) {
+ GodotLib.resize(width, height, !firsttime);
+ firsttime = false;
+ for (int i = 0; i < Godot.singleton_count; i++) {
Godot.singletons[i].onGLSurfaceChanged(gl, width, height);
}
}
diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java
index d8a3ac5591..9e062d89c6 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java
@@ -70,42 +70,37 @@ public class GodotEditText extends EditText {
super(context, attrs, defStyle);
this.initView();
}
-
+
protected void initView() {
- this.setPadding(0, 0, 0, 0);
+ this.setPadding(0, 0, 0, 0);
this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
-
+
sHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
switch (msg.what) {
- case HANDLER_OPEN_IME_KEYBOARD:
- {
- GodotEditText edit = (GodotEditText) msg.obj;
- String text = edit.mOriginText;
- if (edit.requestFocus())
- {
- edit.removeTextChangedListener(edit.mInputWrapper);
- edit.setText("");
- edit.append(text);
- edit.mInputWrapper.setOriginText(text);
- edit.addTextChangedListener(edit.mInputWrapper);
- final InputMethodManager imm = (InputMethodManager) mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.showSoftInput(edit, 0);
- }
+ case HANDLER_OPEN_IME_KEYBOARD: {
+ GodotEditText edit = (GodotEditText)msg.obj;
+ String text = edit.mOriginText;
+ if (edit.requestFocus()) {
+ edit.removeTextChangedListener(edit.mInputWrapper);
+ edit.setText("");
+ edit.append(text);
+ edit.mInputWrapper.setOriginText(text);
+ edit.addTextChangedListener(edit.mInputWrapper);
+ final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(edit, 0);
}
- break;
-
- case HANDLER_CLOSE_IME_KEYBOARD:
- {
- GodotEditText edit = (GodotEditText) msg.obj;
-
- edit.removeTextChangedListener(mInputWrapper);
- final InputMethodManager imm = (InputMethodManager) mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
- edit.mView.requestFocus();
- }
- break;
+ } break;
+
+ case HANDLER_CLOSE_IME_KEYBOARD: {
+ GodotEditText edit = (GodotEditText)msg.obj;
+
+ edit.removeTextChangedListener(mInputWrapper);
+ final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
+ edit.mView.requestFocus();
+ } break;
}
}
};
@@ -116,7 +111,7 @@ public class GodotEditText extends EditText {
// ===========================================================
public void setView(final GodotView view) {
this.mView = view;
- if(mInputWrapper == null)
+ if (mInputWrapper == null)
mInputWrapper = new GodotTextInputWrapper(mView, this);
this.setOnEditorActionListener(mInputWrapper);
view.requestFocus();
@@ -125,7 +120,7 @@ public class GodotEditText extends EditText {
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
- @Override
+ @Override
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
super.onKeyDown(keyCode, keyEvent);
@@ -142,7 +137,7 @@ public class GodotEditText extends EditText {
// ===========================================================
public void showKeyboard(String p_existing_text) {
this.mOriginText = p_existing_text;
-
+
final Message msg = new Message();
msg.what = HANDLER_OPEN_IME_KEYBOARD;
msg.obj = this;
@@ -155,7 +150,7 @@ public class GodotEditText extends EditText {
msg.obj = this;
sHandler.sendMessage(msg);
}
-
+
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index ac424ab9f8..8e34d9e9e7 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -67,7 +67,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
private boolean isFullScreenEdit() {
final TextView textField = this.mEdit;
- final InputMethodManager imm = (InputMethodManager) textField.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ final InputMethodManager imm = (InputMethodManager)textField.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return imm.isFullscreenMode();
}
@@ -81,7 +81,6 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
@Override
public void afterTextChanged(final Editable s) {
-
}
@Override
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
index 4615d2fbb5..0a876d2b7f 100644
--- a/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
+++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
@@ -23,118 +23,118 @@ import android.view.InputDevice;
import android.view.MotionEvent;
public interface InputManagerCompat {
- /**
- * Gets information about the input device with the specified id.
- *
- * @param id The device id
- * @return The input device or null if not found
- */
- public InputDevice getInputDevice(int id);
+ /**
+ * Gets information about the input device with the specified id.
+ *
+ * @param id The device id
+ * @return The input device or null if not found
+ */
+ public InputDevice getInputDevice(int id);
- /**
- * Gets the ids of all input devices in the system.
- *
- * @return The input device ids.
- */
- public int[] getInputDeviceIds();
+ /**
+ * Gets the ids of all input devices in the system.
+ *
+ * @return The input device ids.
+ */
+ public int[] getInputDeviceIds();
- /**
- * Registers an input device listener to receive notifications about when
- * input devices are added, removed or changed.
- *
- * @param listener The listener to register.
- * @param handler The handler on which the listener should be invoked, or
- * null if the listener should be invoked on the calling thread's
- * looper.
- */
- public void registerInputDeviceListener(InputManagerCompat.InputDeviceListener listener,
- Handler handler);
+ /**
+ * Registers an input device listener to receive notifications about when
+ * input devices are added, removed or changed.
+ *
+ * @param listener The listener to register.
+ * @param handler The handler on which the listener should be invoked, or
+ * null if the listener should be invoked on the calling thread's
+ * looper.
+ */
+ public void registerInputDeviceListener(InputManagerCompat.InputDeviceListener listener,
+ Handler handler);
- /**
- * Unregisters an input device listener.
- *
- * @param listener The listener to unregister.
- */
- public void unregisterInputDeviceListener(InputManagerCompat.InputDeviceListener listener);
+ /**
+ * Unregisters an input device listener.
+ *
+ * @param listener The listener to unregister.
+ */
+ public void unregisterInputDeviceListener(InputManagerCompat.InputDeviceListener listener);
- /*
- * The following three calls are to simulate V16 behavior on pre-Jellybean
- * devices. If you don't call them, your callback will never be called
- * pre-API 16.
- */
+ /*
+ * The following three calls are to simulate V16 behavior on pre-Jellybean
+ * devices. If you don't call them, your callback will never be called
+ * pre-API 16.
+ */
- /**
- * Pass the motion events to the InputManagerCompat. This is used to
- * optimize for polling for controllers. If you do not pass these events in,
- * polling will cause regular object creation.
- *
- * @param event the motion event from the app
- */
- public void onGenericMotionEvent(MotionEvent event);
+ /**
+ * Pass the motion events to the InputManagerCompat. This is used to
+ * optimize for polling for controllers. If you do not pass these events in,
+ * polling will cause regular object creation.
+ *
+ * @param event the motion event from the app
+ */
+ public void onGenericMotionEvent(MotionEvent event);
- /**
- * Tell the V9 input manager that it should stop polling for disconnected
- * devices. You can call this during onPause in your activity, although you
- * might want to call it whenever your game is not active (or whenever you
- * don't care about being notified of new input devices)
- */
- public void onPause();
+ /**
+ * Tell the V9 input manager that it should stop polling for disconnected
+ * devices. You can call this during onPause in your activity, although you
+ * might want to call it whenever your game is not active (or whenever you
+ * don't care about being notified of new input devices)
+ */
+ public void onPause();
- /**
- * Tell the V9 input manager that it should start polling for disconnected
- * devices. You can call this during onResume in your activity, although you
- * might want to call it less often (only when the gameplay is actually
- * active)
- */
- public void onResume();
+ /**
+ * Tell the V9 input manager that it should start polling for disconnected
+ * devices. You can call this during onResume in your activity, although you
+ * might want to call it less often (only when the gameplay is actually
+ * active)
+ */
+ public void onResume();
- public interface InputDeviceListener {
- /**
- * Called whenever the input manager detects that a device has been
- * added. This will only be called in the V9 version when a motion event
- * is detected.
- *
- * @param deviceId The id of the input device that was added.
- */
- void onInputDeviceAdded(int deviceId);
+ public interface InputDeviceListener {
+ /**
+ * Called whenever the input manager detects that a device has been
+ * added. This will only be called in the V9 version when a motion event
+ * is detected.
+ *
+ * @param deviceId The id of the input device that was added.
+ */
+ void onInputDeviceAdded(int deviceId);
- /**
- * Called whenever the properties of an input device have changed since
- * they were last queried. This will not be called for the V9 version of
- * the API.
- *
- * @param deviceId The id of the input device that changed.
- */
- void onInputDeviceChanged(int deviceId);
+ /**
+ * Called whenever the properties of an input device have changed since
+ * they were last queried. This will not be called for the V9 version of
+ * the API.
+ *
+ * @param deviceId The id of the input device that changed.
+ */
+ void onInputDeviceChanged(int deviceId);
- /**
- * Called whenever the input manager detects that a device has been
- * removed. For the V9 version, this can take some time depending on the
- * poll rate.
- *
- * @param deviceId The id of the input device that was removed.
- */
- void onInputDeviceRemoved(int deviceId);
- }
+ /**
+ * Called whenever the input manager detects that a device has been
+ * removed. For the V9 version, this can take some time depending on the
+ * poll rate.
+ *
+ * @param deviceId The id of the input device that was removed.
+ */
+ void onInputDeviceRemoved(int deviceId);
+ }
- /**
- * Use this to construct a compatible InputManager.
- */
- public static class Factory {
+ /**
+ * Use this to construct a compatible InputManager.
+ */
+ public static class Factory {
- /**
- * Constructs and returns a compatible InputManger
- *
- * @param context the Context that will be used to get the system
- * service from
- * @return a compatible implementation of InputManager
- */
- public static InputManagerCompat getInputManager(Context context) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- return new InputManagerV16(context);
- } else {
- return new InputManagerV9();
- }
- }
- }
+ /**
+ * Constructs and returns a compatible InputManger
+ *
+ * @param context the Context that will be used to get the system
+ * service from
+ * @return a compatible implementation of InputManager
+ */
+ public static InputManagerCompat getInputManager(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ return new InputManagerV16(context);
+ } else {
+ return new InputManagerV9();
+ }
+ }
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
index f05701f455..3b88609cc9 100644
--- a/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
+++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
@@ -30,78 +30,74 @@ import java.util.Map;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class InputManagerV16 implements InputManagerCompat {
- private final InputManager mInputManager;
- private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners;
-
- public InputManagerV16(Context context) {
- mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
- mListeners = new HashMap<InputManagerCompat.InputDeviceListener, V16InputDeviceListener>();
- }
-
- @Override
- public InputDevice getInputDevice(int id) {
- return mInputManager.getInputDevice(id);
- }
-
- @Override
- public int[] getInputDeviceIds() {
- return mInputManager.getInputDeviceIds();
- }
-
- static class V16InputDeviceListener implements InputManager.InputDeviceListener {
- final InputManagerCompat.InputDeviceListener mIDL;
-
- public V16InputDeviceListener(InputDeviceListener idl) {
- mIDL = idl;
- }
-
- @Override
- public void onInputDeviceAdded(int deviceId) {
- mIDL.onInputDeviceAdded(deviceId);
- }
-
- @Override
- public void onInputDeviceChanged(int deviceId) {
- mIDL.onInputDeviceChanged(deviceId);
- }
-
- @Override
- public void onInputDeviceRemoved(int deviceId) {
- mIDL.onInputDeviceRemoved(deviceId);
- }
-
- }
-
- @Override
- public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
- V16InputDeviceListener v16Listener = new V16InputDeviceListener(listener);
- mInputManager.registerInputDeviceListener(v16Listener, handler);
- mListeners.put(listener, v16Listener);
- }
-
- @Override
- public void unregisterInputDeviceListener(InputDeviceListener listener) {
- V16InputDeviceListener curListener = mListeners.remove(listener);
- if (null != curListener)
- {
- mInputManager.unregisterInputDeviceListener(curListener);
- }
-
- }
-
- @Override
- public void onGenericMotionEvent(MotionEvent event) {
- // unused in V16
- }
-
- @Override
- public void onPause() {
- // unused in V16
- }
-
- @Override
- public void onResume() {
- // unused in V16
- }
-
+ private final InputManager mInputManager;
+ private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners;
+
+ public InputManagerV16(Context context) {
+ mInputManager = (InputManager)context.getSystemService(Context.INPUT_SERVICE);
+ mListeners = new HashMap<InputManagerCompat.InputDeviceListener, V16InputDeviceListener>();
+ }
+
+ @Override
+ public InputDevice getInputDevice(int id) {
+ return mInputManager.getInputDevice(id);
+ }
+
+ @Override
+ public int[] getInputDeviceIds() {
+ return mInputManager.getInputDeviceIds();
+ }
+
+ static class V16InputDeviceListener implements InputManager.InputDeviceListener {
+ final InputManagerCompat.InputDeviceListener mIDL;
+
+ public V16InputDeviceListener(InputDeviceListener idl) {
+ mIDL = idl;
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ mIDL.onInputDeviceAdded(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ mIDL.onInputDeviceChanged(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ mIDL.onInputDeviceRemoved(deviceId);
+ }
+ }
+
+ @Override
+ public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
+ V16InputDeviceListener v16Listener = new V16InputDeviceListener(listener);
+ mInputManager.registerInputDeviceListener(v16Listener, handler);
+ mListeners.put(listener, v16Listener);
+ }
+
+ @Override
+ public void unregisterInputDeviceListener(InputDeviceListener listener) {
+ V16InputDeviceListener curListener = mListeners.remove(listener);
+ if (null != curListener) {
+ mInputManager.unregisterInputDeviceListener(curListener);
+ }
+ }
+
+ @Override
+ public void onGenericMotionEvent(MotionEvent event) {
+ // unused in V16
+ }
+
+ @Override
+ public void onPause() {
+ // unused in V16
+ }
+
+ @Override
+ public void onResume() {
+ // unused in V16
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java b/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
index 0334c00997..a1418c5899 100644
--- a/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
+++ b/platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
@@ -31,181 +31,179 @@ import java.util.Map;
import java.util.Queue;
public class InputManagerV9 implements InputManagerCompat {
- private static final String LOG_TAG = "InputManagerV9";
- private static final int MESSAGE_TEST_FOR_DISCONNECT = 101;
- private static final long CHECK_ELAPSED_TIME = 3000L;
-
- private static final int ON_DEVICE_ADDED = 0;
- private static final int ON_DEVICE_CHANGED = 1;
- private static final int ON_DEVICE_REMOVED = 2;
-
- private final SparseArray<long[]> mDevices;
- private final Map<InputDeviceListener, Handler> mListeners;
- private final Handler mDefaultHandler;
-
- private static class PollingMessageHandler extends Handler {
- private final WeakReference<InputManagerV9> mInputManager;
-
- PollingMessageHandler(InputManagerV9 im) {
- mInputManager = new WeakReference<InputManagerV9>(im);
- }
-
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case MESSAGE_TEST_FOR_DISCONNECT:
- InputManagerV9 imv = mInputManager.get();
- if (null != imv) {
- long time = SystemClock.elapsedRealtime();
- int size = imv.mDevices.size();
- for (int i = 0; i < size; i++) {
- long[] lastContact = imv.mDevices.valueAt(i);
- if (null != lastContact) {
- if (time - lastContact[0] > CHECK_ELAPSED_TIME) {
- // check to see if the device has been
- // disconnected
- int id = imv.mDevices.keyAt(i);
- if (null == InputDevice.getDevice(id)) {
- // disconnected!
- imv.notifyListeners(ON_DEVICE_REMOVED, id);
- imv.mDevices.remove(id);
- } else {
- lastContact[0] = time;
- }
- }
- }
- }
- sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT,
- CHECK_ELAPSED_TIME);
- }
- break;
- }
- }
-
- }
-
- public InputManagerV9() {
- mDevices = new SparseArray<long[]>();
- mListeners = new HashMap<InputDeviceListener, Handler>();
- mDefaultHandler = new PollingMessageHandler(this);
- // as a side-effect, populates our collection of watched
- // input devices
- getInputDeviceIds();
- }
-
- @Override
- public InputDevice getInputDevice(int id) {
- return InputDevice.getDevice(id);
- }
-
- @Override
- public int[] getInputDeviceIds() {
- // add any hitherto unknown devices to our
- // collection of watched input devices
- int[] activeDevices = InputDevice.getDeviceIds();
- long time = SystemClock.elapsedRealtime();
- for ( int id : activeDevices ) {
- long[] lastContact = mDevices.get(id);
- if ( null == lastContact ) {
- // we have a new device
- mDevices.put(id, new long[] { time });
- }
- }
- return activeDevices;
- }
-
- @Override
- public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
- mListeners.remove(listener);
- if (handler == null) {
- handler = mDefaultHandler;
- }
- mListeners.put(listener, handler);
- }
-
- @Override
- public void unregisterInputDeviceListener(InputDeviceListener listener) {
- mListeners.remove(listener);
- }
-
- private void notifyListeners(int why, int deviceId) {
- // the state of some device has changed
- if (!mListeners.isEmpty()) {
- // yes... this will cause an object to get created... hopefully
- // it won't happen very often
- for (InputDeviceListener listener : mListeners.keySet()) {
- Handler handler = mListeners.get(listener);
- DeviceEvent odc = DeviceEvent.getDeviceEvent(why, deviceId, listener);
- handler.post(odc);
- }
- }
- }
-
- private static class DeviceEvent implements Runnable {
- private int mMessageType;
- private int mId;
- private InputDeviceListener mListener;
- private static Queue<DeviceEvent> sEventQueue = new ArrayDeque<DeviceEvent>();
-
- private DeviceEvent() {
- }
-
- static DeviceEvent getDeviceEvent(int messageType, int id,
- InputDeviceListener listener) {
- DeviceEvent curChanged = sEventQueue.poll();
- if (null == curChanged) {
- curChanged = new DeviceEvent();
- }
- curChanged.mMessageType = messageType;
- curChanged.mId = id;
- curChanged.mListener = listener;
- return curChanged;
- }
-
- @Override
- public void run() {
- switch (mMessageType) {
- case ON_DEVICE_ADDED:
- mListener.onInputDeviceAdded(mId);
- break;
- case ON_DEVICE_CHANGED:
- mListener.onInputDeviceChanged(mId);
- break;
- case ON_DEVICE_REMOVED:
- mListener.onInputDeviceRemoved(mId);
- break;
- default:
- Log.e(LOG_TAG, "Unknown Message Type");
- break;
- }
- // dump this runnable back in the queue
- sEventQueue.offer(this);
- }
- }
-
- @Override
- public void onGenericMotionEvent(MotionEvent event) {
- // detect new devices
- int id = event.getDeviceId();
- long[] timeArray = mDevices.get(id);
- if (null == timeArray) {
- notifyListeners(ON_DEVICE_ADDED, id);
- timeArray = new long[1];
- mDevices.put(id, timeArray);
- }
- long time = SystemClock.elapsedRealtime();
- timeArray[0] = time;
- }
-
- @Override
- public void onPause() {
- mDefaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT);
- }
-
- @Override
- public void onResume() {
- mDefaultHandler.sendEmptyMessage(MESSAGE_TEST_FOR_DISCONNECT);
- }
-
+ private static final String LOG_TAG = "InputManagerV9";
+ private static final int MESSAGE_TEST_FOR_DISCONNECT = 101;
+ private static final long CHECK_ELAPSED_TIME = 3000L;
+
+ private static final int ON_DEVICE_ADDED = 0;
+ private static final int ON_DEVICE_CHANGED = 1;
+ private static final int ON_DEVICE_REMOVED = 2;
+
+ private final SparseArray<long[]> mDevices;
+ private final Map<InputDeviceListener, Handler> mListeners;
+ private final Handler mDefaultHandler;
+
+ private static class PollingMessageHandler extends Handler {
+ private final WeakReference<InputManagerV9> mInputManager;
+
+ PollingMessageHandler(InputManagerV9 im) {
+ mInputManager = new WeakReference<InputManagerV9>(im);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what) {
+ case MESSAGE_TEST_FOR_DISCONNECT:
+ InputManagerV9 imv = mInputManager.get();
+ if (null != imv) {
+ long time = SystemClock.elapsedRealtime();
+ int size = imv.mDevices.size();
+ for (int i = 0; i < size; i++) {
+ long[] lastContact = imv.mDevices.valueAt(i);
+ if (null != lastContact) {
+ if (time - lastContact[0] > CHECK_ELAPSED_TIME) {
+ // check to see if the device has been
+ // disconnected
+ int id = imv.mDevices.keyAt(i);
+ if (null == InputDevice.getDevice(id)) {
+ // disconnected!
+ imv.notifyListeners(ON_DEVICE_REMOVED, id);
+ imv.mDevices.remove(id);
+ } else {
+ lastContact[0] = time;
+ }
+ }
+ }
+ }
+ sendEmptyMessageDelayed(MESSAGE_TEST_FOR_DISCONNECT,
+ CHECK_ELAPSED_TIME);
+ }
+ break;
+ }
+ }
+ }
+
+ public InputManagerV9() {
+ mDevices = new SparseArray<long[]>();
+ mListeners = new HashMap<InputDeviceListener, Handler>();
+ mDefaultHandler = new PollingMessageHandler(this);
+ // as a side-effect, populates our collection of watched
+ // input devices
+ getInputDeviceIds();
+ }
+
+ @Override
+ public InputDevice getInputDevice(int id) {
+ return InputDevice.getDevice(id);
+ }
+
+ @Override
+ public int[] getInputDeviceIds() {
+ // add any hitherto unknown devices to our
+ // collection of watched input devices
+ int[] activeDevices = InputDevice.getDeviceIds();
+ long time = SystemClock.elapsedRealtime();
+ for (int id : activeDevices) {
+ long[] lastContact = mDevices.get(id);
+ if (null == lastContact) {
+ // we have a new device
+ mDevices.put(id, new long[] { time });
+ }
+ }
+ return activeDevices;
+ }
+
+ @Override
+ public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
+ mListeners.remove(listener);
+ if (handler == null) {
+ handler = mDefaultHandler;
+ }
+ mListeners.put(listener, handler);
+ }
+
+ @Override
+ public void unregisterInputDeviceListener(InputDeviceListener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void notifyListeners(int why, int deviceId) {
+ // the state of some device has changed
+ if (!mListeners.isEmpty()) {
+ // yes... this will cause an object to get created... hopefully
+ // it won't happen very often
+ for (InputDeviceListener listener : mListeners.keySet()) {
+ Handler handler = mListeners.get(listener);
+ DeviceEvent odc = DeviceEvent.getDeviceEvent(why, deviceId, listener);
+ handler.post(odc);
+ }
+ }
+ }
+
+ private static class DeviceEvent implements Runnable {
+ private int mMessageType;
+ private int mId;
+ private InputDeviceListener mListener;
+ private static Queue<DeviceEvent> sEventQueue = new ArrayDeque<DeviceEvent>();
+
+ private DeviceEvent() {
+ }
+
+ static DeviceEvent getDeviceEvent(int messageType, int id,
+ InputDeviceListener listener) {
+ DeviceEvent curChanged = sEventQueue.poll();
+ if (null == curChanged) {
+ curChanged = new DeviceEvent();
+ }
+ curChanged.mMessageType = messageType;
+ curChanged.mId = id;
+ curChanged.mListener = listener;
+ return curChanged;
+ }
+
+ @Override
+ public void run() {
+ switch (mMessageType) {
+ case ON_DEVICE_ADDED:
+ mListener.onInputDeviceAdded(mId);
+ break;
+ case ON_DEVICE_CHANGED:
+ mListener.onInputDeviceChanged(mId);
+ break;
+ case ON_DEVICE_REMOVED:
+ mListener.onInputDeviceRemoved(mId);
+ break;
+ default:
+ Log.e(LOG_TAG, "Unknown Message Type");
+ break;
+ }
+ // dump this runnable back in the queue
+ sEventQueue.offer(this);
+ }
+ }
+
+ @Override
+ public void onGenericMotionEvent(MotionEvent event) {
+ // detect new devices
+ int id = event.getDeviceId();
+ long[] timeArray = mDevices.get(id);
+ if (null == timeArray) {
+ notifyListeners(ON_DEVICE_ADDED, id);
+ timeArray = new long[1];
+ mDevices.put(id, timeArray);
+ }
+ long time = SystemClock.elapsedRealtime();
+ timeArray[0] = time;
+ }
+
+ @Override
+ public void onPause() {
+ mDefaultHandler.removeMessages(MESSAGE_TEST_FOR_DISCONNECT);
+ }
+
+ @Override
+ public void onResume() {
+ mDefaultHandler.sendEmptyMessage(MESSAGE_TEST_FOR_DISCONNECT);
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
index 8622f4ccff..d6f26e19b2 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
@@ -39,33 +39,32 @@ import android.util.Log;
abstract public class ConsumeTask {
private Context context;
-
+
private IInAppBillingService mService;
- public ConsumeTask(IInAppBillingService mService, Context context ){
+ public ConsumeTask(IInAppBillingService mService, Context context) {
this.context = context;
this.mService = mService;
}
-
- public void consume(final String sku){
+ public void consume(final String sku) {
//Log.d("XXX", "Consuming product " + sku);
PaymentsCache pc = new PaymentsCache(context);
Boolean isBlocked = pc.getConsumableFlag("block", sku);
String _token = pc.getConsumableValue("token", sku);
- //Log.d("XXX", "token " + _token);
- if(!isBlocked && _token == null){
+ //Log.d("XXX", "token " + _token);
+ if (!isBlocked && _token == null) {
//_token = "inapp:"+context.getPackageName()+":android.test.purchased";
//Log.d("XXX", "Consuming product " + sku + " with token " + _token);
- }else if(!isBlocked){
+ } else if (!isBlocked) {
//Log.d("XXX", "It is not blocked ¿?");
return;
- }else if(_token == null){
+ } else if (_token == null) {
//Log.d("XXX", "No token available");
this.error("No token for sku:" + sku);
return;
}
final String token = _token;
- new AsyncTask<String, String, String>(){
+ new AsyncTask<String, String, String>() {
@Override
protected String doInBackground(String... params) {
@@ -73,28 +72,27 @@ abstract public class ConsumeTask {
//Log.d("XXX", "Requesting to release item.");
int response = mService.consumePurchase(3, context.getPackageName(), token);
//Log.d("XXX", "release response code: " + response);
- if(response == 0 || response == 8){
+ if (response == 0 || response == 8) {
return null;
}
} catch (RemoteException e) {
return e.getMessage();
-
}
return "Some error";
}
-
- protected void onPostExecute(String param){
- if(param == null){
- success( new PaymentsCache(context).getConsumableValue("ticket", sku) );
- }else{
+
+ protected void onPostExecute(String param) {
+ if (param == null) {
+ success(new PaymentsCache(context).getConsumableValue("ticket", sku));
+ } else {
error(param);
}
}
-
- }.execute();
+
+ }
+ .execute();
}
-
+
abstract protected void success(String ticket);
abstract protected void error(String message);
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java
index 0afe35510c..31f6396738 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java
@@ -36,15 +36,12 @@ import android.os.AsyncTask;
import android.os.RemoteException;
import android.util.Log;
-abstract public class GenericConsumeTask extends AsyncTask<String, String, String>{
+abstract public class GenericConsumeTask extends AsyncTask<String, String, String> {
private Context context;
private IInAppBillingService mService;
-
-
-
- public GenericConsumeTask(Context context, IInAppBillingService mService, String sku, String receipt, String signature, String token){
+ public GenericConsumeTask(Context context, IInAppBillingService mService, String sku, String receipt, String signature, String token) {
this.context = context;
this.mService = mService;
this.sku = sku;
@@ -52,19 +49,19 @@ abstract public class GenericConsumeTask extends AsyncTask<String, String, Strin
this.signature = signature;
this.token = token;
}
-
+
private String sku;
private String receipt;
private String signature;
private String token;
-
+
@Override
protected String doInBackground(String... params) {
try {
//Log.d("godot", "Requesting to consume an item with token ." + token);
int response = mService.consumePurchase(3, context.getPackageName(), token);
//Log.d("godot", "consumePurchase response: " + response);
- if(response == 0 || response == 8){
+ if (response == 0 || response == 8) {
return null;
}
} catch (Exception e) {
@@ -72,11 +69,10 @@ abstract public class GenericConsumeTask extends AsyncTask<String, String, Strin
}
return null;
}
-
- protected void onPostExecute(String sarasa){
+
+ protected void onPostExecute(String sarasa) {
onSuccess(sku, receipt, signature, token);
}
-
- abstract public void onSuccess(String sku, String receipt, String signature, String token);
+ abstract public void onSuccess(String sku, String receipt, String signature, String token);
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
index 7318ae2fc6..80f53d16c8 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
@@ -50,28 +50,26 @@ import android.util.Log;
abstract public class HandlePurchaseTask {
private Activity context;
-
- public HandlePurchaseTask(Activity context ){
+
+ public HandlePurchaseTask(Activity context) {
this.context = context;
}
-
-
- public void handlePurchaseRequest(int resultCode, Intent data){
+
+ public void handlePurchaseRequest(int resultCode, Intent data) {
//Log.d("XXX", "Handling purchase response");
//int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
PaymentsCache pc = new PaymentsCache(context);
-
+
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
//Log.d("XXX", "Purchase data:" + purchaseData);
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
//Log.d("XXX", "Purchase signature:" + dataSignature);
-
+
if (resultCode == Activity.RESULT_OK) {
-
+
try {
//Log.d("SARLANGA", purchaseData);
-
-
+
JSONObject jo = new JSONObject(purchaseData);
//String sku = jo.getString("productId");
//alert("You have bought the " + sku + ". Excellent choice, aventurer!");
@@ -82,8 +80,8 @@ abstract public class HandlePurchaseTask {
//Integer state = jo.getInt("purchaseState");
String developerPayload = jo.getString("developerPayload");
String purchaseToken = jo.getString("purchaseToken");
-
- if(! pc.getConsumableValue("validation_hash", productId).equals(developerPayload) ) {
+
+ if (!pc.getConsumableValue("validation_hash", productId).equals(developerPayload)) {
error("Untrusted callback");
return;
}
@@ -92,13 +90,13 @@ abstract public class HandlePurchaseTask {
pc.setConsumableValue("ticket", productId, purchaseData);
pc.setConsumableFlag("block", productId, true);
pc.setConsumableValue("token", productId, purchaseToken);
-
+
success(productId, dataSignature, purchaseData);
return;
- } catch (JSONException e) {
+ } catch (JSONException e) {
error(e.getMessage());
}
- }else if( resultCode == Activity.RESULT_CANCELED){
+ } else if (resultCode == Activity.RESULT_CANCELED) {
canceled();
}
}
@@ -106,6 +104,4 @@ abstract public class HandlePurchaseTask {
abstract protected void success(String sku, String signature, String ticket);
abstract protected void error(String message);
abstract protected void canceled();
-
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java
index 69ac02e902..f9828ef77d 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java
@@ -34,41 +34,38 @@ import android.content.SharedPreferences;
import android.util.Log;
public class PaymentsCache {
-
+
public Context context;
- public PaymentsCache(Context context){
+ public PaymentsCache(Context context) {
this.context = context;
}
-
-
- public void setConsumableFlag(String set, String sku, Boolean flag){
- SharedPreferences sharedPref = context.getSharedPreferences("consumables_" + set, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedPref.edit();
- editor.putBoolean(sku, flag);
- editor.commit();
-}
- public boolean getConsumableFlag(String set, String sku){
- SharedPreferences sharedPref = context.getSharedPreferences(
- "consumables_" + set, Context.MODE_PRIVATE);
- return sharedPref.getBoolean(sku, false);
+ public void setConsumableFlag(String set, String sku, Boolean flag) {
+ SharedPreferences sharedPref = context.getSharedPreferences("consumables_" + set, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putBoolean(sku, flag);
+ editor.commit();
}
+ public boolean getConsumableFlag(String set, String sku) {
+ SharedPreferences sharedPref = context.getSharedPreferences(
+ "consumables_" + set, Context.MODE_PRIVATE);
+ return sharedPref.getBoolean(sku, false);
+ }
- public void setConsumableValue(String set, String sku, String value){
- SharedPreferences sharedPref = context.getSharedPreferences("consumables_" + set, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedPref.edit();
- editor.putString(sku, value);
+ public void setConsumableValue(String set, String sku, String value) {
+ 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();
+ editor.commit();
}
- public String getConsumableValue(String set, String sku){
- SharedPreferences sharedPref = context.getSharedPreferences(
- "consumables_" + set, Context.MODE_PRIVATE);
+ 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);
+ return sharedPref.getString(sku, null);
}
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
index b327265abb..71407566e2 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
@@ -106,7 +106,6 @@ public class PaymentsManager {
@Override
protected void error(String message) {
godotPaymentV3.callbackFail();
-
}
@Override
@@ -119,8 +118,8 @@ public class PaymentsManager {
godotPaymentV3.callbackAlreadyOwned(sku);
}
- }.purchase(sku, transactionId);
-
+ }
+ .purchase(sku, transactionId);
}
public void consumeUnconsumedPurchases() {
@@ -135,16 +134,15 @@ public class PaymentsManager {
protected void error(String message) {
Log.d("godot", "consumeUnconsumedPurchases :" + message);
godotPaymentV3.callbackFailConsume();
-
}
@Override
protected void notRequired() {
Log.d("godot", "callbackSuccessNoUnconsumedPurchases :");
godotPaymentV3.callbackSuccessNoUnconsumedPurchases();
-
}
- }.consumeItAll();
+ }
+ .consumeItAll();
}
public void requestPurchased() {
@@ -210,9 +208,9 @@ public class PaymentsManager {
@Override
protected void error(String message) {
godotPaymentV3.callbackFail();
-
}
- }.consume(sku);
+ }
+ .consume(sku);
}
}
@@ -225,7 +223,8 @@ public class PaymentsManager {
protected void canceled() {
godotPaymentV3.callbackCancel();
}
- }.handlePurchaseRequest(resultCode, data);
+ }
+ .handlePurchaseRequest(resultCode, data);
}
public void validatePurchase(String purchaseToken, final String sku) {
@@ -246,8 +245,8 @@ public class PaymentsManager {
protected void error(String message) {
godotPaymentV3.callbackFail();
}
- }.consume(sku);
-
+ }
+ .consume(sku);
}
@Override
@@ -259,7 +258,8 @@ public class PaymentsManager {
protected void canceled() {
godotPaymentV3.callbackCancel();
}
- }.validatePurchase(sku);
+ }
+ .validatePurchase(sku);
}
public void setAutoConsume(boolean autoConsume) {
@@ -278,7 +278,8 @@ public class PaymentsManager {
protected void error(String message) {
godotPaymentV3.callbackFailConsume();
}
- }.consume(sku);
+ }
+ .consume(sku);
}
// Workaround to bug where sometimes response codes come as Long instead of Integer
@@ -287,8 +288,10 @@ public class PaymentsManager {
if (o == null) {
//logDebug("Bundle with null response code, assuming OK (known issue)");
return BILLING_RESPONSE_RESULT_OK;
- } else if (o instanceof Integer) return ((Integer) o).intValue();
- else if (o instanceof Long) return (int) ((Long) o).longValue();
+ } else if (o instanceof Integer)
+ return ((Integer)o).intValue();
+ else if (o instanceof Long)
+ return (int)((Long)o).longValue();
else {
//logError("Unexpected type for bundle response code.");
//logError(o.getClass().getName());
@@ -304,25 +307,41 @@ public class PaymentsManager {
* It also includes the result code numerically.
*/
public static String getResponseDesc(int code) {
- String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/" +
- "3:Billing Unavailable/4:Item unavailable/" +
- "5:Developer Error/6:Error/7:Item Already Owned/" +
- "8:Item not owned").split("/");
- String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/" +
- "-1002:Bad response received/" +
- "-1003:Purchase signature verification failed/" +
- "-1004:Send intent failed/" +
- "-1005:User cancelled/" +
- "-1006:Unknown purchase response/" +
- "-1007:Missing token/" +
- "-1008:Unknown error/" +
- "-1009:Subscriptions not available/" +
- "-1010:Invalid consumption attempt").split("/");
+ String[] iab_msgs = ("0:OK/1:User Canceled/2:Unknown/"
+ +
+ "3:Billing Unavailable/4:Item unavailable/"
+ +
+ "5:Developer Error/6:Error/7:Item Already Owned/"
+ +
+ "8:Item not owned")
+ .split("/");
+ String[] iabhelper_msgs = ("0:OK/-1001:Remote exception during initialization/"
+ +
+ "-1002:Bad response received/"
+ +
+ "-1003:Purchase signature verification failed/"
+ +
+ "-1004:Send intent failed/"
+ +
+ "-1005:User cancelled/"
+ +
+ "-1006:Unknown purchase response/"
+ +
+ "-1007:Missing token/"
+ +
+ "-1008:Unknown error/"
+ +
+ "-1009:Subscriptions not available/"
+ +
+ "-1010:Invalid consumption attempt")
+ .split("/");
if (code <= -1000) {
int index = -1000 - code;
- if (index >= 0 && index < iabhelper_msgs.length) return iabhelper_msgs[index];
- else return String.valueOf(code) + ":Unknown IAB Helper Error";
+ if (index >= 0 && index < iabhelper_msgs.length)
+ return iabhelper_msgs[index];
+ else
+ return String.valueOf(code) + ":Unknown IAB Helper Error";
} else if (code < 0 || code >= iab_msgs.length)
return String.valueOf(code) + ":Unknown";
else
@@ -375,7 +394,7 @@ public class PaymentsManager {
ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
for (String thisResponse : responseList) {
- Log.d("godot", "response = "+thisResponse);
+ Log.d("godot", "response = " + thisResponse);
godotPaymentV3.addSkuDetail(thisResponse);
}
} catch (RemoteException e) {
@@ -385,7 +404,8 @@ public class PaymentsManager {
}
godotPaymentV3.completeSkuDetail();
}
- })).start();
+ }))
+ .start();
}
private GodotPaymentV3 godotPaymentV3;
@@ -393,5 +413,4 @@ public class PaymentsManager {
public void setBaseSingleton(GodotPaymentV3 godotPaymentV3) {
this.godotPaymentV3 = godotPaymentV3;
}
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java
index 6ecea0106c..e2f08345ad 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java
@@ -50,17 +50,16 @@ import android.util.Log;
abstract public class PurchaseTask {
private Activity context;
-
+
private IInAppBillingService mService;
- public PurchaseTask(IInAppBillingService mService, Activity context ){
+ public PurchaseTask(IInAppBillingService mService, Activity context) {
this.context = context;
this.mService = mService;
}
-
private boolean isLooping = false;
-
- public void purchase(final String sku, final String transactionId){
+
+ 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);
@@ -75,7 +74,7 @@ abstract public class PurchaseTask {
Bundle buyIntentBundle;
try {
- buyIntentBundle = mService.getBuyIntent(3, context.getApplicationContext().getPackageName(), sku, "inapp", hash );
+ buyIntentBundle = mService.getBuyIntent(3, context.getApplicationContext().getPackageName(), sku, "inapp", hash);
} catch (RemoteException e) {
//Log.d("XXX", "Error: " + e.getMessage());
error(e.getMessage());
@@ -83,50 +82,45 @@ abstract public class PurchaseTask {
}
Object rc = buyIntentBundle.get("RESPONSE_CODE");
int responseCode = 0;
- if(rc == null){
+ if (rc == null) {
responseCode = PaymentsManager.BILLING_RESPONSE_RESULT_OK;
- }else if( rc instanceof Integer){
+ } else if (rc instanceof Integer) {
responseCode = ((Integer)rc).intValue();
- }else if( rc instanceof Long){
+ } else if (rc instanceof Long) {
responseCode = (int)((Long)rc).longValue();
}
//Log.d("XXX", "Buy intent response code: " + responseCode);
- if(responseCode == 1 || responseCode == 3 || responseCode == 4){
+ if (responseCode == 1 || responseCode == 3 || responseCode == 4) {
canceled();
return;
}
- if(responseCode == 7){
+ if (responseCode == 7) {
alreadyOwned();
return;
}
-
-
+
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
pc.setConsumableValue("validation_hash", sku, hash);
try {
- if(context == null){
+ if (context == null) {
//Log.d("XXX", "No context!");
}
- if(pendingIntent == null){
+ if (pendingIntent == null) {
//Log.d("XXX", "No pending intent");
}
//Log.d("XXX", "Starting activity for purchase!");
context.startIntentSenderForResult(
pendingIntent.getIntentSender(),
- PaymentsManager.REQUEST_CODE_FOR_PURCHASE,
- new Intent(),
+ PaymentsManager.REQUEST_CODE_FOR_PURCHASE,
+ new Intent(),
Integer.valueOf(0), Integer.valueOf(0),
- Integer.valueOf(0));
+ Integer.valueOf(0));
} catch (SendIntentException e) {
error(e.getMessage());
}
-
-
-
}
abstract protected void error(String message);
abstract protected void canceled();
abstract protected void alreadyOwned();
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
index d831e45694..765906d0bb 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
@@ -48,69 +48,63 @@ abstract public class ReleaseAllConsumablesTask {
private Context context;
private IInAppBillingService mService;
-
- public ReleaseAllConsumablesTask(IInAppBillingService mService, Context context ){
+
+ public ReleaseAllConsumablesTask(IInAppBillingService mService, Context context) {
this.context = context;
this.mService = mService;
}
-
- public void consumeItAll(){
- try{
+ public void consumeItAll() {
+ try {
//Log.d("godot", "consumeItall for " + context.getPackageName());
- Bundle bundle = mService.getPurchases(3, context.getPackageName(), "inapp",null);
-
+ Bundle bundle = mService.getPurchases(3, context.getPackageName(), "inapp", null);
+
for (String key : bundle.keySet()) {
Object value = bundle.get(key);
//Log.d("godot", String.format("%s %s (%s)", key,
//value.toString(), value.getClass().getName()));
}
-
-
- if (bundle.getInt("RESPONSE_CODE") == 0){
+
+ if (bundle.getInt("RESPONSE_CODE") == 0) {
final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
-
- if (myPurchases == null || myPurchases.size() == 0){
+ if (myPurchases == null || myPurchases.size() == 0) {
//Log.d("godot", "No purchases!");
notRequired();
return;
}
-
-
+
//Log.d("godot", "# products to be consumed:" + myPurchases.size());
- for (int i=0;i<myPurchases.size();i++)
- {
-
- try{
+ for (int i = 0; i < myPurchases.size(); i++) {
+
+ try {
String receipt = myPurchases.get(i);
JSONObject inappPurchaseData = new JSONObject(receipt);
String sku = inappPurchaseData.getString("productId");
String token = inappPurchaseData.getString("purchaseToken");
String signature = mySignatures.get(i);
//Log.d("godot", "A punto de consumir un item con token:" + token + "\n" + receipt);
- new GenericConsumeTask(context, mService, sku, receipt,signature, token) {
-
+ new GenericConsumeTask(context, mService, sku, receipt, signature, token) {
+
@Override
public void onSuccess(String sku, String receipt, String signature, String token) {
ReleaseAllConsumablesTask.this.success(sku, receipt, signature, token);
}
- }.execute();
-
+ }
+ .execute();
+
} catch (JSONException e) {
}
}
-
}
- }catch(Exception e){
+ } catch (Exception e) {
Log.d("godot", "Error releasing products:" + e.getClass().getName() + ":" + e.getMessage());
}
}
-
+
abstract protected void success(String sku, String receipt, String signature, String token);
abstract protected void error(String message);
abstract protected void notRequired();
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
index 6e058c140c..3e62ef282a 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
@@ -55,22 +55,21 @@ abstract public class ValidateTask {
private Activity context;
private GodotPaymentV3 godotPaymentsV3;
- public ValidateTask(Activity context, GodotPaymentV3 godotPaymentsV3){
+ public ValidateTask(Activity context, GodotPaymentV3 godotPaymentsV3) {
this.context = context;
this.godotPaymentsV3 = godotPaymentsV3;
}
-
- public void validatePurchase(final String sku){
- new AsyncTask<String, String, String>(){
-
+ public void validatePurchase(final String sku) {
+ new AsyncTask<String, String, String>() {
+
private ProgressDialog dialog;
@Override
- protected void onPreExecute(){
+ protected void onPreExecute() {
dialog = ProgressDialog.show(context, null, "Please wait...");
}
-
+
@Override
protected String doInBackground(String... params) {
PaymentsCache pc = new PaymentsCache(context);
@@ -90,37 +89,34 @@ abstract public class ValidateTask {
//Log.d("XXX", "Validation response:\n"+jsonResponse);
return jsonResponse;
}
-
+
@Override
- protected void onPostExecute(String response){
- if(dialog != null){
+ protected void onPostExecute(String response) {
+ if (dialog != null) {
dialog.dismiss();
}
JSONObject j;
try {
j = new JSONObject(response);
- if(j.getString("status").equals("OK")){
+ if (j.getString("status").equals("OK")) {
success();
return;
- }else if(j.getString("status") != null){
+ } else if (j.getString("status") != null) {
error(j.getString("message"));
- }else{
+ } else {
error("Connection error");
}
} catch (JSONException e) {
error(e.getMessage());
- }catch (Exception e){
+ } catch (Exception e) {
error(e.getMessage());
}
-
-
}
-
- }.execute();
+
+ }
+ .execute();
}
abstract protected void success();
abstract protected void error(String message);
abstract protected void canceled();
-
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java
index 2fd66553f6..35e4e430a4 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java
@@ -34,34 +34,34 @@ import java.util.Random;
public class Crypt {
- public static String md5(String input){
- try {
- // Create MD5 Hash
- MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
- digest.update(input.getBytes());
- byte messageDigest[] = digest.digest();
-
- // Create Hex String
- StringBuffer hexString = new StringBuffer();
- for (int i=0; i<messageDigest.length; i++)
- hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
- return hexString.toString();
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "";
+ public static String md5(String input) {
+ try {
+ // Create MD5 Hash
+ MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
+ digest.update(input.getBytes());
+ byte messageDigest[] = digest.digest();
+
+ // Create Hex String
+ StringBuffer hexString = new StringBuffer();
+ for (int i = 0; i < messageDigest.length; i++)
+ hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
+ return hexString.toString();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
}
-
- public static String createRandomHash(){
+
+ public static String createRandomHash() {
return md5(Long.toString(createRandomLong()));
}
-
- public static long createAbsRandomLong(){
+
+ public static long createAbsRandomLong() {
return Math.abs(createRandomLong());
}
-
- public static long createRandomLong(){
+
+ public static long createRandomLong() {
Random r = new Random();
return r.nextLong();
}
diff --git a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
index 3fc8c48397..bfcf7e3b2a 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
@@ -42,30 +42,29 @@ import javax.net.ssl.TrustManagerFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
-
/**
*
* @author Luis Linietsky <luis.linietsky@gmail.com>
*/
public class CustomSSLSocketFactory extends SSLSocketFactory {
- SSLContext sslContext = SSLContext.getInstance("TLS");
+ SSLContext sslContext = SSLContext.getInstance("TLS");
- public CustomSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
- super(truststore);
+ public CustomSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+ super(truststore);
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
- tmf.init(truststore);
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
+ tmf.init(truststore);
- sslContext.init(null, tmf.getTrustManagers(), null);
- }
+ sslContext.init(null, tmf.getTrustManagers(), null);
+ }
- @Override
- public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
- return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
- }
+ @Override
+ public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
+ return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+ }
- @Override
- public Socket createSocket() throws IOException {
- return sslContext.getSocketFactory().createSocket();
- }
+ @Override
+ public Socket createSocket() throws IOException {
+ return sslContext.getSocketFactory().createSocket();
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java
index 0711f30b8b..81a642af9f 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java
@@ -63,7 +63,6 @@ import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
-
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
@@ -73,155 +72,154 @@ import android.util.Log;
* @author Luis Linietsky <luis.linietsky@gmail.com>
*/
public class HttpRequester {
-
+
private Context context;
- private static final int TTL = 600000; // 10 minutos
- private long cttl=0;
-
- public HttpRequester(){
+ private static final int TTL = 600000; // 10 minutos
+ private long cttl = 0;
+
+ public HttpRequester() {
//Log.d("XXX", "Creando http request sin contexto");
}
-
- public HttpRequester(Context context){
- this.context=context;
+
+ public HttpRequester(Context context) {
+ this.context = context;
//Log.d("XXX", "Creando http request con contexto");
}
-
- public String post(RequestParams params){
- HttpPost httppost = new HttpPost(params.getUrl());
- try {
+
+ public String post(RequestParams params) {
+ HttpPost httppost = new HttpPost(params.getUrl());
+ try {
httppost.setEntity(new UrlEncodedFormEntity(params.toPairsList()));
return request(httppost);
} catch (UnsupportedEncodingException e) {
return null;
}
}
-
- public String get(RequestParams params){
+
+ public String get(RequestParams params) {
String response = getResponseFromCache(params.getUrl());
- if(response == null){
+ if (response == null) {
//Log.d("XXX", "Cache miss!");
- HttpGet httpget = new HttpGet(params.getUrl());
- long timeInit = new Date().getTime();
- response = request(httpget);
- long delay = new Date().getTime() - timeInit;
- Log.d("com.app11tt.android.utils.HttpRequest::get(url)", "Url: " + params.getUrl() + " downloaded in " + String.format("%.03f", delay/1000.0f) + " seconds");
- if(response == null || response.length() == 0){
- response = "";
- }else{
- saveResponseIntoCache(params.getUrl(), response);
- }
+ HttpGet httpget = new HttpGet(params.getUrl());
+ long timeInit = new Date().getTime();
+ response = request(httpget);
+ long delay = new Date().getTime() - timeInit;
+ Log.d("com.app11tt.android.utils.HttpRequest::get(url)", "Url: " + params.getUrl() + " downloaded in " + String.format("%.03f", delay / 1000.0f) + " seconds");
+ if (response == null || response.length() == 0) {
+ response = "";
+ } else {
+ saveResponseIntoCache(params.getUrl(), response);
+ }
}
Log.d("XXX", "Req: " + params.getUrl());
Log.d("XXX", "Resp: " + response);
- return response;
+ return response;
}
-
- private String request(HttpUriRequest request){
+
+ private String request(HttpUriRequest request) {
//Log.d("XXX", "Haciendo request a: " + request.getURI() );
- Log.d("PPP", "Haciendo request a: " + request.getURI() );
+ Log.d("PPP", "Haciendo request a: " + request.getURI());
long init = new Date().getTime();
HttpClient httpclient = getNewHttpClient();
HttpParams httpParameters = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 0);
HttpConnectionParams.setSoTimeout(httpParameters, 0);
HttpConnectionParams.setTcpNoDelay(httpParameters, true);
- try {
- HttpResponse response = httpclient.execute(request);
- Log.d("PPP", "Fin de request (" + (new Date().getTime() - init) + ") a: " + request.getURI() );
+ try {
+ HttpResponse response = httpclient.execute(request);
+ Log.d("PPP", "Fin de request (" + (new Date().getTime() - init) + ") a: " + request.getURI());
//Log.d("XXX1", "Status:" + response.getStatusLine().toString());
- if(response.getStatusLine().getStatusCode() == 200){
- String strResponse = EntityUtils.toString(response.getEntity());
+ if (response.getStatusLine().getStatusCode() == 200) {
+ String strResponse = EntityUtils.toString(response.getEntity());
//Log.d("XXX2", strResponse);
- return strResponse;
- }else{
- Log.d("XXX3", "Response status code:" + response.getStatusLine().getStatusCode() + "\n" + EntityUtils.toString(response.getEntity()));
- return null;
- }
-
- } catch (ClientProtocolException e) {
- Log.d("XXX3", e.getMessage());
- } catch (IOException e) {
- Log.d("XXX4", e.getMessage());
- }
+ return strResponse;
+ } else {
+ Log.d("XXX3", "Response status code:" + response.getStatusLine().getStatusCode() + "\n" + EntityUtils.toString(response.getEntity()));
+ return null;
+ }
+
+ } catch (ClientProtocolException e) {
+ Log.d("XXX3", e.getMessage());
+ } catch (IOException e) {
+ Log.d("XXX4", e.getMessage());
+ }
return null;
}
-
+
private HttpClient getNewHttpClient() {
- try {
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(null, null);
+ try {
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
- SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
- sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
+ sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- HttpParams params = new BasicHttpParams();
- HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
- HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
- SchemeRegistry registry = new SchemeRegistry();
- registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- registry.register(new Scheme("https", sf, 443));
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme("https", sf, 443));
- ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
+ ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
- return new DefaultHttpClient(ccm, params);
- } catch (Exception e) {
- return new DefaultHttpClient();
- }
+ return new DefaultHttpClient(ccm, params);
+ } catch (Exception e) {
+ return new DefaultHttpClient();
+ }
}
-
+
private static String convertStreamToString(InputStream is) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- StringBuilder sb = new StringBuilder();
- String line = null;
- try {
- while ((line = reader.readLine()) != null) {
- sb.append((line + "\n"));
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return sb.toString();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ try {
+ while ((line = reader.readLine()) != null) {
+ sb.append((line + "\n"));
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return sb.toString();
}
- public void saveResponseIntoCache(String request, String response){
- if(context == null){
+ public void saveResponseIntoCache(String request, String response) {
+ if (context == null) {
//Log.d("XXX", "No context, cache failed!");
return;
}
- SharedPreferences sharedPref = context.getSharedPreferences("http_get_cache", Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sharedPref.edit();
- editor.putString("request_" + Crypt.md5(request), response);
- editor.putLong("request_" + Crypt.md5(request) + "_ttl", new Date().getTime() + getTtl());
- editor.commit();
+ SharedPreferences sharedPref = context.getSharedPreferences("http_get_cache", Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putString("request_" + Crypt.md5(request), response);
+ editor.putLong("request_" + Crypt.md5(request) + "_ttl", new Date().getTime() + getTtl());
+ editor.commit();
}
-
-
- public String getResponseFromCache(String request){
- if(context == null){
+
+ public String getResponseFromCache(String request) {
+ if (context == null) {
Log.d("XXX", "No context, cache miss");
return null;
}
- SharedPreferences sharedPref = context.getSharedPreferences( "http_get_cache", Context.MODE_PRIVATE);
- long ttl = getResponseTtl(request);
- if(ttl == 0l || (new Date().getTime() - ttl) > 0l){
- Log.d("XXX", "Cache invalid ttl:" + ttl + " vs now:" + new Date().getTime());
- return null;
- }
- return sharedPref.getString("request_" + Crypt.md5(request), null);
+ SharedPreferences sharedPref = context.getSharedPreferences("http_get_cache", Context.MODE_PRIVATE);
+ long ttl = getResponseTtl(request);
+ if (ttl == 0l || (new Date().getTime() - ttl) > 0l) {
+ Log.d("XXX", "Cache invalid ttl:" + ttl + " vs now:" + new Date().getTime());
+ return null;
+ }
+ return sharedPref.getString("request_" + Crypt.md5(request), null);
}
- public long getResponseTtl(String request){
- SharedPreferences sharedPref = context.getSharedPreferences(
- "http_get_cache", Context.MODE_PRIVATE);
- return sharedPref.getLong("request_" + Crypt.md5(request) + "_ttl", 0l);
+ public long getResponseTtl(String request) {
+ SharedPreferences sharedPref = context.getSharedPreferences(
+ "http_get_cache", Context.MODE_PRIVATE);
+ return sharedPref.getLong("request_" + Crypt.md5(request) + "_ttl", 0l);
}
public long getTtl() {
@@ -229,7 +227,6 @@ public class HttpRequester {
}
public void setTtl(long ttl) {
- this.cttl = (ttl*1000) + new Date().getTime();
+ this.cttl = (ttl * 1000) + new Date().getTime();
}
-
}
diff --git a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java
index ded11550bb..051fed5500 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java
@@ -43,33 +43,33 @@ import org.apache.http.message.BasicNameValuePair;
*/
public class RequestParams {
- private HashMap<String,String> params;
+ private HashMap<String, String> params;
private String url;
-
- public RequestParams(){
- params = new HashMap<String,String>();
+
+ public RequestParams() {
+ params = new HashMap<String, String>();
}
-
- public void put(String key, String value){
+
+ public void put(String key, String value) {
params.put(key, value);
}
-
- public String get(String key){
+
+ public String get(String key) {
return params.get(key);
}
-
- public void remove(Object key){
+
+ public void remove(Object key) {
params.remove(key);
}
-
- public boolean has(String key){
+
+ public boolean has(String key) {
return params.containsKey(key);
}
-
- public List<NameValuePair> toPairsList(){
- List<NameValuePair> fields = new ArrayList<NameValuePair>();
- for(String key : params.keySet()){
+ public List<NameValuePair> toPairsList() {
+ List<NameValuePair> fields = new ArrayList<NameValuePair>();
+
+ for (String key : params.keySet()) {
fields.add(new BasicNameValuePair(key, this.get(key)));
}
return fields;
@@ -82,6 +82,4 @@ public class RequestParams {
public void setUrl(String url) {
this.url = url;
}
-
-
}
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index 8606ea41a0..892e64cdfc 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -59,7 +59,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
r_error.argument = pc;
continue;
}
- uint32_t *ptypes = E->get().param_types.ptr();
+ uint32_t *ptypes = E->get().param_types.ptrw();
bool valid = true;
for (int i = 0; i < pc; i++) {
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 90144d9b4d..40dfe6d909 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -647,7 +647,7 @@ static int _open_uri(const String &p_uri) {
return env->CallIntMethod(godot_io, _openURI, jStr);
}
-static String _get_data_dir() {
+static String _get_user_data_dir() {
JNIEnv *env = ThreadAndroid::get_env();
jstring s = (jstring)env->CallObjectMethod(godot_io, _getDataDir);
@@ -825,7 +825,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
AudioDriverAndroid::setup(gob);
}
- os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion);
+ os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion);
os_android->set_need_reload_hooks(p_need_reload_hook);
char wd[500];
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 2578bd6d96..b575f15559 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -114,15 +114,6 @@ void OS_Android::initialize_core() {
#endif
}
-void OS_Android::initialize_logger() {
- Vector<Logger *> loggers;
- loggers.push_back(memnew(AndroidLogger));
- // FIXME: Reenable once we figure out how to get this properly in user://
- // instead of littering the user's working dirs (res:// + pwd) with log files (GH-12277)
- //loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
ERR_FAIL_COND(!p_gl_extensions);
@@ -612,13 +603,13 @@ void OS_Android::set_need_reload_hooks(bool p_needs_them) {
use_reload_hooks = p_needs_them;
}
-String OS_Android::get_data_dir() const {
+String OS_Android::get_user_data_dir() const {
if (data_dir_cache != String())
return data_dir_cache;
- if (get_data_dir_func) {
- String data_dir = get_data_dir_func();
+ if (get_user_data_dir_func) {
+ String data_dir = get_user_data_dir_func();
//store current dir
char real_current_dir_name[2048];
@@ -641,7 +632,6 @@ String OS_Android::get_data_dir() const {
}
return ".";
- //return Engine::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir");
}
void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) {
@@ -706,10 +696,27 @@ String OS_Android::get_joy_guid(int p_device) const {
}
bool OS_Android::_check_internal_feature_support(const String &p_feature) {
- return p_feature == "mobile" || p_feature == "etc" || p_feature == "etc2"; //TODO support etc2 only if GLES3 driver is selected
+ if (p_feature == "mobile" || p_feature == "etc" || p_feature == "etc2") {
+ //TODO support etc2 only if GLES3 driver is selected
+ return true;
+ }
+#if defined(__aarch64__)
+ if (p_feature == "arm64-v8a") {
+ return true;
+ }
+#elif defined(__ARM_ARCH_7A__)
+ if (p_feature == "armeabi-v7a" || p_feature == "armeabi") {
+ return true;
+ }
+#elif defined(__arm__)
+ if (p_feature == "armeabi") {
+ return true;
+ }
+#endif
+ return false;
}
-OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) {
+OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) {
use_apk_expansion = p_use_apk_expansion;
default_videomode.width = 800;
@@ -725,7 +732,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
use_gl2 = false;
open_uri_func = p_open_uri_func;
- get_data_dir_func = p_get_data_dir_func;
+ get_user_data_dir_func = p_get_user_data_dir_func;
get_locale_func = p_get_locale_func;
get_model_func = p_get_model_func;
get_screen_dpi_func = p_get_screen_dpi_func;
@@ -746,7 +753,9 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
alert_func = p_alert_func;
use_reload_hooks = false;
- _set_logger(memnew(AndroidLogger));
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(AndroidLogger));
+ _set_logger(memnew(CompositeLogger(loggers)));
}
OS_Android::~OS_Android() {
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 750afa7a14..3b7f55096e 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -48,7 +48,7 @@
typedef void (*GFXInitFunc)(void *ud, bool gl2);
typedef int (*OpenURIFunc)(const String &);
-typedef String (*GetDataDirFunc)();
+typedef String (*GetUserDataDirFunc)();
typedef String (*GetLocaleFunc)();
typedef String (*GetModelFunc)();
typedef int (*GetScreenDPIFunc)();
@@ -116,7 +116,7 @@ private:
MainLoop *main_loop;
OpenURIFunc open_uri_func;
- GetDataDirFunc get_data_dir_func;
+ GetUserDataDirFunc get_user_data_dir_func;
GetLocaleFunc get_locale_func;
GetModelFunc get_model_func;
GetScreenDPIFunc get_screen_dpi_func;
@@ -144,7 +144,6 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -208,7 +207,7 @@ public:
virtual void set_screen_orientation(ScreenOrientation p_orientation);
virtual Error shell_open(String p_uri);
- virtual String get_data_dir() const;
+ virtual String get_user_data_dir() const;
virtual String get_resource_dir() const;
virtual String get_locale() const;
virtual String get_model_name() const;
@@ -237,7 +236,7 @@ public:
void joy_connection_changed(int p_device, bool p_connected, String p_name);
virtual bool _check_internal_feature_support(const String &p_feature);
- OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion);
+ OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion);
~OS_Android();
};
diff --git a/platform/android/power_android.cpp b/platform/android/power_android.cpp
index 48c9377a5a..54fb435b62 100644
--- a/platform/android/power_android.cpp
+++ b/platform/android/power_android.cpp
@@ -245,8 +245,10 @@ int power_android::get_power_percent_left() {
}
}
-power_android::power_android()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+power_android::power_android() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
power_android::~power_android() {
diff --git a/platform/haiku/SCsub b/platform/haiku/SCsub
index d0c244a194..592f56bbbf 100644
--- a/platform/haiku/SCsub
+++ b/platform/haiku/SCsub
@@ -12,7 +12,7 @@ common_haiku = [
'audio_driver_media_kit.cpp'
]
-target = env.Program(
+target = env.add_program(
'#bin/godot',
['godot_haiku.cpp'] + common_haiku
)
diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py
index 50f9783dd2..7c62654ef6 100644
--- a/platform/haiku/detect.py
+++ b/platform/haiku/detect.py
@@ -67,7 +67,7 @@ def configure(env):
## Flags
env.Append(CPPPATH=['#platform/haiku'])
- env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
+ env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED', '-DGLES_OVER_GL'])
env.Append(CPPFLAGS=['-DMEDIA_KIT_ENABLED'])
# env.Append(CCFLAGS=['-DFREETYPE_ENABLED'])
env.Append(CPPFLAGS=['-DPTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np
diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp
index d23b9e27d8..e2649b15a4 100644
--- a/platform/haiku/haiku_application.cpp
+++ b/platform/haiku/haiku_application.cpp
@@ -29,6 +29,6 @@
/*************************************************************************/
#include "haiku_application.h"
-HaikuApplication::HaikuApplication()
- : BApplication("application/x-vnd.godot") {
+HaikuApplication::HaikuApplication() :
+ BApplication("application/x-vnd.godot") {
}
diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp
index 24a8a4b17b..aa25064ccb 100644
--- a/platform/haiku/haiku_direct_window.cpp
+++ b/platform/haiku/haiku_direct_window.cpp
@@ -34,8 +34,8 @@
#include "main/main.h"
#include "os/keyboard.h"
-HaikuDirectWindow::HaikuDirectWindow(BRect p_frame)
- : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) {
+HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) :
+ BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) {
last_mouse_pos_valid = false;
last_buttons_state = 0;
last_button_mask = 0;
diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp
index d898bd1a5d..bb9c439e94 100644
--- a/platform/haiku/haiku_gl_view.cpp
+++ b/platform/haiku/haiku_gl_view.cpp
@@ -30,8 +30,8 @@
#include "haiku_gl_view.h"
#include "main/main.h"
-HaikuGLView::HaikuGLView(BRect frame, uint32 type)
- : BGLView(frame, "GodotGLView", B_FOLLOW_ALL_SIDES, 0, type) {
+HaikuGLView::HaikuGLView(BRect frame, uint32 type) :
+ BGLView(frame, "GodotGLView", B_FOLLOW_ALL_SIDES, 0, type) {
}
void HaikuGLView::AttachedToWindow(void) {
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 0c34e39655..f7196755af 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -76,7 +76,7 @@ int OS_Haiku::get_video_driver_count() const {
}
const char *OS_Haiku::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ return "GLES3";
}
void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
@@ -105,8 +105,11 @@ void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_
context_gl = memnew(ContextGL_Haiku(window));
context_gl->initialize();
context_gl->make_current();
+ context_gl->set_use_vsync(current_video_mode.use_vsync);
+
+ /* Port to GLES 3 rasterizer */
+ //rasterizer = memnew(RasterizerGLES2);
- rasterizer = memnew(RasterizerGLES2);
#endif
visual_server = memnew(VisualServerRaster(rasterizer));
@@ -314,3 +317,36 @@ bool OS_Haiku::_check_internal_feature_support(const String &p_feature) {
return p_feature == "pc" || p_feature == "s3tc";
}
+
+String OS_Haiku::get_config_path() const {
+
+ if (has_environment("XDG_CONFIG_HOME")) {
+ return get_environment("XDG_CONFIG_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".config");
+ } else {
+ return ".";
+ }
+}
+
+String OS_Haiku::get_data_path() const {
+
+ if (has_environment("XDG_DATA_HOME")) {
+ return get_environment("XDG_DATA_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".local/share");
+ } else {
+ return get_config_path();
+ }
+}
+
+String OS_Haiku::get_cache_path() const {
+
+ if (has_environment("XDG_CACHE_HOME")) {
+ return get_environment("XDG_CACHE_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".cache");
+ } else {
+ return get_config_path();
+ }
+}
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index 86148f1fb4..4ee54fb48d 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -117,6 +117,10 @@ public:
virtual int get_power_percent_left();
virtual bool _check_internal_feature_support(const String &p_feature);
+
+ virtual String get_config_path() const;
+ virtual String get_data_path() const;
+ virtual String get_cache_path() const;
};
#endif
diff --git a/platform/haiku/power_haiku.cpp b/platform/haiku/power_haiku.cpp
index 8718b317a3..73d60e9fec 100644
--- a/platform/haiku/power_haiku.cpp
+++ b/platform/haiku/power_haiku.cpp
@@ -64,8 +64,10 @@ int PowerX11::get_power_percent_left() {
}
}
-PowerHaiku::PowerHaiku()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerHaiku::PowerHaiku() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
PowerHaiku::~PowerHaiku() {
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 61798c5f87..6b5f30dc41 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -3,7 +3,7 @@
Import('env')
iphone_lib = [
-
+ 'godot_iphone.cpp',
'os_iphone.cpp',
'sem_iphone.cpp',
'gl_view.mm',
@@ -17,10 +17,10 @@ iphone_lib = [
]
env_ios = env.Clone()
+ios_lib = env_ios.add_library('iphone', iphone_lib)
-obj = env_ios.Object('godot_iphone.cpp')
+def combine_libs(target=None, source=None, env=None):
+ lib_path = target[0].srcnode().abspath
+ env.Execute('$IPHONEPATH/usr/bin/libtool -static -o "' + lib_path + '" ' + ' '.join([('"' + lib.srcnode().abspath + '"') for lib in source]))
-prog = None
-prog = env_ios.Program('#bin/godot', [obj] + iphone_lib)
-action = "$IPHONEPATH/usr/bin/dsymutil " + File(prog)[0].path + " -o " + File(prog)[0].path + ".dSYM"
-env.AddPostAction(prog, action)
+combine_command = env_ios.Command('#bin/libgodot' + env_ios['LIBSUFFIX'], [ios_lib] + env_ios['LIBS'], combine_libs)
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index 8f2893e69e..111cdce2de 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -35,21 +35,6 @@
#include "main/main.h"
#include "os_iphone.h"
-#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
-#include "modules/FacebookScorer_ios/FacebookScorer.h"
-#endif
-
-#ifdef MODULE_GAME_ANALYTICS_ENABLED
-#import "modules/game_analytics/ios/MobileAppTracker.framework/Headers/MobileAppTracker.h"
-//#import "modules/game_analytics/ios/MobileAppTracker.h"
-#import <AdSupport/AdSupport.h>
-#endif
-
-#ifdef MODULE_PARSE_ENABLED
-#import "FBSDKCoreKit/FBSDKCoreKit.h"
-#import <Parse/Parse.h>
-#endif
-
#import "GameController/GameController.h"
#define kFilteringFactor 0.1
@@ -418,11 +403,7 @@ static int frame_count = 0;
OSIPhone::get_singleton()->set_unique_id(String::utf8([uuid UTF8String]));
}; break;
- /*
- case 1: {
- ++frame_count;
- }; break;
-*/
+
case 1: {
Main::setup2();
@@ -453,11 +434,7 @@ static int frame_count = 0;
}
}; break;
- /*
- case 3: {
- ++frame_count;
- }; break;
-*/
+
case 2: {
Main::start();
@@ -558,15 +535,11 @@ static int frame_count = 0;
};
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
-
- printf("****************** did receive memory warning!\n");
OS::get_singleton()->get_main_loop()->notification(
MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
};
-- (void)applicationDidFinishLaunching:(UIApplication *)application {
-
- printf("**************** app delegate init\n");
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect rect = [[UIScreen mainScreen] bounds];
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
@@ -603,7 +576,7 @@ static int frame_count = 0;
if (err != 0) {
// bail, things did not go very well for us, should probably output a message on screen with our error code...
exit(0);
- return;
+ return FALSE;
};
view_controller = [[ViewController alloc] init];
@@ -641,42 +614,10 @@ static int frame_count = 0;
// prevent to stop music in another background app
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
-#ifdef MODULE_GAME_ANALYTICS_ENABLED
- printf("********************* didFinishLaunchingWithOptions\n");
- if (!ProjectSettings::get_singleton()->has("mobileapptracker/advertiser_id")) {
- return;
- }
- if (!ProjectSettings::get_singleton()->has("mobileapptracker/conversion_key")) {
- return;
- }
-
- String adid = GLOBAL_DEF("mobileapptracker/advertiser_id", "");
- String convkey = GLOBAL_DEF("mobileapptracker/conversion_key", "");
-
- NSString *advertiser_id =
- [NSString stringWithUTF8String:adid.utf8().get_data()];
- NSString *conversion_key =
- [NSString stringWithUTF8String:convkey.utf8().get_data()];
-
- // Account Configuration info - must be set
- [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id
- MATConversionKey:conversion_key];
-
- // Used to pass us the IFA, enables highly accurate 1-to-1 attribution.
- // Required for many advertising networks.
- [MobileAppTracker
- setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager]
- advertisingIdentifier]
- advertisingTrackingEnabled:[[ASIdentifierManager sharedManager]
- isAdvertisingTrackingEnabled]];
-
-#endif
+ return TRUE;
};
- (void)applicationWillTerminate:(UIApplication *)application {
-
- printf("********************* will terminate\n");
-
[self deinitGameControllers];
if (motionInitialised) {
@@ -691,7 +632,6 @@ static int frame_count = 0;
};
- (void)applicationDidEnterBackground:(UIApplication *)application {
- printf("********************* did enter background\n");
///@TODO maybe add pause motionManager? and where would we unpause it?
if (OS::get_singleton()->get_main_loop())
@@ -705,24 +645,17 @@ static int frame_count = 0;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
- printf("********************* did enter foreground\n");
// OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
[view_controller.view startAnimation];
}
- (void)applicationWillResignActive:(UIApplication *)application {
- printf("********************* will resign active\n");
// OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
[view_controller.view
stopAnimation]; // FIXME: pause seems to be recommended elsewhere
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
- printf("********************* did become active\n");
-#ifdef MODULE_GAME_ANALYTICS_ENABLED
- printf("********************* mobile app tracker found\n");
- [MobileAppTracker measureSession];
-#endif
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(
MainLoop::NOTIFICATION_WM_FOCUS_IN);
@@ -738,65 +671,6 @@ static int frame_count = 0;
AudioDriverCoreAudio::get_singleton()->start();
}
-- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
-#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
- return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
-#else
- return false;
-#endif
-}
-
-// For 4.2+ support
-- (BOOL)application:(UIApplication *)application
- openURL:(NSURL *)url
- sourceApplication:(NSString *)sourceApplication
- annotation:(id)annotation {
-#ifdef MODULE_PARSE_ENABLED
- NSLog(@"Handling application openURL");
- return
- [[FBSDKApplicationDelegate sharedInstance] application:application
- openURL:url
- sourceApplication:sourceApplication
- annotation:annotation];
-#endif
-
-#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
- return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
-#else
- return false;
-#endif
-}
-
-- (void)application:(UIApplication *)application
- didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
-#ifdef MODULE_PARSE_ENABLED
- // Store the deviceToken in the current installation and save it to Parse.
- PFInstallation *currentInstallation = [PFInstallation currentInstallation];
- // NSString* token = [[NSString alloc] initWithData:deviceToken
- // encoding:NSUTF8StringEncoding];
- NSLog(@"Device Token : %@ ", deviceToken);
- [currentInstallation setDeviceTokenFromData:deviceToken];
- [currentInstallation saveInBackground];
-#endif
-}
-
-- (void)application:(UIApplication *)application
- didReceiveRemoteNotification:(NSDictionary *)userInfo {
-#ifdef MODULE_PARSE_ENABLED
- [PFPush handlePush:userInfo];
- NSDictionary *aps =
- [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-
- NSLog(@"Push Notification Payload (app active) %@", aps);
- [defaults setObject:aps forKey:@"notificationInfo"];
- [defaults synchronize];
- if (application.applicationState == UIApplicationStateInactive) {
- [PFAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];
- }
-#endif
-}
-
- (void)dealloc {
[window release];
[super dealloc];
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index d426b478bf..25674c2b47 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -61,10 +61,13 @@ def configure(env):
env.Append(LINKFLAGS=['-flto'])
## Architecture
+ if env["ios_sim"] and not ("arch" in env):
+ env["arch"] = "x86"
- if env["ios_sim"] or env["arch"] == "x86": # i386, simulator
- env["arch"] = "x86"
+ if env["arch"] == "x86": # i386, simulator
env["bits"] = "32"
+ elif env["arch"] == "x86_64":
+ env["bits"] = "64"
elif (env["arch"] == "arm" or env["arch"] == "arm32" or env["arch"] == "armv7" or env["bits"] == "32"): # arm
env["arch"] = "arm"
env["bits"] = "32"
@@ -95,10 +98,11 @@ def configure(env):
## Compile flags
- if (env["arch"] == "x86"):
+ if (env["arch"] == "x86" or env["arch"] == "x86_64"):
env['IPHONEPLATFORM'] = 'iPhoneSimulator'
- env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
- env.Append(CCFLAGS='-arch i386 -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -D__IPHONE_OS_VERSION_MIN_REQUIRED=40100 -isysroot $IPHONESDK -mios-simulator-version-min=4.3 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"'.split())
+ env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
+ arch_flag = "i386" if env["arch"] == "x86" else env["arch"]
+ env.Append(CCFLAGS=('-arch ' + arch_flag + ' -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=9.0 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"').split())
elif (env["arch"] == "arm"):
env.Append(CCFLAGS='-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=9.0 -MMD -MT dependencies'.split())
elif (env["arch"] == "arm64"):
@@ -113,8 +117,9 @@ def configure(env):
## Link flags
- if (env["arch"] == "x86"):
- env.Append(LINKFLAGS=['-arch', 'i386', '-mios-simulator-version-min=4.3',
+ if (env["arch"] == "x86" or env["arch"] == "x86_64"):
+ arch_flag = "i386" if env["arch"] == "x86" else env["arch"]
+ env.Append(LINKFLAGS=['-arch', arch_flag, '-mios-simulator-version-min=9.0',
'-isysroot', '$IPHONESDK',
'-Xlinker',
'-objc_abi_version',
@@ -163,7 +168,7 @@ def configure(env):
env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate'
env.Append(CPPPATH=['#platform/iphone'])
- env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DMPC_FIXED_POINT', '-DCOREAUDIO_ENABLED'])
+ env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DMPC_FIXED_POINT', '-DCOREAUDIO_ENABLED'])
# TODO: Move that to opus module's config
if 'module_opus_enabled' in env and env['module_opus_enabled']:
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 0507ef19d6..9ea8d58db0 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -37,7 +37,7 @@
#include "io/zip_io.h"
#include "os/file_access.h"
#include "os/os.h"
-#include "platform/osx/logo.gen.h"
+#include "platform/iphone/logo.gen.h"
#include "project_settings.h"
#include "string.h"
#include "version.h"
@@ -56,11 +56,49 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata);
static Error _codesign(String p_file, void *p_userdata);
- void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const String &p_name, const String &p_binary, bool p_debug);
- static Error _export_dylibs(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
+ struct IOSConfigData {
+ String pkg_name;
+ String binary_name;
+ String plist_content;
+ String architectures;
+ String linker_flags;
+ String cpp_code;
+ };
+
+ struct ExportArchitecture {
+ String name;
+ bool is_default;
+
+ ExportArchitecture() :
+ name(""),
+ is_default(false) {
+ }
+
+ ExportArchitecture(String p_name, bool p_is_default) {
+ name = p_name;
+ is_default = p_is_default;
+ }
+ };
+
+ struct IOSExportAsset {
+ String exported_path;
+ bool is_framework; // framework is anything linked to the binary, otherwise it's a resource
+ };
+
+ String _get_additional_plist_content();
+ String _get_linker_flags();
+ String _get_cpp_code();
+ void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const IOSConfigData &p_config, bool p_debug);
Error _export_loading_screens(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir);
Error _export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir);
+ Vector<ExportArchitecture> _get_supported_architectures();
+ Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset);
+
+ void _add_assets_to_project(Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets);
+ Error _export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, Vector<IOSExportAsset> &r_exported_assets);
+ Error _export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets);
+
protected:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
virtual void get_export_options(List<ExportOption> *r_options);
@@ -70,7 +108,7 @@ public:
virtual String get_os_name() const { return "iOS"; }
virtual Ref<Texture> get_logo() const { return logo; }
- virtual String get_binary_extension() const { return "ipa"; }
+ virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return "ipa"; }
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
@@ -96,6 +134,17 @@ void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset>
if (p_preset->get("texture_format/etc2")) {
r_features->push_back("etc2");
}
+ Vector<String> architectures = _get_preset_architectures(p_preset);
+ for (int i = 0; i < architectures.size(); ++i) {
+ r_features->push_back(architectures[i]);
+ }
+}
+
+Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_get_supported_architectures() {
+ Vector<ExportArchitecture> archs;
+ archs.push_back(ExportArchitecture("armv7", true));
+ archs.push_back(ExportArchitecture("arm64", true));
+ return archs;
}
void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
@@ -120,7 +169,6 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/bits_mode", PROPERTY_HINT_ENUM, "Fat (32 & 64 bits),64 bits,32 bits"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPhone/iPod Touch with retina display
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/ipad_76x76", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPad
@@ -145,10 +193,13 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), true));
- /* probably need some more info */
+ Vector<ExportArchitecture> architectures = _get_supported_architectures();
+ for (int i = 0; i < architectures.size(); ++i) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + architectures[i].name), architectures[i].is_default));
+ }
}
-void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const String &p_name, const String &p_binary, bool p_debug) {
+void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const IOSConfigData &p_config, bool p_debug) {
static const String export_method_string[] = {
"app-store",
"development",
@@ -158,13 +209,12 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
String str;
String strnew;
str.parse_utf8((const char *)pfile.ptr(), pfile.size());
- print_line(str);
Vector<String> lines = str.split("\n");
for (int i = 0; i < lines.size(); i++) {
if (lines[i].find("$binary") != -1) {
- strnew += lines[i].replace("$binary", p_binary) + "\n";
+ strnew += lines[i].replace("$binary", p_config.binary_name) + "\n";
} else if (lines[i].find("$name") != -1) {
- strnew += lines[i].replace("$name", p_name) + "\n";
+ strnew += lines[i].replace("$name", p_config.pkg_name) + "\n";
} else if (lines[i].find("$info") != -1) {
strnew += lines[i].replace("$info", p_preset->get("application/info")) + "\n";
} else if (lines[i].find("$identifier") != -1) {
@@ -186,10 +236,21 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
strnew += lines[i].replace("$provisioning_profile_uuid_release", p_preset->get("application/provisioning_profile_uuid_release")) + "\n";
} else if (lines[i].find("$provisioning_profile_uuid_debug") != -1) {
strnew += lines[i].replace("$provisioning_profile_uuid_debug", p_preset->get("application/provisioning_profile_uuid_debug")) + "\n";
+ } else if (lines[i].find("$provisioning_profile_uuid") != -1) {
+ String uuid = p_debug ? p_preset->get("application/provisioning_profile_uuid_debug") : p_preset->get("application/provisioning_profile_uuid_release");
+ strnew += lines[i].replace("$provisioning_profile_uuid", uuid) + "\n";
} else if (lines[i].find("$code_sign_identity_debug") != -1) {
strnew += lines[i].replace("$code_sign_identity_debug", p_preset->get("application/code_sign_identity_debug")) + "\n";
} else if (lines[i].find("$code_sign_identity_release") != -1) {
strnew += lines[i].replace("$code_sign_identity_release", p_preset->get("application/code_sign_identity_release")) + "\n";
+ } else if (lines[i].find("$additional_plist_content") != -1) {
+ strnew += lines[i].replace("$additional_plist_content", p_config.plist_content) + "\n";
+ } else if (lines[i].find("$godot_archs") != -1) {
+ strnew += lines[i].replace("$godot_archs", p_config.architectures) + "\n";
+ } else if (lines[i].find("$linker_flags") != -1) {
+ strnew += lines[i].replace("$linker_flags", p_config.linker_flags) + "\n";
+ } else if (lines[i].find("$cpp_code") != -1) {
+ strnew += lines[i].replace("$cpp_code", p_config.cpp_code) + "\n";
} else {
strnew += lines[i] + "\n";
}
@@ -204,27 +265,37 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
}
}
-Error EditorExportPlatformIOS::_export_dylibs(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
- if (!p_path.ends_with(".dylib")) return OK;
- const String &dest_dir = *(String *)p_userdata;
- String rel_path = p_path.replace_first("res://", "dylibs/");
- DirAccess *dest_dir_access = DirAccess::open(dest_dir);
- ERR_FAIL_COND_V(!dest_dir_access, ERR_CANT_OPEN);
-
- String base_dir = rel_path.get_base_dir();
- Error make_dir_err = OK;
- if (!dest_dir_access->dir_exists(base_dir)) {
- make_dir_err = dest_dir_access->make_dir_recursive(base_dir);
- }
- if (make_dir_err != OK) {
- memdelete(dest_dir_access);
- return make_dir_err;
+String EditorExportPlatformIOS::_get_additional_plist_content() {
+ Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
+ String result;
+ for (int i = 0; i < export_plugins.size(); ++i) {
+ result += export_plugins[i]->get_ios_plist_content();
}
+ return result;
+}
- Error copy_err = dest_dir_access->copy(p_path, dest_dir + rel_path);
- memdelete(dest_dir_access);
+String EditorExportPlatformIOS::_get_linker_flags() {
+ Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
+ String result;
+ for (int i = 0; i < export_plugins.size(); ++i) {
+ String flags = export_plugins[i]->get_ios_linker_flags();
+ if (flags.length() == 0) continue;
+ if (result.length() > 0) {
+ result += ' ';
+ }
+ result += flags;
+ }
+ // the flags will be enclosed in quotes, so need to escape them
+ return result.replace("\"", "\\\"");
+}
- return copy_err;
+String EditorExportPlatformIOS::_get_cpp_code() {
+ Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
+ String result;
+ for (int i = 0; i < export_plugins.size(); ++i) {
+ result += export_plugins[i]->get_ios_cpp_code();
+ }
+ return result;
}
struct IconInfo {
@@ -383,8 +454,9 @@ struct CodesignData {
const Ref<EditorExportPreset> &preset;
bool debug;
- CodesignData(const Ref<EditorExportPreset> &p_preset, bool p_debug)
- : preset(p_preset), debug(p_debug) {
+ CodesignData(const Ref<EditorExportPreset> &p_preset, bool p_debug) :
+ preset(p_preset),
+ debug(p_debug) {
}
};
@@ -402,7 +474,207 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) {
return OK;
}
+struct PbxId {
+private:
+ static char _hex_char(uint8_t four_bits) {
+ if (four_bits < 10) {
+ return ('0' + four_bits);
+ }
+ return 'A' + (four_bits - 10);
+ }
+
+ static String _hex_pad(uint32_t num) {
+ Vector<char> ret;
+ ret.resize(sizeof(num) * 2);
+ for (int i = 0; i < sizeof(num) * 2; ++i) {
+ uint8_t four_bits = (num >> (sizeof(num) * 8 - (i + 1) * 4)) & 0xF;
+ ret[i] = _hex_char(four_bits);
+ }
+ return String::utf8(ret.ptr(), ret.size());
+ }
+
+public:
+ uint32_t high_bits;
+ uint32_t mid_bits;
+ uint32_t low_bits;
+
+ String str() const {
+ return _hex_pad(high_bits) + _hex_pad(mid_bits) + _hex_pad(low_bits);
+ }
+
+ PbxId &operator++() {
+ low_bits++;
+ if (!low_bits) {
+ mid_bits++;
+ if (!mid_bits) {
+ high_bits++;
+ }
+ }
+
+ return *this;
+ }
+};
+
+struct ExportLibsData {
+ Vector<String> lib_paths;
+ String dest_dir;
+};
+
+void EditorExportPlatformIOS::_add_assets_to_project(Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets) {
+ Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
+ Vector<String> frameworks;
+ for (int i = 0; i < export_plugins.size(); ++i) {
+ Vector<String> plugin_frameworks = export_plugins[i]->get_ios_frameworks();
+ for (int j = 0; j < plugin_frameworks.size(); ++j) {
+ frameworks.push_back(plugin_frameworks[j]);
+ }
+ }
+
+ // that is just a random number, we just need Godot IDs not to clash with
+ // existing IDs in the project.
+ PbxId current_id = { 0x58938401, 0, 0 };
+ String pbx_files;
+ String pbx_frameworks_build;
+ String pbx_frameworks_refs;
+ String pbx_resources_build;
+ String pbx_resources_refs;
+
+ const String file_info_format = String("$build_id = {isa = PBXBuildFile; fileRef = $ref_id; };\n") +
+ "$ref_id = {isa = PBXFileReference; lastKnownFileType = $file_type; name = $name; path = \"$file_path\"; sourceTree = \"<group>\"; };\n";
+ for (int i = 0; i < p_additional_assets.size(); ++i) {
+ String build_id = (++current_id).str();
+ String ref_id = (++current_id).str();
+ const IOSExportAsset &asset = p_additional_assets[i];
+
+ String type;
+ if (asset.exported_path.ends_with(".framework")) {
+ type = "wrapper.framework";
+ } else if (asset.exported_path.ends_with(".dylib")) {
+ type = "compiled.mach-o.dylib";
+ } else if (asset.exported_path.ends_with(".a")) {
+ type = "archive.ar";
+ } else {
+ type = "file";
+ }
+
+ String &pbx_build = asset.is_framework ? pbx_frameworks_build : pbx_resources_build;
+ String &pbx_refs = asset.is_framework ? pbx_frameworks_refs : pbx_resources_refs;
+
+ if (pbx_build.length() > 0) {
+ pbx_build += ",\n";
+ pbx_refs += ",\n";
+ }
+ pbx_build += build_id;
+ pbx_refs += ref_id;
+
+ Dictionary format_dict;
+ format_dict["build_id"] = build_id;
+ format_dict["ref_id"] = ref_id;
+ format_dict["name"] = asset.exported_path.get_file();
+ format_dict["file_path"] = asset.exported_path;
+ format_dict["file_type"] = type;
+ pbx_files += file_info_format.format(format_dict, "$_");
+ }
+
+ String str = String::utf8((const char *)p_project_data.ptr(), p_project_data.size());
+ str = str.replace("$additional_pbx_files", pbx_files);
+ str = str.replace("$additional_pbx_frameworks_build", pbx_frameworks_build);
+ str = str.replace("$additional_pbx_frameworks_refs", pbx_frameworks_refs);
+ str = str.replace("$additional_pbx_resources_build", pbx_resources_build);
+ str = str.replace("$additional_pbx_resources_refs", pbx_resources_refs);
+
+ CharString cs = str.utf8();
+ p_project_data.resize(cs.size() - 1);
+ for (int i = 0; i < cs.size() - 1; i++) {
+ p_project_data[i] = cs[i];
+ }
+}
+
+Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, Vector<IOSExportAsset> &r_exported_assets) {
+ DirAccess *filesystem_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ ERR_FAIL_COND_V(!filesystem_da, ERR_CANT_CREATE);
+ for (int f_idx = 0; f_idx < p_assets.size(); ++f_idx) {
+ String asset = p_assets[f_idx];
+ if (!asset.begins_with("res://")) {
+ // either SDK-builtin or already a part of the export template
+ IOSExportAsset exported_asset = { asset, p_is_framework };
+ r_exported_assets.push_back(exported_asset);
+ } else {
+ DirAccess *da = DirAccess::create_for_path(asset);
+ if (!da) {
+ memdelete(filesystem_da);
+ ERR_FAIL_COND_V(!da, ERR_CANT_CREATE);
+ }
+ bool file_exists = da->file_exists(asset);
+ bool dir_exists = da->dir_exists(asset);
+ if (!file_exists && !dir_exists) {
+ memdelete(da);
+ memdelete(filesystem_da);
+ return ERR_FILE_NOT_FOUND;
+ }
+ String additional_dir = p_is_framework && asset.ends_with(".dylib") ? "/dylibs/" : "/";
+ String destination_dir = p_out_dir + additional_dir + asset.get_base_dir().replace("res://", "");
+ if (!filesystem_da->dir_exists(destination_dir)) {
+ Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir);
+ if (make_dir_err) {
+ memdelete(da);
+ memdelete(filesystem_da);
+ return make_dir_err;
+ }
+ }
+
+ String destination = destination_dir + "/" + asset.get_file();
+ Error err = dir_exists ? da->copy_dir(asset, destination) : da->copy(asset, destination);
+ memdelete(da);
+ if (err) {
+ memdelete(filesystem_da);
+ return err;
+ }
+ IOSExportAsset exported_asset = { destination, p_is_framework };
+ r_exported_assets.push_back(exported_asset);
+ }
+ }
+ memdelete(filesystem_da);
+
+ return OK;
+}
+
+Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets) {
+ Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
+ for (int i = 0; i < export_plugins.size(); i++) {
+ Vector<String> frameworks = export_plugins[i]->get_ios_frameworks();
+ Error err = _export_additional_assets(p_out_dir, frameworks, true, r_exported_assets);
+ ERR_FAIL_COND_V(err, err);
+ Vector<String> ios_bundle_files = export_plugins[i]->get_ios_bundle_files();
+ err = _export_additional_assets(p_out_dir, ios_bundle_files, false, r_exported_assets);
+ ERR_FAIL_COND_V(err, err);
+ }
+
+ Vector<String> library_paths;
+ for (int i = 0; i < p_libraries.size(); ++i) {
+ library_paths.push_back(p_libraries[i].path);
+ }
+ Error err = _export_additional_assets(p_out_dir, library_paths, true, r_exported_assets);
+ ERR_FAIL_COND_V(err, err);
+
+ return OK;
+}
+
+Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<EditorExportPreset> &p_preset) {
+ Vector<ExportArchitecture> all_archs = _get_supported_architectures();
+ Vector<String> enabled_archs;
+ for (int i = 0; i < all_archs.size(); ++i) {
+ bool is_enabled = p_preset->get("architectures/" + all_archs[i].name);
+ if (is_enabled) {
+ enabled_archs.push_back(all_archs[i].name);
+ }
+ }
+ return enabled_archs;
+}
+
Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
+
String src_pkg_name;
String dest_dir = p_path.get_base_dir() + "/";
String binary_name = p_path.get_file().get_basename();
@@ -427,26 +699,43 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
}
}
- FileAccess *src_f = NULL;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ if (da) {
+ String current_dir = da->get_current_dir();
- ep.step("Creating app", 0);
+ // remove leftovers from last export so they don't interfere
+ // in case some files are no longer needed
+ if (da->change_dir(dest_dir + binary_name + ".xcodeproj") == OK) {
+ da->erase_contents_recursive();
+ }
+ if (da->change_dir(dest_dir + binary_name) == OK) {
+ da->erase_contents_recursive();
+ }
- unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
- if (!src_pkg_zip) {
+ da->change_dir(current_dir);
- EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name);
- return ERR_FILE_NOT_FOUND;
+ if (!da->dir_exists(dest_dir + binary_name)) {
+ Error err = da->make_dir(dest_dir + binary_name);
+ if (err) {
+ memdelete(da);
+ return err;
+ }
+ }
+ memdelete(da);
}
- ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN);
- int ret = unzGoToFirstFile(src_pkg_zip);
+ ep.step("Making .pck", 0);
+ String pack_path = dest_dir + binary_name + ".pck";
+ Vector<SharedObject> libraries;
+ Error err = save_pack(p_preset, pack_path, &libraries);
+ if (err)
+ return err;
+
+ ep.step("Extracting and configuring Xcode project", 1);
- String binary_to_use = "godot.iphone." + String(p_debug ? "debug" : "release") + ".";
- int bits_mode = p_preset->get("application/bits_mode");
- binary_to_use += String(bits_mode == 0 ? "fat" : bits_mode == 1 ? "arm64" : "armv7");
+ String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".fat.a";
- print_line("binary: " + binary_to_use);
+ print_line("static library: " + library_to_use);
String pkg_name;
if (p_preset->get("application/name") != "")
pkg_name = p_preset->get("application/name"); // app_name
@@ -455,22 +744,41 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
else
pkg_name = "Unnamed";
- DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir);
- ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE)
-
- /* Now process our template */
- bool found_binary = false;
+ bool found_library = false;
int total_size = 0;
+ const String project_file = "godot_ios.xcodeproj/project.pbxproj";
Set<String> files_to_parse;
files_to_parse.insert("godot_ios/godot_ios-Info.plist");
- files_to_parse.insert("godot_ios.xcodeproj/project.pbxproj");
- files_to_parse.insert("export_options.plist");
+ files_to_parse.insert(project_file);
+ files_to_parse.insert("godot_ios/export_options.plist");
+ files_to_parse.insert("godot_ios/dummy.cpp");
files_to_parse.insert("godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata");
files_to_parse.insert("godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme");
- print_line("Unzipping...");
+ IOSConfigData config_data = {
+ pkg_name,
+ binary_name,
+ _get_additional_plist_content(),
+ String(" ").join(_get_preset_architectures(p_preset)),
+ _get_linker_flags(),
+ _get_cpp_code()
+ };
+
+ DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir);
+ ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE)
+ print_line("Unzipping...");
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
+ if (!src_pkg_zip) {
+ EditorNode::add_io_error("Could not open export template (not a zip file?):\n" + src_pkg_name);
+ return ERR_CANT_OPEN;
+ }
+ ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN);
+ int ret = unzGoToFirstFile(src_pkg_zip);
+ Vector<uint8_t> project_file_data;
while (ret == UNZ_OK) {
bool is_execute = false;
@@ -487,7 +795,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
//read
unzOpenCurrentFile(src_pkg_zip);
- unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size());
+ unzReadCurrentFile(src_pkg_zip, data.ptrw(), data.size());
unzCloseCurrentFile(src_pkg_zip);
//write
@@ -496,15 +804,18 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (files_to_parse.has(file)) {
print_line(String("parse ") + file);
- _fix_config_file(p_preset, data, pkg_name, binary_name, p_debug);
- } else if (file.begins_with("godot.iphone")) {
- if (file != binary_to_use) {
+ _fix_config_file(p_preset, data, config_data, p_debug);
+ } else if (file.begins_with("libgodot.iphone")) {
+ if (file != library_to_use) {
ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore!
}
- found_binary = true;
+ found_library = true;
is_execute = true;
- file = "godot_ios.iphone";
+ file = "godot_ios.a";
+ }
+ if (file == project_file) {
+ project_file_data = data;
}
///@TODO need to parse logo files
@@ -557,16 +868,16 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
/* we're done with our source zip */
unzClose(src_pkg_zip);
- if (!found_binary) {
- ERR_PRINTS("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive.");
+ if (!found_library) {
+ ERR_PRINTS("Requested template library '" + library_to_use + "' not found. It might be missing from your template archive.");
memdelete(tmp_app_path);
return ERR_FILE_NOT_FOUND;
}
String iconset_dir = dest_dir + binary_name + "/Images.xcassets/AppIcon.appiconset/";
- Error err = OK;
+ err = OK;
if (!tmp_app_path->dir_exists(iconset_dir)) {
- Error err = tmp_app_path->make_dir_recursive(iconset_dir);
+ err = tmp_app_path->make_dir_recursive(iconset_dir);
}
memdelete(tmp_app_path);
if (err)
@@ -580,20 +891,23 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (err)
return err;
- ep.step("Making .pck", 1);
-
- String pack_path = dest_dir + binary_name + ".pck";
- err = save_pack(p_preset, pack_path);
- if (err)
- return err;
-
- err = export_project_files(p_preset, _export_dylibs, &dest_dir);
- if (err)
- return err;
+ print_line("Exporting additional assets");
+ Vector<IOSExportAsset> assets;
+ _export_additional_assets(dest_dir + binary_name, libraries, assets);
+ _add_assets_to_project(project_file_data, assets);
+ String project_file_name = dest_dir + binary_name + ".xcodeproj/project.pbxproj";
+ FileAccess *f = FileAccess::open(project_file_name, FileAccess::WRITE);
+ if (!f) {
+ ERR_PRINTS("Can't write '" + project_file_name + "'.");
+ return ERR_CANT_CREATE;
+ };
+ f->store_buffer(project_file_data.ptr(), project_file_data.size());
+ f->close();
+ memdelete(f);
#ifdef OSX_ENABLED
ep.step("Code-signing dylibs", 2);
- DirAccess *dylibs_dir = DirAccess::open(dest_dir + "dylibs");
+ DirAccess *dylibs_dir = DirAccess::open(dest_dir + binary_name + "/dylibs");
ERR_FAIL_COND_V(!dylibs_dir, ERR_CANT_OPEN);
CodesignData codesign_data(p_preset, p_debug);
err = _walk_dir_recursive(dylibs_dir, _codesign, &codesign_data);
@@ -625,13 +939,14 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
export_args.push_back("-archivePath");
export_args.push_back(archive_path);
export_args.push_back("-exportOptionsPlist");
- export_args.push_back(dest_dir + "export_options.plist");
+ export_args.push_back(dest_dir + binary_name + "/export_options.plist");
+ export_args.push_back("-allowProvisioningUpdates");
export_args.push_back("-exportPath");
export_args.push_back(dest_dir);
err = OS::get_singleton()->execute("xcodebuild", export_args, true);
ERR_FAIL_COND_V(err, err);
#else
- print_line(".ipa can only be built on macOS. Leaving XCode project without building the package.");
+ print_line(".ipa can only be built on macOS. Leaving Xcode project without building the package.");
#endif
return OK;
@@ -659,14 +974,13 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
if (!err.empty())
r_error = err;
+ r_missing_templates = !valid;
return valid;
}
EditorExportPlatformIOS::EditorExportPlatformIOS() {
- ///@TODO need to create the correct logo
- // Ref<Image> img = memnew(Image(_iphone_logo));
- Ref<Image> img = memnew(Image(_osx_logo));
+ Ref<Image> img = memnew(Image(_iphone_logo));
logo.instance();
logo->create_from_image(img);
}
diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm
index 531b80eee3..d2104ae765 100644
--- a/platform/iphone/game_center.mm
+++ b/platform/iphone/game_center.mm
@@ -109,7 +109,7 @@ void GameCenter::connect() {
GameCenter::get_singleton()->authenticated = true;
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
ret["error_description"] = [error.localizedDescription UTF8String];
GameCenter::get_singleton()->authenticated = false;
};
@@ -145,7 +145,7 @@ Error GameCenter::post_score(Variant p_score) {
ret["result"] = "ok";
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
ret["error_description"] = [error.localizedDescription UTF8String];
};
@@ -183,7 +183,7 @@ Error GameCenter::award_achievement(Variant p_params) {
ret["result"] = "ok";
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
};
pending_events.push_back(ret);
@@ -241,7 +241,7 @@ void GameCenter::request_achievement_descriptions() {
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
};
pending_events.push_back(ret);
@@ -273,7 +273,7 @@ void GameCenter::request_achievements() {
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
};
pending_events.push_back(ret);
@@ -289,7 +289,7 @@ void GameCenter::reset_achievements() {
ret["result"] = "ok";
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
};
pending_events.push_back(ret);
@@ -358,7 +358,7 @@ Error GameCenter::request_identity_verification_signature() {
ret["player_id"] = [player.playerID UTF8String];
} else {
ret["result"] = "error";
- ret["error_code"] = error.code;
+ ret["error_code"] = (int64_t)error.code;
ret["error_description"] = [error.localizedDescription UTF8String];
};
diff --git a/platform/iphone/globals/global_defaults.cpp b/platform/iphone/globals/global_defaults.cpp
index 4bdc716d6e..b81e6def3b 100644
--- a/platform/iphone/globals/global_defaults.cpp
+++ b/platform/iphone/globals/global_defaults.cpp
@@ -31,11 +31,4 @@
#include "project_settings.h"
void register_iphone_global_defaults() {
-
- /*GLOBAL_DEF("rasterizer.iOS/use_fragment_lighting",false);
- GLOBAL_DEF("rasterizer.iOS/fp16_framebuffer",false);
- GLOBAL_DEF("display.iOS/driver","GLES2");
- ProjectSettings::get_singleton()->set_custom_property_info("display.iOS/driver",PropertyInfo(Variant::STRING,"display.iOS/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2"));
- GLOBAL_DEF("display.iOS/use_cadisplaylink",true);
- */
}
diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm
index 9efd4b9891..31d3659802 100644
--- a/platform/iphone/in_app_store.mm
+++ b/platform/iphone/in_app_store.mm
@@ -31,10 +31,6 @@
#include "in_app_store.h"
-#ifdef MODULE_FUSEBOXX_ENABLED
-#import "modules/fuseboxx/ios/FuseSDK.h"
-#endif
-
extern "C" {
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
@@ -92,6 +88,7 @@ void InAppStore::_bind_methods() {
PoolRealArray prices;
PoolStringArray ids;
PoolStringArray localized_prices;
+ PoolStringArray currency_codes;
for (int i = 0; i < [products count]; i++) {
@@ -105,12 +102,14 @@ void InAppStore::_bind_methods() {
prices.push_back([product.price doubleValue]);
ids.push_back(String::utf8([product.productIdentifier UTF8String]));
localized_prices.push_back(String::utf8([product.localizedPrice UTF8String]));
+ currency_codes.push_back(String::utf8([[[product priceLocale] objectForKey:NSLocaleCurrencyCode] UTF8String]));
};
ret["titles"] = titles;
ret["descriptions"] = descriptions;
ret["prices"] = prices;
ret["ids"] = ids;
ret["localized_prices"] = localized_prices;
+ ret["currency_codes"] = currency_codes;
PoolStringArray invalid_ids;
@@ -221,10 +220,6 @@ Error InAppStore::request_product_info(Variant p_params) {
[pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier];
}
-#ifdef MODULE_FUSEBOXX_ENABLED
- printf("Registering transaction on Fuseboxx!\n");
- [FuseSDK registerInAppPurchase:transaction];
-#endif
}; break;
case SKPaymentTransactionStateFailed: {
printf("status transaction failed!\n");
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index d0865a35b9..1c7f41b464 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -46,6 +46,7 @@
#include "sem_iphone.h"
#include "ios.h"
+#include <dlfcn.h>
int OSIPhone::get_video_driver_count() const {
@@ -54,7 +55,7 @@ int OSIPhone::get_video_driver_count() const {
const char *OSIPhone::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ return "GLES3";
};
OSIPhone *OSIPhone::get_singleton() {
@@ -96,15 +97,6 @@ void OSIPhone::initialize_core() {
set_data_dir(data_dir);
};
-void OSIPhone::initialize_logger() {
- Vector<Logger *> loggers;
- loggers.push_back(memnew(SyslogLogger));
- // FIXME: Reenable once we figure out how to get this properly in user://
- // instead of littering the user's working dirs (res:// + pwd) with log files (GH-12277)
- //loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
supported_orientations = 0;
@@ -125,7 +117,7 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_
*/
visual_server->init();
- // visual_server->cursor_set_visible(false, 0);
+ //visual_server->cursor_set_visible(false, 0);
// reset this to what it should be, it will have been set to 0 after visual_server->init() is called
RasterizerStorageGLES3::system_fbo = gl_view_base_fb;
@@ -135,14 +127,6 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_
input = memnew(InputDefault);
-/*
-#ifdef IOS_SCORELOOP_ENABLED
- scoreloop = memnew(ScoreloopIOS);
- Engine::get_singleton()->add_singleton(Engine::Singleton("Scoreloop", scoreloop));
- scoreloop->connect();
-#endif
- */
-
#ifdef GAME_CENTER_ENABLED
game_center = memnew(GameCenter);
Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center));
@@ -157,7 +141,7 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_
#ifdef ICLOUD_ENABLED
icloud = memnew(ICloud);
Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud));
-//icloud->connect();
+ //icloud->connect();
#endif
Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", memnew(iOS)));
};
@@ -402,6 +386,37 @@ void OSIPhone::alert(const String &p_alert, const String &p_title) {
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
}
+Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+ if (p_path.length() == 0) {
+ p_library_handle = RTLD_SELF;
+ return OK;
+ }
+ return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path);
+}
+
+Error OSIPhone::close_dynamic_library(void *p_library_handle) {
+ if (p_library_handle == RTLD_SELF) {
+ return OK;
+ }
+ return OS_Unix::close_dynamic_library(p_library_handle);
+}
+
+HashMap<String, void *> OSIPhone::dynamic_symbol_lookup_table;
+void register_dynamic_symbol(char *name, void *address) {
+ OSIPhone::dynamic_symbol_lookup_table[String(name)] = address;
+}
+
+Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
+ if (p_library_handle == RTLD_SELF) {
+ void **ptr = OSIPhone::dynamic_symbol_lookup_table.getptr(p_name);
+ if (ptr) {
+ p_symbol_handle = *ptr;
+ return OK;
+ }
+ }
+ return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional);
+}
+
void OSIPhone::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
video_mode = p_video_mode;
@@ -470,7 +485,7 @@ void OSIPhone::set_cursor_shape(CursorShape p_shape){
};
-String OSIPhone::get_data_dir() const {
+String OSIPhone::get_user_data_dir() const {
return data_dir;
};
@@ -509,7 +524,7 @@ Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
bool exists = f && f->is_open();
- String tempFile = get_data_dir();
+ String tempFile = get_user_data_dir();
if (!exists)
return FAILED;
@@ -521,7 +536,7 @@ Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_
p_path = p_path.replace("res:/", ProjectSettings::get_singleton()->get_resource_path());
}
} else if (p_path.begins_with("user://"))
- p_path = p_path.replace("user:/", get_data_dir());
+ p_path = p_path.replace("user:/", get_user_data_dir());
memdelete(f);
@@ -558,7 +573,36 @@ bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
return p_feature == "mobile" || p_feature == "etc" || p_feature == "pvrtc" || p_feature == "etc2";
}
+// Initialization order between compilation units is not guaranteed,
+// so we use this as a hack to ensure certain code is called before
+// everything else, but after all units are initialized.
+typedef void (*init_callback)();
+static init_callback *ios_init_callbacks = NULL;
+static int ios_init_callbacks_count = 0;
+static int ios_init_callbacks_capacity = 0;
+
+void add_ios_init_callback(init_callback cb) {
+ if (ios_init_callbacks_count == ios_init_callbacks_capacity) {
+ void *new_ptr = realloc(ios_init_callbacks, sizeof(cb) * 32);
+ if (new_ptr) {
+ ios_init_callbacks = (init_callback *)(new_ptr);
+ ios_init_callbacks_capacity += 32;
+ }
+ }
+ if (ios_init_callbacks_capacity > ios_init_callbacks_count) {
+ ios_init_callbacks[ios_init_callbacks_count] = cb;
+ ++ios_init_callbacks_count;
+ }
+}
+
OSIPhone::OSIPhone(int width, int height, String p_data_dir) {
+ for (int i = 0; i < ios_init_callbacks_count; ++i) {
+ ios_init_callbacks[i]();
+ }
+ free(ios_init_callbacks);
+ ios_init_callbacks = NULL;
+ ios_init_callbacks_count = 0;
+ ios_init_callbacks_capacity = 0;
main_loop = NULL;
visual_server = NULL;
@@ -576,7 +620,13 @@ OSIPhone::OSIPhone(int width, int height, String p_data_dir) {
// which is initialized in initialize_core
data_dir = p_data_dir;
- _set_logger(memnew(SyslogLogger));
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(SyslogLogger));
+#ifdef DEBUG_ENABLED
+ // it seems iOS app's stdout/stderr is only obtainable if you launch it from Xcode
+ loggers.push_back(memnew(StdLogger));
+#endif
+ _set_logger(memnew(CompositeLogger(loggers)));
};
OSIPhone::~OSIPhone() {
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 6627fddf08..3f989b49be 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -60,6 +60,9 @@ private:
MAX_EVENTS = 64,
};
+ static HashMap<String, void *> dynamic_symbol_lookup_table;
+ friend void register_dynamic_symbol(char *name, void *address);
+
uint8_t supported_orientations;
VisualServer *visual_server;
@@ -83,7 +86,6 @@ private:
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -153,6 +155,10 @@ public:
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
+ virtual Error close_dynamic_library(void *p_library_handle);
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
+
virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
virtual VideoMode get_video_mode(int p_screen = 0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
@@ -178,7 +184,7 @@ public:
Error shell_open(String p_uri);
- String get_data_dir() const;
+ String get_user_data_dir() const;
void set_locale(String p_locale);
String get_locale() const;
diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h
index 54de66082e..7ff6e7a9a9 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/iphone/platform_config.h
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include <alloca.h>
-// #define GLES2_INCLUDE_H <ES2/gl.h>
+
#define GLES3_INCLUDE_H <ES3/gl.h>
#define PLATFORM_REFCOUNT
diff --git a/platform/iphone/power_iphone.cpp b/platform/iphone/power_iphone.cpp
index 055d31ef0a..03afdb15f9 100644
--- a/platform/iphone/power_iphone.cpp
+++ b/platform/iphone/power_iphone.cpp
@@ -58,8 +58,10 @@ int PowerIphone::get_power_percent_left() {
}
}
-PowerIphone::PowerIphone()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerIphone::PowerIphone() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
// TODO Auto-generated constructor stub
}
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index e3015d87b9..05992ebac8 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -21,37 +21,21 @@ for x in javascript_files:
env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_main_after_fs_sync','_send_notification']\""])
-# output file name without file extension
-basename = "godot" + env["PROGSUFFIX"]
target_dir = env.Dir("#bin")
-
-zip_dir = target_dir.Dir('.javascript_zip')
-zip_files = env.InstallAs(zip_dir.File('godot.html'), '#misc/dist/html/default.html')
-
-implicit_targets = []
-if env['wasm']:
- wasm = target_dir.File(basename + '.wasm')
- implicit_targets.append(wasm)
- zip_files.append(InstallAs(zip_dir.File('godot.wasm'), wasm))
- prejs = env.File('pre_wasm.js')
-else:
- asmjs_files = [target_dir.File(basename + '.asm.js'), target_dir.File(basename + '.js.mem')]
- implicit_targets.extend(asmjs_files)
- zip_files.append(InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files))
- prejs = env.File('pre_asmjs.js')
-
-js = env.Program(['#bin/godot'] + implicit_targets, javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js')[0];
-zip_files.append(InstallAs(zip_dir.File('godot.js'), js))
+build = env.add_program(['#bin/godot', target_dir.File('godot' + env['PROGSUFFIX'] + '.wasm')], javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js');
js_libraries = []
js_libraries.append(env.File('http_request.js'))
for lib in js_libraries:
env.Append(LINKFLAGS=['--js-library', lib.path])
-env.Depends(js, js_libraries)
+env.Depends(build, js_libraries)
+prejs = env.File('pre.js')
postjs = env.File('engine.js')
-env.Depends(js, [prejs, postjs])
env.Append(LINKFLAGS=['--pre-js', prejs.path])
env.Append(LINKFLAGS=['--post-js', postjs.path])
+env.Depends(build, [prejs, postjs])
+zip_dir = target_dir.Dir('.javascript_zip')
+zip_files = env.InstallAs([zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html')], build + ['#misc/dist/html/default.html'])
Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX'] + env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET")
diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/javascript/api/api.cpp
index 8a6951fd6e..f2b2ca40bf 100644
--- a/platform/windows/packet_peer_udp_winsock.h
+++ b/platform/javascript/api/api.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* packet_peer_udp_winsock.h */
+/* api.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,58 +27,47 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef PACKET_PEER_UDP_WINSOCK_H
-#define PACKET_PEER_UDP_WINSOCK_H
+#include "api.h"
+#include "engine.h"
+#include "javascript_eval.h"
-#include "io/packet_peer_udp.h"
-#include "ring_buffer.h"
+static JavaScript *javascript_eval;
-class PacketPeerUDPWinsock : public PacketPeerUDP {
+void register_javascript_api() {
- enum {
- PACKET_BUFFER_SIZE = 65536
- };
+ ClassDB::register_virtual_class<JavaScript>();
+ javascript_eval = memnew(JavaScript);
+ Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval));
+}
- mutable RingBuffer<uint8_t> rb;
- uint8_t recv_buffer[PACKET_BUFFER_SIZE];
- mutable uint8_t packet_buffer[PACKET_BUFFER_SIZE];
- mutable IP_Address packet_ip;
- mutable int packet_port;
- mutable int queue_count;
- int sockfd;
- bool sock_blocking;
- IP::Type sock_type;
+void unregister_javascript_api() {
- IP_Address peer_addr;
- int peer_port;
+ memdelete(javascript_eval);
+}
- _FORCE_INLINE_ int _get_socket();
+JavaScript *JavaScript::singleton = NULL;
- static PacketPeerUDP *_create();
+JavaScript *JavaScript::get_singleton() {
- void _set_sock_blocking(bool p_blocking);
+ return singleton;
+}
- Error _poll(bool p_wait);
+JavaScript::JavaScript() {
-public:
- virtual int get_available_packet_count() const;
- virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) const;
- virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size);
+ ERR_FAIL_COND(singleton != NULL);
+ singleton = this;
+}
- virtual int get_max_packet_size() const;
+JavaScript::~JavaScript() {}
- virtual Error listen(int p_port, const IP_Address &p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536);
- virtual void close();
- virtual Error wait();
- virtual bool is_listening() const;
+void JavaScript::_bind_methods() {
- virtual IP_Address get_packet_address() const;
- virtual int get_packet_port() const;
+ ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, DEFVAL(false));
+}
- virtual void set_dest_address(const IP_Address &p_address, int p_port);
+#if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED)
+Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
- static void make_default();
- PacketPeerUDPWinsock();
- ~PacketPeerUDPWinsock();
-};
-#endif // PACKET_PEER_UDP_WINSOCK_H
+ return Variant();
+}
+#endif
diff --git a/platform/windows/stream_peer_winsock.h b/platform/javascript/api/api.h
index 26e2a3e4c9..53cd9239fc 100644
--- a/platform/windows/stream_peer_winsock.h
+++ b/platform/javascript/api/api.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* stream_peer_winsock.h */
+/* api.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,65 +27,5 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef WINDOWS_ENABLED
-
-#ifndef STREAM_PEER_WINSOCK_H
-#define STREAM_PEER_WINSOCK_H
-
-#include "error_list.h"
-
-#include "core/io/ip_address.h"
-#include "core/io/stream_peer_tcp.h"
-
-class StreamPeerWinsock : public StreamPeerTCP {
-
-protected:
- mutable Status status;
- IP::Type sock_type;
-
- int sockfd;
-
- Error _block(int p_sockfd, bool p_read, bool p_write) const;
-
- Error _poll_connection() const;
-
- IP_Address peer_host;
- int peer_port;
-
- Error write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block);
- Error read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block);
-
- static StreamPeerTCP *_create();
-
-public:
- virtual Error connect_to_host(const IP_Address &p_host, uint16_t p_port);
-
- virtual Error put_data(const uint8_t *p_data, int p_bytes);
- virtual Error put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent);
-
- virtual Error get_data(uint8_t *p_buffer, int p_bytes);
- virtual Error get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received);
-
- virtual int get_available_bytes() const;
-
- void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type);
-
- virtual IP_Address get_connected_host() const;
- virtual uint16_t get_connected_port() const;
-
- virtual bool is_connected_to_host() const;
- virtual Status get_status() const;
- virtual void disconnect_from_host();
-
- static void make_default();
- static void cleanup();
-
- virtual void set_nodelay(bool p_enabled);
-
- StreamPeerWinsock();
- ~StreamPeerWinsock();
-};
-
-#endif // TCP_SOCKET_POSIX_H
-
-#endif
+void register_javascript_api();
+void unregister_javascript_api();
diff --git a/platform/javascript/javascript_eval.h b/platform/javascript/api/javascript_eval.h
index ed7cf383da..4d0b0b21ff 100644
--- a/platform/javascript/javascript_eval.h
+++ b/platform/javascript/api/javascript_eval.h
@@ -27,8 +27,6 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef JAVASCRIPT_EVAL_ENABLED
-
#ifndef JAVASCRIPT_EVAL_H
#define JAVASCRIPT_EVAL_H
@@ -52,4 +50,3 @@ public:
};
#endif // JAVASCRIPT_EVAL_H
-#endif // JAVASCRIPT_EVAL_ENABLED
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index a2988d9c60..8472c3ccab 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -19,7 +19,6 @@ def can_build():
def get_opts():
from SCons.Variables import BoolVariable
return [
- BoolVariable('wasm', 'Compile to WebAssembly', False),
BoolVariable('javascript_eval', 'Enable JavaScript eval interface', True),
]
@@ -103,20 +102,13 @@ def configure(env):
## Link flags
- env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"'])
+ env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
+ env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1'])
env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1'])
+ env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"'])
- if env['wasm']:
- env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
- # In contrast to asm.js, enabling memory growth on WebAssembly has no
- # major performance impact, and causes only a negligible increase in
- # memory size.
- env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1'])
- env.extra_suffix = '.webassembly' + env.extra_suffix
- else:
- env.Append(LINKFLAGS=['-s', 'ASM_JS=1'])
- env.Append(LINKFLAGS=['--separate-asm'])
- env.Append(LINKFLAGS=['--memory-init-file', '1'])
+ env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0'])
+ env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1'])
# TODO: Move that to opus module's config
if 'module_opus_enabled' in env and env['module_opus_enabled']:
diff --git a/platform/javascript/dom_keys.h b/platform/javascript/dom_keys.h
index d63f165382..bd15cec603 100644
--- a/platform/javascript/dom_keys.h
+++ b/platform/javascript/dom_keys.h
@@ -262,7 +262,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_CAPS_LOCK:
return KEY_CAPSLOCK;
- /*
+ /*
case DOM_VK_KANA: return KEY_UNKNOWN;
case DOM_VK_HANGUL: return KEY_UNKNOWN;
case DOM_VK_EISU: return KEY_UNKNOWN;
@@ -274,7 +274,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_ESCAPE:
return KEY_ESCAPE;
- /*
+ /*
case DOM_VK_CONVERT: return KEY_UNKNOWN;
case DOM_VK_NONCONVERT: return KEY_UNKNOWN;
case DOM_VK_ACCEPT: return KEY_UNKNOWN;
@@ -292,7 +292,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_DOWN:
return KEY_DOWN;
- //case DOM_VK_SELECT: return KEY_UNKNOWN;
+ //case DOM_VK_SELECT: return KEY_UNKNOWN;
case DOM_VK_PRINTSCREEN: // this is the usual printScreen key
case DOM_VK_PRINT: // maybe for alt+printScreen or physical printers?
@@ -320,7 +320,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_DIVIDE:
return KEY_KP_DIVIDE;
- /*
+ /*
case DOM_VK_F17: return KEY_UNKNOWN;
case DOM_VK_F18: return KEY_UNKNOWN;
case DOM_VK_F19: return KEY_UNKNOWN;
@@ -335,7 +335,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_SCROLL_LOCK:
return KEY_SCROLLLOCK;
- /*
+ /*
case DOM_VK_WIN_OEM_FJ_JISHO: return KEY_UNKNOWN;
case DOM_VK_WIN_OEM_FJ_MASSHOU: return KEY_UNKNOWN;
case DOM_VK_WIN_OEM_FJ_TOUROKU: return KEY_UNKNOWN;
@@ -375,7 +375,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_QUOTE:
return KEY_APOSTROPHE;
- // rest is OEM/unusual
+ // rest is OEM/unusual
default: return KEY_UNKNOWN;
};
diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js
index 99d1c20bbd..dc4bdc7efb 100644
--- a/platform/javascript/engine.js
+++ b/platform/javascript/engine.js
@@ -5,7 +5,6 @@
(function() {
var engine = Engine;
- var USING_WASM = engine.USING_WASM;
var DOWNLOAD_ATTEMPTS_MAX = 4;
var basePath = null;
@@ -32,87 +31,101 @@
this.rtenv = null;
- var gameInitPromise = null;
+ var initPromise = null;
var unloadAfterInit = true;
- var memorySize = 268435456;
+ var preloadedFiles = [];
+
+ var resizeCanvasOnStart = true;
var progressFunc = null;
- var pckProgressTracker = {};
+ var preloadProgressTracker = {};
var lastProgress = { loaded: 0, total: 0 };
var canvas = null;
+ var executableName = null;
+ var locale = null;
var stdout = null;
var stderr = null;
- this.initGame = function(mainPack) {
-
- if (!gameInitPromise) {
+ this.init = function(newBasePath) {
- if (mainPack === undefined) {
- if (basePath !== null) {
- mainPack = basePath + '.pck';
- } else {
- return Promise.reject(new Error("No main pack to load specified"));
- }
- }
- if (basePath === null)
- basePath = getBasePath(mainPack);
-
- gameInitPromise = Engine.initEngine().then(
+ if (!initPromise) {
+ initPromise = Engine.load(newBasePath).then(
instantiate.bind(this)
);
- var gameLoadPromise = loadPromise(mainPack, pckProgressTracker).then(function(xhr) { return xhr.response; });
- gameInitPromise = Promise.all([gameLoadPromise, gameInitPromise]).then(function(values) {
- // resolve with pck
- return new Uint8Array(values[0]);
- });
- if (unloadAfterInit)
- gameInitPromise.then(Engine.unloadEngine);
requestAnimationFrame(animateProgress);
+ if (unloadAfterInit)
+ initPromise.then(Engine.unloadEngine);
}
- return gameInitPromise;
+ return initPromise;
};
- function instantiate(initializer) {
+ function instantiate(wasmBuf) {
- var rtenvOpts = {
- noInitialRun: true,
- thisProgram: getBaseName(basePath),
+ var rtenvProps = {
engine: this,
+ ENV: {},
};
if (typeof stdout === 'function')
- rtenvOpts.print = stdout;
+ rtenvProps.print = stdout;
if (typeof stderr === 'function')
- rtenvOpts.printErr = stderr;
- if (typeof WebAssembly === 'object' && initializer instanceof ArrayBuffer) {
- rtenvOpts.instantiateWasm = function(imports, onSuccess) {
- WebAssembly.instantiate(initializer, imports).then(function(result) {
- onSuccess(result.instance);
- });
- return {};
- };
- } else if (initializer.asm && initializer.mem) {
- rtenvOpts.asm = initializer.asm;
- rtenvOpts.memoryInitializerRequest = initializer.mem;
- rtenvOpts.TOTAL_MEMORY = memorySize;
- } else {
- throw new Error("Invalid initializer");
- }
+ rtenvProps.printErr = stderr;
+ rtenvProps.instantiateWasm = function(imports, onSuccess) {
+ WebAssembly.instantiate(wasmBuf, imports).then(function(result) {
+ onSuccess(result.instance);
+ });
+ return {};
+ };
return new Promise(function(resolve, reject) {
- rtenvOpts.onRuntimeInitialized = resolve;
- rtenvOpts.onAbort = reject;
- rtenvOpts.engine.rtenv = Engine.RuntimeEnvironment(rtenvOpts);
+ rtenvProps.onRuntimeInitialized = resolve;
+ rtenvProps.onAbort = reject;
+ rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps);
});
}
- this.start = function(mainPack) {
+ this.preloadFile = function(pathOrBuffer, bufferFilename) {
+
+ if (pathOrBuffer instanceof ArrayBuffer) {
+ pathOrBuffer = new Uint8Array(pathOrBuffer);
+ } else if (ArrayBuffer.isView(pathOrBuffer)) {
+ pathOrBuffer = new Uint8Array(pathOrBuffer.buffer);
+ }
+ if (pathOrBuffer instanceof Uint8Array) {
+ preloadedFiles.push({
+ name: bufferFilename,
+ buffer: pathOrBuffer
+ });
+ return Promise.resolve();
+ } else if (typeof pathOrBuffer === 'string') {
+ return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) {
+ preloadedFiles.push({
+ name: pathOrBuffer,
+ buffer: xhr.response
+ });
+ });
+ } else {
+ throw Promise.reject("Invalid object for preloading");
+ }
+ };
+
+ this.start = function() {
+
+ return this.init().then(
+ Function.prototype.apply.bind(synchronousStart, this, arguments)
+ );
+ };
+
+ this.startGame = function(mainPack) {
- return this.initGame(mainPack).then(synchronousStart.bind(this));
+ executableName = getBaseName(mainPack);
+ return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then(
+ Function.prototype.apply.bind(synchronousStart, this, [])
+ );
};
- function synchronousStart(pckView) {
- // TODO don't expect canvas when runninng as cli tool
+ function synchronousStart() {
+
if (canvas instanceof HTMLCanvasElement) {
this.rtenv.canvas = canvas;
} else {
@@ -147,15 +160,33 @@
ev.preventDefault();
}, false);
- this.rtenv.FS.createDataFile('/', this.rtenv.thisProgram + '.pck', pckView, true, true, true);
- gameInitPromise = null;
- this.rtenv.callMain();
+ if (locale) {
+ this.rtenv.locale = locale;
+ } else {
+ this.rtenv.locale = navigator.languages ? navigator.languages[0] : navigator.language;
+ }
+ this.rtenv.locale = this.rtenv.locale.split('.')[0];
+ this.rtenv.resizeCanvasOnStart = resizeCanvasOnStart;
+
+ this.rtenv.thisProgram = executableName || getBaseName(basePath);
+
+ preloadedFiles.forEach(function(file) {
+ this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true);
+ }, this);
+
+ preloadedFiles = null;
+ initPromise = null;
+ this.rtenv.callMain(arguments);
}
this.setProgressFunc = function(func) {
progressFunc = func;
};
+ this.setResizeCanvasOnStart = function(enabled) {
+ resizeCanvasOnStart = enabled;
+ };
+
function animateProgress() {
var loaded = 0;
@@ -163,7 +194,7 @@
var totalIsValid = true;
var progressIsFinal = true;
- [loadingFiles, pckProgressTracker].forEach(function(tracker) {
+ [loadingFiles, preloadProgressTracker].forEach(function(tracker) {
Object.keys(tracker).forEach(function(file) {
if (!tracker[file].final)
progressIsFinal = false;
@@ -190,14 +221,20 @@
canvas = elem;
};
- this.setAsmjsMemorySize = function(size) {
- memorySize = size;
+ this.setExecutableName = function(newName) {
+
+ executableName = newName;
+ };
+
+ this.setLocale = function(newLocale) {
+
+ locale = newLocale;
};
this.setUnloadAfterInit = function(enabled) {
- if (enabled && !unloadAfterInit && gameInitPromise) {
- gameInitPromise.then(Engine.unloadEngine);
+ if (enabled && !unloadAfterInit && initPromise) {
+ initPromise.then(Engine.unloadEngine);
}
unloadAfterInit = enabled;
};
@@ -232,26 +269,16 @@
Engine.RuntimeEnvironment = engine.RuntimeEnvironment;
- Engine.initEngine = function(newBasePath) {
+ Engine.load = function(newBasePath) {
if (newBasePath !== undefined) basePath = getBasePath(newBasePath);
if (engineLoadPromise === null) {
- if (USING_WASM) {
- if (typeof WebAssembly !== 'object')
- return Promise.reject(new Error("Browser doesn't support WebAssembly"));
- // TODO cache/retrieve module to/from idb
- engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) {
- return xhr.response;
- });
- } else {
- var asmjsPromise = loadPromise(basePath + '.asm.js').then(function(xhr) {
- return asmjsModulePromise(xhr.response);
- });
- var memPromise = loadPromise(basePath + '.mem');
- engineLoadPromise = Promise.all([asmjsPromise, memPromise]).then(function(values) {
- return { asm: values[0], mem: values[1] };
- });
- }
+ if (typeof WebAssembly !== 'object')
+ return Promise.reject(new Error("Browser doesn't support WebAssembly"));
+ // TODO cache/retrieve module to/from idb
+ engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) {
+ return xhr.response;
+ });
engineLoadPromise = engineLoadPromise.catch(function(err) {
engineLoadPromise = null;
throw err;
@@ -260,34 +287,7 @@
return engineLoadPromise;
};
- function asmjsModulePromise(module) {
- var elem = document.createElement('script');
- var script = new Blob([
- 'Engine.asm = (function() { var Module = {};',
- module,
- 'return Module.asm; })();'
- ]);
- var url = URL.createObjectURL(script);
- elem.src = url;
- return new Promise(function(resolve, reject) {
- elem.addEventListener('load', function() {
- URL.revokeObjectURL(url);
- var asm = Engine.asm;
- Engine.asm = undefined;
- setTimeout(function() {
- // delay to reclaim compilation memory
- resolve(asm);
- }, 1);
- });
- elem.addEventListener('error', function() {
- URL.revokeObjectURL(url);
- reject("asm.js faiilure");
- });
- document.body.appendChild(elem);
- });
- }
-
- Engine.unloadEngine = function() {
+ Engine.unload = function() {
engineLoadPromise = null;
};
@@ -306,7 +306,7 @@
if (!file.endsWith('.js')) {
xhr.responseType = 'arraybuffer';
}
- ['loadstart', 'progress', 'load', 'error', 'timeout', 'abort'].forEach(function(ev) {
+ ['loadstart', 'progress', 'load', 'error', 'abort'].forEach(function(ev) {
xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker));
});
xhr.send();
@@ -321,7 +321,7 @@
this.abort();
return;
} else {
- loadXHR(resolve, reject, file);
+ setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000);
}
}
@@ -348,12 +348,11 @@
break;
case 'error':
- case 'timeout':
if (++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) {
tracker[file].final = true;
reject(new Error("Failed loading file '" + file + "'"));
} else {
- loadXHR(resolve, reject, file);
+ setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000);
}
break;
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 4a97bf4c32..ec5010f330 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -30,13 +30,12 @@
#include "editor/editor_node.h"
#include "editor_export.h"
#include "io/zip_io.h"
+#include "main/splash.gen.h"
#include "platform/javascript/logo.gen.h"
#include "platform/javascript/run_icon.gen.h"
#define EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE "webassembly_release.zip"
#define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip"
-#define EXPORT_TEMPLATE_ASMJS_RELEASE "javascript_release.zip"
-#define EXPORT_TEMPLATE_ASMJS_DEBUG "javascript_debug.zip"
class EditorExportPlatformJavaScript : public EditorExportPlatform {
@@ -47,25 +46,18 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
bool runnable_when_last_polled;
void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug);
- void _fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size);
public:
- enum Target {
- TARGET_WEBASSEMBLY,
- TARGET_ASMJS
- };
-
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
virtual void get_export_options(List<ExportOption> *r_options);
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
virtual String get_name() const;
virtual String get_os_name() const;
virtual Ref<Texture> get_logo() const;
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
- virtual String get_binary_extension() const;
+ virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const;
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
virtual bool poll_devices();
@@ -90,17 +82,9 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
String str_export;
Vector<String> lines = str_template.split("\n");
- int memory_mb;
- if (p_preset->get("options/target").operator int() != TARGET_ASMJS)
- // WebAssembly allows memory growth, so start with a reasonable default
- memory_mb = 1 << 4;
- else
- memory_mb = 1 << (p_preset->get("options/memory_size").operator int() + 5);
-
for (int i = 0; i < lines.size(); i++) {
String current_line = lines[i];
- current_line = current_line.replace("$GODOT_TOTAL_MEMORY", itos(memory_mb * 1024 * 1024));
current_line = current_line.replace("$GODOT_BASENAME", p_name);
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
@@ -129,24 +113,15 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "options/target", PROPERTY_HINT_ENUM, "WebAssembly,asm.js"), TARGET_WEBASSEMBLY));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "options/memory_size", PROPERTY_HINT_ENUM, "32 MB,64 MB,128 MB,256 MB,512 MB,1 GB"), 3));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_GLOBAL_FILE, "html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
}
-bool EditorExportPlatformJavaScript::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
- if (p_option == "options/memory_size") {
- return p_options["options/target"].operator int() == TARGET_ASMJS;
- }
- return true;
-}
-
String EditorExportPlatformJavaScript::get_name() const {
return "HTML5";
@@ -166,30 +141,25 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p
r_missing_templates = false;
- if (p_preset->get("options/target").operator int() == TARGET_WEBASSEMBLY) {
- if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) == String())
- r_missing_templates = true;
- else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) == String())
- r_missing_templates = true;
- } else {
- if (find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE) == String())
- r_missing_templates = true;
- else if (find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG) == String())
- r_missing_templates = true;
- }
+ if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) == String())
+ r_missing_templates = true;
+ else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) == String())
+ r_missing_templates = true;
return !r_missing_templates;
}
-String EditorExportPlatformJavaScript::get_binary_extension() const {
+String EditorExportPlatformJavaScript::get_binary_extension(const Ref<EditorExportPreset> &p_preset) const {
return "html";
}
Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String custom_debug = p_preset->get("custom_template/debug");
String custom_release = p_preset->get("custom_template/release");
+ String custom_html = p_preset->get("html/custom_html_shell");
String template_path = p_debug ? custom_debug : custom_release;
@@ -197,17 +167,10 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
if (template_path == String()) {
- if (p_preset->get("options/target").operator int() == TARGET_WEBASSEMBLY) {
- if (p_debug)
- template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG);
- else
- template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE);
- } else {
- if (p_debug)
- template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG);
- else
- template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE);
- }
+ if (p_debug)
+ template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG);
+ else
+ template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE);
}
if (template_path != String() && !FileAccess::exists(template_path)) {
@@ -222,14 +185,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
return error;
}
- FileAccess *f = FileAccess::open(pck_path, FileAccess::READ);
- if (!f) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:\n") + pck_path);
- return ERR_FILE_CANT_READ;
- }
- size_t pack_size = f->get_len();
- memdelete(f);
-
FileAccess *src_f = NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
unzFile pkg = unzOpen2(template_path.utf8().get_data(), &io);
@@ -240,13 +195,17 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
return ERR_FILE_NOT_FOUND;
}
- int ret = unzGoToFirstFile(pkg);
- while (ret == UNZ_OK) {
+ if (unzGoToFirstFile(pkg) != UNZ_OK) {
+ EditorNode::get_singleton()->show_warning(TTR("Invalid export template:\n") + template_path);
+ unzClose(pkg);
+ return ERR_FILE_CORRUPT;
+ }
+ do {
//get filename
unz_file_info info;
char fname[16384];
- ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
+ unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
String file = fname;
@@ -255,27 +214,25 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
//read
unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptr(), data.size());
+ unzReadCurrentFile(pkg, data.ptrw(), data.size());
unzCloseCurrentFile(pkg);
//write
if (file == "godot.html") {
+ if (!custom_html.empty()) {
+ continue;
+ }
_fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug);
file = p_path.get_file();
+
} else if (file == "godot.js") {
file = p_path.get_file().get_basename() + ".js";
} else if (file == "godot.wasm") {
file = p_path.get_file().get_basename() + ".wasm";
- } else if (file == "godot.asm.js") {
-
- file = p_path.get_file().get_basename() + ".asm.js";
- } else if (file == "godot.mem") {
-
- file = p_path.get_file().get_basename() + ".mem";
}
String dst = p_path.get_base_dir().plus_file(file);
@@ -288,9 +245,50 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
f->store_buffer(data.ptr(), data.size());
memdelete(f);
- ret = unzGoToNextFile(pkg);
+ } while (unzGoToNextFile(pkg) == UNZ_OK);
+ unzClose(pkg);
+
+ if (!custom_html.empty()) {
+
+ FileAccess *f = FileAccess::open(custom_html, FileAccess::READ);
+ if (!f) {
+ EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:\n") + custom_html);
+ return ERR_FILE_CANT_READ;
+ }
+ Vector<uint8_t> buf;
+ buf.resize(f->get_len());
+ f->get_buffer(buf.ptrw(), buf.size());
+ memdelete(f);
+ _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug);
+
+ f = FileAccess::open(p_path, FileAccess::WRITE);
+ if (!f) {
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + p_path);
+ return ERR_FILE_CANT_WRITE;
+ }
+ f->store_buffer(buf.ptr(), buf.size());
+ memdelete(f);
}
+ Ref<Image> splash;
+ String splash_path = GLOBAL_GET("application/boot_splash/image");
+ splash_path = splash_path.strip_edges();
+ if (!splash_path.empty()) {
+ splash.instance();
+ Error err = splash->load(splash_path);
+ if (err) {
+ EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:\n") + splash_path + "\nUsing default boot splash image");
+ splash.unref();
+ }
+ }
+ if (splash.is_null()) {
+ splash = Ref<Image>(memnew(Image(boot_splash_png)));
+ }
+ String png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png");
+ if (splash->save_png(png_path) != OK) {
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + png_path);
+ return ERR_FILE_CANT_WRITE;
+ }
return OK;
}
@@ -319,7 +317,7 @@ int EditorExportPlatformJavaScript::get_device_count() const {
Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) {
- String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp_export.html";
+ String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_export.html");
Error err = export_project(p_preset, true, path, p_debug_flags);
if (err) {
return err;
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index 0b105dcb40..b170ba6f35 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -37,16 +37,31 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
WARN_PRINT("Disabling HTTPClient's host verification is not supported for the HTML5 platform, host will be verified");
}
+ port = p_port;
+ use_tls = p_ssl;
+
host = p_host;
- if (host.begins_with("http://")) {
- host.replace_first("http://", "");
- } else if (host.begins_with("https://")) {
- host.replace_first("https://", "");
+
+ String host_lower = host.to_lower();
+ if (host_lower.begins_with("http://")) {
+ host = host.substr(7, host.length() - 7);
+ } else if (host_lower.begins_with("https://")) {
+ use_tls = true;
+ host = host.substr(8, host.length() - 8);
+ }
+
+ ERR_FAIL_COND_V(host.length() < HOST_MIN_LEN, ERR_INVALID_PARAMETER);
+
+ if (port < 0) {
+ if (use_tls) {
+ port = PORT_HTTPS;
+ } else {
+ port = PORT_HTTP;
+ }
}
status = host.is_valid_ip_address() ? STATUS_CONNECTING : STATUS_RESOLVING;
- port = p_port;
- use_tls = p_ssl;
+
return OK;
}
@@ -68,17 +83,7 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(host.empty(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
-
- static const char *_methods[HTTPClient::METHOD_MAX] = {
- "GET",
- "HEAD",
- "POST",
- "PUT",
- "DELETE",
- "OPTIONS",
- "TRACE",
- "CONNECT"
- };
+ ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + "/" + p_url;
godot_xhr_reset(xhr_id);
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index 1d737879f6..9fc23a6747 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -29,16 +29,9 @@
/*************************************************************************/
#ifdef JAVASCRIPT_EVAL_ENABLED
-#include "javascript_eval.h"
+#include "api/javascript_eval.h"
#include "emscripten.h"
-JavaScript *JavaScript::singleton = NULL;
-
-JavaScript *JavaScript::get_singleton() {
-
- return singleton;
-}
-
extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_poolbytearray_and_open_write(PoolByteArray *p_arr, PoolByteArray::Write *r_write, int p_len) {
p_arr->resize(p_len);
@@ -52,7 +45,7 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
bool b;
double d;
char *s;
- } js_data[4];
+ } js_data;
PoolByteArray arr;
PoolByteArray::Write arr_write;
@@ -63,9 +56,8 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
const CODE = $0;
const USE_GLOBAL_EXEC_CONTEXT = $1;
const PTR = $2;
- const ELEM_LEN = $3;
- const BYTEARRAY_PTR = $4;
- const BYTEARRAY_WRITE_PTR = $5;
+ const BYTEARRAY_PTR = $3;
+ const BYTEARRAY_WRITE_PTR = $4;
var eval_ret;
try {
if (USE_GLOBAL_EXEC_CONTEXT) {
@@ -125,56 +117,25 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
HEAPU8.set(eval_ret, bytes_ptr);
return 20; // POOL_BYTE_ARRAY
}
-
- if (typeof eval_ret.x==='number' && typeof eval_ret.y==='number') {
- setValue(PTR, eval_ret.x, 'double');
- setValue(PTR + ELEM_LEN, eval_ret.y, 'double');
- if (typeof eval_ret.z==='number') {
- setValue(PTR + ELEM_LEN*2, eval_ret.z, 'double');
- return 7; // VECTOR3
- }
- else if (typeof eval_ret.width==='number' && typeof eval_ret.height==='number') {
- setValue(PTR + ELEM_LEN*2, eval_ret.width, 'double');
- setValue(PTR + ELEM_LEN*3, eval_ret.height, 'double');
- return 6; // RECT2
- }
- return 5; // VECTOR2
- }
-
- if (typeof eval_ret.r === 'number' && typeof eval_ret.g === 'number' && typeof eval_ret.b === 'number') {
- setValue(PTR, eval_ret.r, 'double');
- setValue(PTR + ELEM_LEN, eval_ret.g, 'double');
- setValue(PTR + ELEM_LEN*2, eval_ret.b, 'double');
- setValue(PTR + ELEM_LEN*3, typeof eval_ret.a === 'number' ? eval_ret.a : 1, 'double');
- return 14; // COLOR
- }
break;
}
return 0; // NIL
- }, p_code.utf8().get_data(), p_use_global_exec_context, js_data, sizeof *js_data, &arr, &arr_write));
+ }, p_code.utf8().get_data(), p_use_global_exec_context, &js_data, &arr, &arr_write));
/* clang-format on */
switch (return_type) {
case Variant::BOOL:
- return js_data->b;
+ return js_data.b;
case Variant::REAL:
- return js_data->d;
+ return js_data.d;
case Variant::STRING: {
- String str = String::utf8(js_data->s);
+ String str = String::utf8(js_data.s);
/* clang-format off */
- EM_ASM_({ _free($0); }, js_data->s);
+ EM_ASM_({ _free($0); }, js_data.s);
/* clang-format on */
return str;
}
- case Variant::VECTOR2:
- return Vector2(js_data[0].d, js_data[1].d);
- case Variant::VECTOR3:
- return Vector3(js_data[0].d, js_data[1].d, js_data[2].d);
- case Variant::RECT2:
- return Rect2(js_data[0].d, js_data[1].d, js_data[2].d, js_data[3].d);
- case Variant::COLOR:
- return Color(js_data[0].d, js_data[1].d, js_data[2].d, js_data[3].d);
case Variant::POOL_BYTE_ARRAY:
arr_write = PoolByteArray::Write();
return arr;
@@ -182,18 +143,4 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
return Variant();
}
-void JavaScript::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, false);
-}
-
-JavaScript::JavaScript() {
-
- ERR_FAIL_COND(singleton != NULL);
- singleton = this;
-}
-
-JavaScript::~JavaScript() {
-}
-
#endif // JAVASCRIPT_EVAL_ENABLED
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index ed4f416cfd..5c5d608524 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -61,7 +61,6 @@ int main(int argc, char *argv[]) {
// run the 'main_after_fs_sync' function
/* clang-format off */
EM_ASM(
- Module.noExitRuntime = true;
FS.mkdir('/userfs');
FS.mount(IDBFS, {}, '/userfs');
FS.syncfs(true, function(err) {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 77d81aec5d..3b02bfd862 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -80,10 +80,6 @@ void OS_JavaScript::initialize_core() {
FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
}
-void OS_JavaScript::initialize_logger() {
- _set_logger(memnew(StdLogger));
-}
-
void OS_JavaScript::set_opengl_extensions(const char *p_gl_extensions) {
ERR_FAIL_COND(!p_gl_extensions);
@@ -205,7 +201,7 @@ static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *m
ev->set_position(pos);
ev->set_global_position(ev->get_position());
- ev->set_relative(_input->get_mouse_position() - ev->get_position());
+ ev->set_relative(ev->get_position() - _input->get_mouse_position());
_input->set_mouse_position(ev->get_position());
ev->set_speed(_input->get_last_mouse_speed());
@@ -340,7 +336,7 @@ static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *t
ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
ev_mouse->set_global_position(ev_mouse->get_position());
- ev_mouse->set_relative(_input->get_mouse_position() - ev_mouse->get_position());
+ ev_mouse->set_relative(ev_mouse->get_position() - _input->get_mouse_position());
_input->set_mouse_position(ev_mouse->get_position());
ev_mouse->set_speed(_input->get_last_mouse_speed());
@@ -438,25 +434,23 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
video_mode = p_desired;
// can't fulfil fullscreen request due to browser security
video_mode.fullscreen = false;
- set_window_size(Size2(p_desired.width, p_desired.height));
+ /* clang-format off */
+ bool resize_canvas_on_start = EM_ASM_INT_V(
+ return Module.resizeCanvasOnStart;
+ );
+ /* clang-format on */
+ if (resize_canvas_on_start) {
+ set_window_size(Size2(video_mode.width, video_mode.height));
+ } else {
+ Size2 canvas_size = get_window_size();
+ video_mode.width = canvas_size.width;
+ video_mode.height = canvas_size.height;
+ }
- // find locale, emscripten only sets "C"
char locale_ptr[16];
/* clang-format off */
- EM_ASM_({
- var locale = "";
- if (Module.locale) {
- // best case: server-side script reads Accept-Language early and
- // defines the locale to be read here
- locale = Module.locale;
- } else {
- // no luck, use what the JS engine can tell us
- // if this turns out not compatible enough, add tests for
- // browserLanguage, systemLanguage and userLanguage
- locale = navigator.languages ? navigator.languages[0] : navigator.language;
- }
- locale = locale.split('.')[0];
- stringToUTF8(locale, $0, 16);
+ EM_ASM_ARGS({
+ stringToUTF8(Module.locale, $0, 16);
}, locale_ptr);
/* clang-format on */
setenv("LANG", locale_ptr, true);
@@ -512,11 +506,6 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
#undef SET_EM_CALLBACK
#undef EM_CHECK
-#ifdef JAVASCRIPT_EVAL_ENABLED
- javascript_eval = memnew(JavaScript);
- Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval));
-#endif
-
visual_server->init();
}
@@ -889,11 +878,11 @@ String OS_JavaScript::get_resource_dir() const {
return "/"; //javascript has it's own filesystem for resources inside the APK
}
-String OS_JavaScript::get_data_dir() const {
+String OS_JavaScript::get_user_data_dir() const {
/*
- if (get_data_dir_func)
- return get_data_dir_func();
+ if (get_user_data_dir_func)
+ return get_user_data_dir_func();
*/
return "/userfs";
};
@@ -993,7 +982,7 @@ bool OS_JavaScript::is_userfs_persistent() const {
return idbfs_available;
}
-OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func) {
+OS_JavaScript::OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func) {
set_cmdline(p_execpath, get_cmdline_args());
main_loop = NULL;
gl_extensions = NULL;
@@ -1001,7 +990,7 @@ OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_d
soft_fs_enabled = false;
canvas_size_adjustment_requested = false;
- get_data_dir_func = p_get_data_dir_func;
+ get_user_data_dir_func = p_get_user_data_dir_func;
FileAccessUnix::close_notification_func = _close_notification_funcs;
idbfs_available = false;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index f478f95dd2..a95b069d03 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -32,7 +32,6 @@
#include "audio_driver_javascript.h"
#include "drivers/unix/os_unix.h"
-#include "javascript_eval.h"
#include "main/input_default.h"
#include "os/input.h"
#include "os/main_loop.h"
@@ -42,7 +41,7 @@
#include <emscripten/html5.h>
-typedef String (*GetDataDirFunc)();
+typedef String (*GetUserDataDirFunc)();
class OS_JavaScript : public OS_Unix {
@@ -63,14 +62,10 @@ class OS_JavaScript : public OS_Unix {
CursorShape cursor_shape;
MainLoop *main_loop;
- GetDataDirFunc get_data_dir_func;
+ GetUserDataDirFunc get_user_data_dir_func;
PowerJavascript *power_manager;
-#ifdef JAVASCRIPT_EVAL_ENABLED
- JavaScript *javascript_eval;
-#endif
-
static void _close_notification_funcs(const String &p_file, int p_flags);
void process_joypads();
@@ -86,7 +81,6 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -146,7 +140,7 @@ public:
void set_opengl_extensions(const char *p_gl_extensions);
virtual Error shell_open(String p_uri);
- virtual String get_data_dir() const;
+ virtual String get_user_data_dir() const;
String get_executable_path() const;
virtual String get_resource_dir() const;
@@ -165,7 +159,7 @@ public:
void set_idbfs_available(bool p_idbfs_available);
- OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func);
+ OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func);
~OS_JavaScript();
};
diff --git a/platform/javascript/power_javascript.cpp b/platform/javascript/power_javascript.cpp
index 10964502d4..54fceb75f4 100644
--- a/platform/javascript/power_javascript.cpp
+++ b/platform/javascript/power_javascript.cpp
@@ -63,8 +63,10 @@ int PowerJavascript::get_power_percent_left() {
}
}
-PowerJavascript::PowerJavascript()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerJavascript::PowerJavascript() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
PowerJavascript::~PowerJavascript() {
diff --git a/platform/javascript/pre_wasm.js b/platform/javascript/pre.js
index be4383c8c9..311aa44fda 100644
--- a/platform/javascript/pre_wasm.js
+++ b/platform/javascript/pre.js
@@ -1,3 +1,2 @@
var Engine = {
- USING_WASM: true,
RuntimeEnvironment: function(Module) {
diff --git a/platform/javascript/pre_asmjs.js b/platform/javascript/pre_asmjs.js
deleted file mode 100644
index 3c497721b6..0000000000
--- a/platform/javascript/pre_asmjs.js
+++ /dev/null
@@ -1,3 +0,0 @@
-var Engine = {
- USING_WASM: false,
- RuntimeEnvironment: function(Module) {
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index be3950bc6d..029e3d808c 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -4,7 +4,12 @@ import os
Import('env')
def make_debug(target, source, env):
- os.system('dsymutil %s -o %s.dSYM' % (target[0], target[0]))
+ if (env["macports_clang"] != 'no'):
+ mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
+ mpclangver = env["macports_clang"]
+ os.system(mpprefix + '/libexec/llvm-' + mpclangver + '/bin/llvm-dsymutil %s -o %s.dSYM' % (target[0], target[0]))
+ else:
+ os.system('dsymutil %s -o %s.dSYM' % (target[0], target[0]))
files = [
'crash_handler_osx.mm',
@@ -16,7 +21,8 @@ files = [
'power_osx.cpp',
]
-binary = env.Program('#bin/godot', files)
+prog = env.add_program('#bin/godot', files)
+
if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes":
- env.AddPostAction(binary, make_debug)
+ env.AddPostAction(prog, make_debug)
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index c24bd98bf6..e8a8319431 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -72,6 +72,19 @@ def configure(env):
else: # 64-bit, default
env.Append(CCFLAGS=['-arch', 'x86_64'])
env.Append(LINKFLAGS=['-arch', 'x86_64'])
+ if (env["macports_clang"] != 'no'):
+ mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
+ mpclangver = env["macports_clang"]
+ env["CC"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang"
+ env["LD"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++"
+ env["CXX"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++"
+ env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar"
+ env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib"
+ env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as"
+ env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define
+ if (env["openmp"]):
+ env.Append(CPPFLAGS=['-fopenmp'])
+ env.Append(LINKFLAGS=['-fopenmp'])
else: # osxcross build
root = os.environ.get("OSXCROSS_ROOT", 0)
@@ -110,7 +123,7 @@ def configure(env):
## Flags
env.Append(CPPPATH=['#platform/osx'])
- env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED'])
+ env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED'])
env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
env.Append(LIBS=['pthread'])
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 8a6f1dc04c..8a09aa634e 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -74,7 +74,7 @@ public:
virtual String get_os_name() const { return "OSX"; }
virtual Ref<Texture> get_logo() const { return logo; }
- virtual String get_binary_extension() const { return use_dmg() ? "dmg" : "zip"; }
+ virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const { return use_dmg() ? "dmg" : "zip"; }
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
@@ -160,7 +160,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
copy->convert(Image::FORMAT_RGBA8);
copy->resize(size, size);
it->create_from_image(copy);
- String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/icon.png";
+ String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png");
ResourceSaver::save(path, it);
FileAccess *f = FileAccess::open(path, FileAccess::READ);
@@ -288,6 +288,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
}
Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String src_pkg_name;
@@ -344,7 +345,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (use_dmg()) {
// We're on OSX so we can export to DMG, but first we create our application bundle
- tmp_app_path_name = EditorSettings::get_singleton()->get_settings_path() + "/tmp/" + pkg_name + ".app";
+ tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app");
print_line("Exporting to " + tmp_app_path_name);
DirAccess *tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
if (!tmp_app_path) {
@@ -389,7 +390,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
//read
unzOpenCurrentFile(src_pkg_zip);
- unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size());
+ unzReadCurrentFile(src_pkg_zip, data.ptrw(), data.size());
unzCloseCurrentFile(src_pkg_zip);
//write
@@ -539,7 +540,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
OS::get_singleton()->move_to_trash(tmp_app_path_name);
} else {
- String pack_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/" + pkg_name + ".pck";
+ String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck");
Error err = save_pack(p_preset, pack_path);
if (err == OK) {
@@ -604,6 +605,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
if (!err.empty())
r_error = err;
+ r_missing_templates = !valid;
return valid;
}
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 1df847eb79..ede50a05ba 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -43,7 +43,6 @@
#include "servers/visual_server.h"
#include <ApplicationServices/ApplicationServices.h>
-//bitch
#undef CursorShape
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -121,7 +120,6 @@ protected:
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
virtual void finalize();
@@ -154,6 +152,11 @@ public:
virtual MainLoop *get_main_loop() const;
+ virtual String get_config_path() const;
+ virtual String get_data_path() const;
+ virtual String get_cache_path() const;
+ virtual String get_godot_dir_name() const;
+
virtual String get_system_dir(SystemDir p_dir) const;
virtual bool can_draw() const;
@@ -201,7 +204,7 @@ public:
virtual void request_attention();
virtual String get_joy_guid(int p_device) const;
- virtual void set_borderless_window(int p_borderless);
+ virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window();
virtual void set_ime_position(const Point2 &p_pos);
virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp);
@@ -225,6 +228,8 @@ public:
virtual Error move_to_trash(const String &p_path);
+ void force_process_input();
+
OS_OSX();
private:
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 2e0e2620be..f3809e6eed 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -36,6 +36,7 @@
#include "print_string.h"
#include "sem_osx.h"
#include "servers/visual/visual_server_raster.h"
+#include "version_generated.gen.h"
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
@@ -84,6 +85,15 @@ static int prev_mouse_y = 0;
static int button_mask = 0;
static bool mouse_down_control = false;
+static Vector2 get_mouse_pos(NSEvent *event) {
+
+ const NSRect contentRect = [OS_OSX::singleton->window_view frame];
+ const NSPoint p = [event locationInWindow];
+ mouse_x = p.x * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
+ mouse_y = (contentRect.size.height - p.y) * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
+ return Vector2(mouse_x, mouse_y);
+}
+
@interface GodotApplication : NSApplication
@end
@@ -507,12 +517,9 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
mm->set_button_mask(button_mask);
prev_mouse_x = mouse_x;
prev_mouse_y = mouse_y;
- const NSRect contentRect = [OS_OSX::singleton->window_view frame];
- const NSPoint p = [event locationInWindow];
- mouse_x = p.x * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- mouse_y = (contentRect.size.height - p.y) * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- mm->set_position(Vector2(mouse_x, mouse_y));
- mm->set_global_position(Vector2(mouse_x, mouse_y));
+ const Vector2 pos = get_mouse_pos(event);
+ mm->set_position(pos);
+ mm->set_global_position(pos);
Vector2 relativeMotion = Vector2();
relativeMotion.x = [event deltaX] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
relativeMotion.y = [event deltaY] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
@@ -574,6 +581,15 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
OS_OSX::singleton->input->set_mouse_in_window(true);
}
+- (void)magnifyWithEvent:(NSEvent *)event {
+ Ref<InputEventMagnifyGesture> ev;
+ ev.instance();
+ get_key_modifier_state([event modifierFlags], ev);
+ ev->set_position(get_mouse_pos(event));
+ ev->set_factor([event magnification] + 1.0);
+ OS_OSX::singleton->push_input(ev);
+}
+
- (void)viewDidChangeBackingProperties {
// nothing left to do here
}
@@ -837,6 +853,18 @@ inline void sendScrollEvent(int button, double factor, int modifierFlags) {
OS_OSX::singleton->push_input(sc);
}
+inline void sendPanEvent(double dx, double dy, int modifierFlags) {
+
+ Ref<InputEventPanGesture> pg;
+ pg.instance();
+
+ get_key_modifier_state(modifierFlags, pg);
+ Vector2 mouse_pos = Vector2(mouse_x, mouse_y);
+ pg->set_position(mouse_pos);
+ pg->set_delta(Vector2(-dx, -dy));
+ OS_OSX::singleton->push_input(pg);
+}
+
- (void)scrollWheel:(NSEvent *)event {
double deltaX, deltaY;
@@ -855,11 +883,16 @@ inline void sendScrollEvent(int button, double factor, int modifierFlags) {
deltaX = [event deltaX];
deltaY = [event deltaY];
}
- if (fabs(deltaX)) {
- sendScrollEvent(0 > deltaX ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]);
- }
- if (fabs(deltaY)) {
- sendScrollEvent(0 < deltaY ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]);
+
+ if ([event phase] != NSEventPhaseNone || [event momentumPhase] != NSEventPhaseNone) {
+ sendPanEvent(deltaX, deltaY, [event modifierFlags]);
+ } else {
+ if (fabs(deltaX)) {
+ sendScrollEvent(0 > deltaX ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]);
+ }
+ if (fabs(deltaY)) {
+ sendScrollEvent(0 < deltaY ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]);
+ }
}
}
@@ -896,7 +929,7 @@ int OS_OSX::get_video_driver_count() const {
const char *OS_OSX::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ return "GLES3";
}
void OS_OSX::initialize_core() {
@@ -995,7 +1028,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
// OS X needs non-zero color size, so set resonable values
int colorBits = 32;
-// Fail if a robustness strategy was requested
+ // Fail if a robustness strategy was requested
#define ADD_ATTR(x) \
{ attributes[attributeCount++] = x; }
@@ -1056,6 +1089,8 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
[context makeCurrentContext];
+ set_use_vsync(p_desired.use_vsync);
+
[NSApp activateIgnoringOtherApps:YES];
_update_window();
@@ -1066,8 +1101,6 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
zoomed = true;
/*** END OSX INITIALIZATION ***/
- /*** END OSX INITIALIZATION ***/
- /*** END OSX INITIALIZATION ***/
bool use_gl2 = p_video_driver != 1;
@@ -1077,16 +1110,12 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
- //rasterizer = instance_RasterizerGLES2();
- //visual_server = memnew( VisualServerRaster(rasterizer) );
-
visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
visual_server->init();
- // visual_server->cursor_set_visible(false, 0);
AudioDriverManager::initialize(p_audio_driver);
@@ -1095,7 +1124,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
power_manager = memnew(power_osx);
- _ensure_data_dir();
+ _ensure_user_data_dir();
restore_rect = Rect2(get_window_position(), get_window_size());
}
@@ -1190,15 +1219,6 @@ public:
typedef UnixTerminalLogger OSXTerminalLogger;
#endif
-void OS_OSX::initialize_logger() {
- Vector<Logger *> loggers;
- loggers.push_back(memnew(OSXTerminalLogger));
- // FIXME: Reenable once we figure out how to get this properly in user://
- // instead of littering the user's working dirs (res:// + pwd) with log files (GH-12277)
- //loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
void OS_OSX::alert(const String &p_alert, const String &p_title) {
// Set OS X-compliant variables
NSAlert *window = [[NSAlert alloc] init];
@@ -1340,6 +1360,43 @@ MainLoop *OS_OSX::get_main_loop() const {
return main_loop;
}
+String OS_OSX::get_config_path() const {
+
+ if (has_environment("XDG_CONFIG_HOME")) {
+ return get_environment("XDG_CONFIG_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file("Library/Application Support");
+ } else {
+ return ".";
+ }
+}
+
+String OS_OSX::get_data_path() const {
+
+ if (has_environment("XDG_DATA_HOME")) {
+ return get_environment("XDG_DATA_HOME");
+ } else {
+ return get_config_path();
+ }
+}
+
+String OS_OSX::get_cache_path() const {
+
+ if (has_environment("XDG_CACHE_HOME")) {
+ return get_environment("XDG_CACHE_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file("Library/Caches");
+ } else {
+ return get_config_path();
+ }
+}
+
+// Get properly capitalized engine name for system paths
+String OS_OSX::get_godot_dir_name() const {
+
+ return String(VERSION_SHORT_NAME).capitalize();
+}
+
String OS_OSX::get_system_dir(SystemDir p_dir) const {
NSSearchPathDirectory id = 0;
@@ -1428,7 +1485,7 @@ void OS_OSX::make_rendering_thread() {
Error OS_OSX::shell_open(String p_uri) {
- [[NSWorkspace sharedWorkspace] openURL:[[NSURL alloc] initWithString:[NSString stringWithUTF8String:p_uri.utf8().get_data()]]];
+ [[NSWorkspace sharedWorkspace] openURL:[[NSURL alloc] initWithString:[[NSString stringWithUTF8String:p_uri.utf8().get_data()] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]];
return OK;
}
@@ -1761,7 +1818,7 @@ void OS_OSX::request_attention() {
[NSApp requestUserAttention:NSCriticalRequest];
}
-void OS_OSX::set_borderless_window(int p_borderless) {
+void OS_OSX::set_borderless_window(bool p_borderless) {
// OrderOut prevents a lose focus bug with the window
[window_object orderOut:nil];
@@ -1914,6 +1971,12 @@ void OS_OSX::push_input(const Ref<InputEvent> &p_event) {
input->parse_input_event(ev);
}
+void OS_OSX::force_process_input() {
+
+ process_events(); // get rid of pending events
+ joypad_osx->process_joypads();
+}
+
void OS_OSX::run() {
force_quit = false;
@@ -2110,7 +2173,9 @@ OS_OSX::OS_OSX() {
window_size = Vector2(1024, 600);
zoomed = false;
- _set_logger(memnew(OSXTerminalLogger));
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(OSXTerminalLogger));
+ _set_logger(memnew(CompositeLogger(loggers)));
}
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp
index eed03e63c1..bd5f9fe65f 100644
--- a/platform/osx/power_osx.cpp
+++ b/platform/osx/power_osx.cpp
@@ -242,8 +242,10 @@ int power_osx::get_power_percent_left() {
}
}
-power_osx::power_osx()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+power_osx::power_osx() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
power_osx::~power_osx() {
diff --git a/platform/windows/tcp_server_winsock.h b/platform/register_platform_apis.h
index a3e01098ed..37f98f6cd3 100644
--- a/platform/windows/tcp_server_winsock.h
+++ b/platform/register_platform_apis.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* tcp_server_winsock.h */
+/* register_platform_apis.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,30 +27,10 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef TCP_SERVER_WINSOCK_H
-#define TCP_SERVER_WINSOCK_H
+#ifndef REGISTER_APIS_H
+#define REGISTER_APIS_H
-#include "core/io/tcp_server.h"
-
-class TCPServerWinsock : public TCP_Server {
-
- int listen_sockfd;
- IP::Type sock_type;
-
- static TCP_Server *_create();
-
-public:
- virtual Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*"));
- virtual bool is_connection_available() const;
- virtual Ref<StreamPeerTCP> take_connection();
-
- virtual void stop(); //stop listening
-
- static void make_default();
- static void cleanup();
-
- TCPServerWinsock();
- ~TCPServerWinsock();
-};
+void register_platform_apis();
+void unregister_platform_apis();
#endif
diff --git a/platform/server/SCsub b/platform/server/SCsub
index 30195bb908..30d8cc8064 100644
--- a/platform/server/SCsub
+++ b/platform/server/SCsub
@@ -7,4 +7,4 @@ common_server = [\
"os_server.cpp",\
]
-env.Program('#bin/godot_server', ['godot_server.cpp'] + common_server)
+prog = env.add_program('#bin/godot_server', ['godot_server.cpp'] + common_server)
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index ca73f610e4..5b852af738 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -73,7 +73,7 @@ void OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p
input = memnew(InputDefault);
- _ensure_data_dir();
+ _ensure_user_data_dir();
}
void OS_Server::finalize() {
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 03f7c2a6c8..40b10c019f 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -38,7 +38,6 @@
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
-//bitch
#undef CursorShape
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub
index bbd329a7e5..fb0c4a92ae 100644
--- a/platform/uwp/SCsub
+++ b/platform/uwp/SCsub
@@ -4,9 +4,6 @@ Import('env')
files = [
'thread_uwp.cpp',
- '#platform/windows/tcp_server_winsock.cpp',
- '#platform/windows/packet_peer_udp_winsock.cpp',
- '#platform/windows/stream_peer_winsock.cpp',
'#platform/windows/key_mapping_win.cpp',
'#platform/windows/windows_terminal_logger.cpp',
'joypad_uwp.cpp',
@@ -19,7 +16,7 @@ files = [
if "build_angle" in env and env["build_angle"]:
cmd = env.AlwaysBuild(env.ANGLE('libANGLE.lib', None))
-prog = env.Program('#bin/godot', files)
+prog = env.add_program('#bin/godot', files)
if "build_angle" in env and env["build_angle"]:
env.Depends(prog, [cmd])
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index c565999d82..b47b99744e 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -77,15 +77,15 @@ public:
return 0;
}
-App::App()
- : mWindowClosed(false),
- mWindowVisible(true),
- mWindowWidth(0),
- mWindowHeight(0),
- mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE),
- number_of_contacts(0) {
+App::App() :
+ mWindowClosed(false),
+ mWindowVisible(true),
+ mWindowWidth(0),
+ mWindowHeight(0),
+ mEglDisplay(EGL_NO_DISPLAY),
+ mEglContext(EGL_NO_CONTEXT),
+ mEglSurface(EGL_NO_SURFACE),
+ number_of_contacts(0) {
}
// The first method called when the IFrameworkView is being created.
diff --git a/platform/uwp/app.h b/platform/uwp/app.h
index e079fa9c9d..b812512a98 100644
--- a/platform/uwp/app.h
+++ b/platform/uwp/app.h
@@ -33,6 +33,7 @@
#include <wrl.h>
+// ANGLE doesn't provide a specific lib for GLES3, so we keep using GLES2
#include "GLES2/gl2.h"
#include "os_uwp.h"
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 434c597449..7cc8afff06 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -136,7 +136,7 @@ def configure(env):
env.Append(CPPPATH=['#platform/uwp', '#drivers/windows'])
env.Append(CCFLAGS=['/DUWP_ENABLED', '/DWINDOWS_ENABLED', '/DTYPED_METHOD_BIND'])
- env.Append(CCFLAGS=['/DGLES2_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED'])
+ env.Append(CCFLAGS=['/DGLES_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED'])
winver = "0x0602" # Windows 8 is the minimum target for UWP build
env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index d66bcaa91c..45ca097de5 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -137,7 +137,7 @@ class AppxPackager {
ZPOS64_T end_of_central_dir_offset;
Vector<uint8_t> central_dir_data;
- String hash_block(uint8_t *p_block_data, size_t p_block_len);
+ String hash_block(const uint8_t *p_block_data, size_t p_block_len);
void make_block_map();
void make_content_types();
@@ -188,14 +188,14 @@ public:
///////////////////////////////////////////////////////////////////////////
-String AppxPackager::hash_block(uint8_t *p_block_data, size_t p_block_len) {
+String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) {
char hash[32];
char base64[45];
sha256_context ctx;
sha256_init(&ctx);
- sha256_hash(&ctx, p_block_data, p_block_len);
+ sha256_hash(&ctx, (uint8_t *)p_block_data, p_block_len);
sha256_done(&ctx, (uint8_t *)hash);
base64_encode(base64, hash, 32);
@@ -456,8 +456,8 @@ void AppxPackager::init(FileAccess *p_fa) {
package = p_fa;
central_dir_offset = 0;
end_of_central_dir_offset = 0;
- tmp_blockmap_file_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpblockmap.xml";
- tmp_content_types_file_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpcontenttypes.xml";
+ tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml");
+ tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml");
}
void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) {
@@ -510,8 +510,8 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
strm.avail_in = block_size;
strm.avail_out = strm_out.size();
- strm.next_in = strm_in.ptr();
- strm.next_out = strm_out.ptr();
+ strm.next_in = (uint8_t *)strm_in.ptr();
+ strm.next_out = strm_out.ptrw();
int total_out_before = strm.total_out;
@@ -541,8 +541,8 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
strm.avail_in = 0;
strm.avail_out = strm_out.size();
- strm.next_in = strm_in.ptr();
- strm.next_out = strm_out.ptr();
+ strm.next_in = (uint8_t *)strm_in.ptr();
+ strm.next_out = strm_out.ptrw();
int total_out_before = strm.total_out;
@@ -588,7 +588,7 @@ void AppxPackager::finish() {
Vector<uint8_t> blockmap_buffer;
blockmap_buffer.resize(blockmap_file->get_len());
- blockmap_file->get_buffer(blockmap_buffer.ptr(), blockmap_buffer.size());
+ blockmap_file->get_buffer(blockmap_buffer.ptrw(), blockmap_buffer.size());
add_file("AppxBlockMap.xml", blockmap_buffer.ptr(), blockmap_buffer.size(), -1, -1, true);
@@ -604,7 +604,7 @@ void AppxPackager::finish() {
Vector<uint8_t> types_buffer;
types_buffer.resize(types_file->get_len());
- types_file->get_buffer(types_buffer.ptr(), types_buffer.size());
+ types_file->get_buffer(types_buffer.ptrw(), types_buffer.size());
add_file("[Content_Types].xml", types_buffer.ptr(), types_buffer.size(), -1, -1, true);
@@ -886,7 +886,7 @@ class EditorExportUWP : public EditorExportPlatform {
if (!image) return data;
- String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/uwp_tmp_logo.png");
+ String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("uwp_tmp_logo.png");
Error err = image->get_data()->save_png(tmp_path);
@@ -911,7 +911,7 @@ class EditorExportUWP : public EditorExportPlatform {
}
data.resize(f->get_len());
- f->get_buffer(data.ptr(), data.size());
+ f->get_buffer(data.ptrw(), data.size());
f->close();
memdelete(f);
@@ -1013,7 +1013,7 @@ public:
return "UWP";
}
- virtual String get_binary_extension() const {
+ virtual String get_binary_extension(const Ref<EditorExportPreset> &p_preset) const {
return "appx";
}
@@ -1301,7 +1301,7 @@ public:
if (do_read) {
data.resize(info.uncompressed_size);
unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptr(), data.size());
+ unzReadCurrentFile(pkg, data.ptrw(), data.size());
unzCloseCurrentFile(pkg);
}
@@ -1341,7 +1341,7 @@ public:
// Argc
clf.resize(4);
- encode_uint32(cl.size(), clf.ptr());
+ encode_uint32(cl.size(), clf.ptrw());
for (int i = 0; i < cl.size(); i++) {
diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp
index dafe5d5e25..2130af6d60 100644
--- a/platform/uwp/gl_context_egl.cpp
+++ b/platform/uwp/gl_context_egl.cpp
@@ -108,7 +108,8 @@ Error ContextEGL::initialize() {
EGL_NONE,*/
// These are the default display attributes, used to request ANGLE's D3D11 renderer.
// eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
- EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+ EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
@@ -117,7 +118,8 @@ Error ContextEGL::initialize() {
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
- EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
+ EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
+ EGL_TRUE,
EGL_NONE,
};
@@ -190,10 +192,10 @@ void ContextEGL::cleanup() {
}
};
-ContextEGL::ContextEGL(CoreWindow ^ p_window)
- : mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE) {
+ContextEGL::ContextEGL(CoreWindow ^ p_window) :
+ mEglDisplay(EGL_NO_DISPLAY),
+ mEglContext(EGL_NO_CONTEXT),
+ mEglSurface(EGL_NO_SURFACE) {
window = p_window;
};
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
index 0f84bd55a3..088d232e04 100644
--- a/platform/uwp/joypad_uwp.cpp
+++ b/platform/uwp/joypad_uwp.cpp
@@ -54,7 +54,7 @@ void JoypadUWP::process_controllers() {
case ControllerType::GAMEPAD_CONTROLLER: {
- GamepadReading reading = ((Gamepad ^)joy.controller_reference)->GetCurrentReading();
+ GamepadReading reading = ((Gamepad ^) joy.controller_reference)->GetCurrentReading();
int button_mask = (int)GamepadButtons::Menu;
for (int j = 0; j < 14; j++) {
@@ -161,7 +161,7 @@ void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, flo
GamepadVibration vibration;
vibration.LeftMotor = p_strong_magnitude;
vibration.RightMotor = p_weak_magnitude;
- ((Gamepad ^)joy.controller_reference)->Vibration = vibration;
+ ((Gamepad ^) joy.controller_reference)->Vibration = vibration;
joy.ff_timestamp = p_timestamp;
joy.ff_end_timestamp = p_duration == 0 ? 0 : p_timestamp + (uint64_t)(p_duration * 1000000.0);
@@ -175,7 +175,7 @@ void JoypadUWP::joypad_vibration_stop(int p_device, uint64_t p_timestamp) {
GamepadVibration vibration;
vibration.LeftMotor = 0.0;
vibration.RightMotor = 0.0;
- ((Gamepad ^)joy.controller_reference)->Vibration = vibration;
+ ((Gamepad ^) joy.controller_reference)->Vibration = vibration;
joy.ff_timestamp = p_timestamp;
joy.vibrating = false;
diff --git a/platform/uwp/logo.png b/platform/uwp/logo.png
index 4376abd563..9017a30636 100644
--- a/platform/uwp/logo.png
+++ b/platform/uwp/logo.png
Binary files differ
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index acb0ba4bca..3018ac0bef 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -28,18 +28,19 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "os_uwp.h"
+
#include "drivers/gles3/rasterizer_gles3.h"
#include "drivers/unix/ip_unix.h"
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
#include "drivers/windows/mutex_windows.h"
+#include "drivers/windows/packet_peer_udp_winsock.h"
#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
+#include "drivers/windows/stream_peer_tcp_winsock.h"
+#include "drivers/windows/tcp_server_winsock.h"
#include "io/marshalls.h"
#include "main/main.h"
-#include "platform/windows/packet_peer_udp_winsock.h"
-#include "platform/windows/stream_peer_winsock.h"
-#include "platform/windows/tcp_server_winsock.h"
#include "platform/windows/windows_terminal_logger.h"
#include "project_settings.h"
#include "servers/audio_server.h"
@@ -69,7 +70,7 @@ int OSUWP::get_video_driver_count() const {
}
const char *OSUWP::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ return "GLES3";
}
Size2 OSUWP::get_window_size() const {
@@ -162,7 +163,7 @@ void OSUWP::initialize_core() {
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
TCPServerWinsock::make_default();
- StreamPeerWinsock::make_default();
+ StreamPeerTCPWinsock::make_default();
PacketPeerUDPWinsock::make_default();
// We need to know how often the clock is updated
@@ -178,15 +179,6 @@ void OSUWP::initialize_core() {
cursor_shape = CURSOR_ARROW;
}
-void OSUWP::initialize_logger() {
- Vector<Logger *> loggers;
- loggers.push_back(memnew(WindowsTerminalLogger));
- // FIXME: Reenable once we figure out how to get this properly in user://
- // instead of littering the user's working dirs (res:// + pwd) with log files (GH-12277)
- //loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
bool OSUWP::can_draw() const {
return !minimized;
@@ -249,6 +241,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
+ gl_context->set_use_vsync(vm.use_vsync);
visual_server = memnew(VisualServerRaster);
// FIXME: Reimplement threaded rendering? Or remove?
@@ -298,7 +291,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud
ref new TypedEventHandler<Gyrometer ^, GyrometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_gyroscope_reading_changed);
}
- _ensure_data_dir();
+ _ensure_user_data_dir();
if (is_keep_screen_on())
display_request->RequestActive();
@@ -781,7 +774,7 @@ MainLoop *OSUWP::get_main_loop() const {
return main_loop;
}
-String OSUWP::get_data_dir() const {
+String OSUWP::get_user_data_dir() const {
Windows::Storage::StorageFolder ^ data_folder = Windows::Storage::ApplicationData::Current->LocalFolder;
@@ -833,7 +826,9 @@ OSUWP::OSUWP() {
AudioDriverManager::add_driver(&audio_driver);
- _set_logger(memnew(WindowsTerminalLogger));
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(WindowsTerminalLogger));
+ _set_logger(memnew(CompositeLogger(loggers)));
}
OSUWP::~OSUWP() {
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 2931e9b07d..8d69cd53fd 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -157,7 +157,6 @@ protected:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -226,7 +225,7 @@ public:
virtual String get_locale() const;
virtual void move_window_to_foreground();
- virtual String get_data_dir() const;
+ virtual String get_user_data_dir() const;
virtual bool _check_internal_feature_support(const String &p_feature);
diff --git a/platform/uwp/power_uwp.cpp b/platform/uwp/power_uwp.cpp
index 81e97b1391..14fce8b133 100644
--- a/platform/uwp/power_uwp.cpp
+++ b/platform/uwp/power_uwp.cpp
@@ -30,8 +30,10 @@
#include "power_uwp.h"
-PowerUWP::PowerUWP()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerUWP::PowerUWP() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
PowerUWP::~PowerUWP() {
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index aa9eb3e69b..604896b0db 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -4,9 +4,14 @@ import os
Import('env')
def make_debug_mingw(target, source, env):
- os.system('objcopy --only-keep-debug %s %s.debug' % (target[0], target[0]))
- os.system('strip --strip-debug --strip-unneeded %s' % (target[0]))
- os.system('objcopy --add-gnu-debuglink=%s.debug %s' % (target[0], target[0]))
+ mingw_prefix = ""
+ if (env["bits"] == "32"):
+ mingw_prefix = env["mingw_prefix_32"]
+ else:
+ mingw_prefix = env["mingw_prefix_64"]
+ os.system(mingw_prefix + 'objcopy --only-keep-debug %s %s.debugsymbols' % (target[0], target[0]))
+ os.system(mingw_prefix + 'strip --strip-debug --strip-unneeded %s' % (target[0]))
+ os.system(mingw_prefix + 'objcopy --add-gnu-debuglink=%s.debugsymbols %s' % (target[0], target[0]))
common_win = [
"context_gl_win.cpp",
@@ -14,9 +19,6 @@ common_win = [
"os_windows.cpp",
"ctxgl_procaddr.cpp",
"key_mapping_win.cpp",
- "tcp_server_winsock.cpp",
- "packet_peer_udp_winsock.cpp",
- "stream_peer_winsock.cpp",
"joypad.cpp",
"power_windows.cpp",
"windows_terminal_logger.cpp"
@@ -28,7 +30,7 @@ obj = env.RES(restarget, 'godot_res.rc')
common_win.append(obj)
-binary = env.Program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"])
+prog = env.add_program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"])
# Microsoft Visual Studio Project Generation
if env['vsproj']:
@@ -38,4 +40,4 @@ if env['vsproj']:
if not os.getenv("VCINSTALLDIR"):
if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes":
- env.AddPostAction(binary, make_debug_mingw)
+ env.AddPostAction(prog, make_debug_mingw)
diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp
index 8571f0dc65..ccb0a41d13 100644
--- a/platform/windows/context_gl_win.cpp
+++ b/platform/windows/context_gl_win.cpp
@@ -27,25 +27,12 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
-
-//
-// C++ Implementation: context_gl_x11
-//
-// Description:
-//
-//
+#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
+
// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
#include "context_gl_win.h"
-//#include "drivers/opengl/glwrapper.h"
-//#include "ctxgl_procaddr.h"
-
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
@@ -194,8 +181,6 @@ Error ContextGL_Win::initialize() {
MessageBox(NULL, "Can't Activate The GL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return ERR_CANT_CREATE; // Return FALSE
}
-
- printf("Activated GL 3.3 context");
}
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h
index 0059cbc311..5a280b0d08 100644
--- a/platform/windows/context_gl_win.h
+++ b/platform/windows/context_gl_win.h
@@ -27,18 +27,9 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
-//
-// C++ Interface: context_gl_x11
-//
-// Description:
-//
-//
+#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
+
// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
-//
-// Copyright: See COPYING file that comes with this distribution
-//
-//
#ifndef CONTEXT_GL_WIN_H
#define CONTEXT_GL_WIN_H
diff --git a/platform/windows/crash_handler_win.cpp b/platform/windows/crash_handler_win.cpp
index feea3911b2..5657036693 100644
--- a/platform/windows/crash_handler_win.cpp
+++ b/platform/windows/crash_handler_win.cpp
@@ -61,8 +61,8 @@ class symbol {
static const int max_name_len = 1024;
public:
- symbol(HANDLE process, DWORD64 address)
- : sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) {
+ symbol(HANDLE process, DWORD64 address) :
+ sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) {
memset(sym, '\0', sizeof(*sym) + max_name_len);
sym->SizeOfStruct = sizeof(*sym);
sym->MaxNameLength = max_name_len;
@@ -85,8 +85,8 @@ class get_mod_info {
HANDLE process;
public:
- get_mod_info(HANDLE h)
- : process(h) {}
+ get_mod_info(HANDLE h) :
+ process(h) {}
module_data operator()(HMODULE module) {
module_data ret;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index fbb02c9d1b..01eb50e69c 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -64,6 +64,10 @@ def get_opts():
return [
('mingw_prefix_32', 'MinGW prefix (Win32)', mingw32),
('mingw_prefix_64', 'MinGW prefix (Win64)', mingw64),
+ # Targeted Windows version: 7 (and later), minimum supported version
+ # XP support dropped after EOL due to missing API for IPv6 and other issues
+ # Vista support dropped after EOL due to GH-10243
+ ('target_win_version', 'Targeted Windows version, >= 0x0601 (Windows 7)', '0x0601'),
EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')),
]
@@ -97,11 +101,6 @@ def configure(env):
env.Append(CPPPATH=['#platform/windows'])
- # Targeted Windows version: 7 (and later), minimum supported version
- # XP support dropped after EOL due to missing API for IPv6 and other issues
- # Vista support dropped after EOL due to GH-10243
- winver = "0x0601"
-
if (os.name == "nt" and os.getenv("VCINSTALLDIR")): # MSVC
env['ENV']['TMP'] = os.environ['TMP']
@@ -175,7 +174,7 @@ def configure(env):
env.Append(CCFLAGS=['/DWASAPI_ENABLED'])
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
env.Append(CCFLAGS=['/DWIN32'])
- env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
+ env.Append(CCFLAGS=['/DWINVER=%s' % env['target_win_version'], '/D_WIN32_WINNT=%s' % env['target_win_version']])
if env["bits"] == "64":
env.Append(CCFLAGS=['/D_WIN64'])
@@ -189,6 +188,9 @@ def configure(env):
else:
VC_PATH = ""
+ if (env["openmp"]):
+ env.Append(CPPFLAGS=['/openmp'])
+
env.Append(CCFLAGS=["/I" + p for p in os.getenv("INCLUDE").split(";")])
env.Append(LIBPATH=[p for p in os.getenv("LIB").split(";")])
@@ -265,13 +267,17 @@ def configure(env):
env.Append(CCFLAGS=['-flto'])
env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
+ if (env["openmp"]):
+ env.Append(CPPFLAGS=['-fopenmp'])
+ env.Append(LINKFLAGS=['-fopenmp'])
+
## Compile flags
env.Append(CCFLAGS=['-DWINDOWS_ENABLED', '-mwindows'])
env.Append(CCFLAGS=['-DOPENGL_ENABLED'])
env.Append(CCFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DWASAPI_ENABLED'])
- env.Append(CCFLAGS=['-DWINVER=%s' % winver, '-D_WIN32_WINNT=%s' % winver])
+ env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']])
env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser'])
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 5301aa9e95..1b6a8f4a60 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -28,11 +28,135 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "editor/editor_export.h"
+#include "editor/editor_settings.h"
+#include "os/file_access.h"
+#include "os/os.h"
#include "platform/windows/logo.gen.h"
+class EditorExportPlatformWindows : public EditorExportPlatformPC {
+
+public:
+ virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
+ virtual void get_export_options(List<ExportOption> *r_options);
+};
+
+Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, p_path, p_flags);
+
+ if (err != OK) {
+ return err;
+ }
+
+ String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
+
+ if (rcedit_path == String()) {
+ return OK;
+ }
+
+ if (!FileAccess::exists(rcedit_path)) {
+ ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", aborting.");
+ return ERR_FILE_NOT_FOUND;
+ }
+
+#ifndef WINDOWS_ENABLED
+ // On non-Windows we need WINE to run rcedit
+ String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
+
+ if (wine_path != String() && !FileAccess::exists(wine_path)) {
+ ERR_PRINTS("Could not find wine executable at " + wine_path + ", aborting.");
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ if (wine_path == String()) {
+ wine_path = "wine"; // try to run wine from PATH
+ }
+#endif
+
+ String icon_path = p_preset->get("application/icon");
+ String file_verion = p_preset->get("application/file_version");
+ String product_version = p_preset->get("application/product_version");
+ String company_name = p_preset->get("application/company_name");
+ String product_name = p_preset->get("application/product_name");
+ String file_description = p_preset->get("application/file_description");
+ String copyright = p_preset->get("application/copyright");
+ String trademarks = p_preset->get("application/trademarks");
+ String comments = p_preset->get("application/comments");
+
+ List<String> args;
+ args.push_back(p_path);
+ if (icon_path != String()) {
+ args.push_back("--set-icon");
+ args.push_back(icon_path);
+ }
+ if (file_verion != String()) {
+ args.push_back("--set-file-version");
+ args.push_back(file_verion);
+ }
+ if (product_version != String()) {
+ args.push_back("--set-product-version");
+ args.push_back(product_version);
+ }
+ if (company_name != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("CompanyName");
+ args.push_back(company_name);
+ }
+ if (product_name != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("ProductName");
+ args.push_back(product_name);
+ }
+ if (file_description != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("FileDescription");
+ args.push_back(file_description);
+ }
+ if (copyright != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("LegalCopyright");
+ args.push_back(copyright);
+ }
+ if (trademarks != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("LegalTrademarks");
+ args.push_back(trademarks);
+ }
+
+#ifdef WINDOWS_ENABLED
+ OS::get_singleton()->execute(rcedit_path, args, true);
+#else
+ // On non-Windows we need WINE to run rcedit
+ args.push_front(rcedit_path);
+ OS::get_singleton()->execute(wine_path, args, true);
+#endif
+
+ return OK;
+}
+
+void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) {
+ EditorExportPlatformPC::get_export_options(r_options);
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_GLOBAL_FILE, "*.ico"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), String()));
+}
+
void register_windows_exporter() {
- Ref<EditorExportPlatformPC> platform;
+ EDITOR_DEF("export/windows/rcedit", "");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/rcedit", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
+#ifndef WINDOWS_ENABLED
+ // On non-Windows we need WINE to run rcedit
+ EDITOR_DEF("export/windows/wine", "");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/wine", PROPERTY_HINT_GLOBAL_FILE));
+#endif
+
+ Ref<EditorExportPlatformWindows> platform;
platform.instance();
Ref<Image> img = memnew(Image(_windows_logo));
diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc
index b86869d316..c535a749c0 100644
--- a/platform/windows/godot_res.rc
+++ b/platform/windows/godot_res.rc
@@ -23,13 +23,13 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Godot Engine"
- VALUE "FileDescription", _MKSTR(VERSION_NAME) " Editor"
+ VALUE "FileDescription", VERSION_NAME " Editor"
VALUE "FileVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH)
- VALUE "ProductName", _MKSTR(VERSION_NAME)
+ VALUE "ProductName", VERSION_NAME
VALUE "Licence", "MIT"
VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur"
- VALUE "Info", "http://www.godotengine.org"
- VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) PATCH_STRING "." _MKSTR(VERSION_REVISION)
+ VALUE "Info", "https://godotengine.org"
+ VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) PATCH_STRING "." VERSION_BUILD
END
END
BLOCK "VarFileInfo"
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 0f62dbb9e8..6cab683e83 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -34,19 +34,20 @@
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
#include "drivers/windows/mutex_windows.h"
+#include "drivers/windows/packet_peer_udp_winsock.h"
#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
+#include "drivers/windows/stream_peer_tcp_winsock.h"
+#include "drivers/windows/tcp_server_winsock.h"
#include "drivers/windows/thread_windows.h"
#include "io/marshalls.h"
#include "joypad.h"
#include "lang_table.h"
#include "main/main.h"
-#include "packet_peer_udp_winsock.h"
#include "servers/audio_server.h"
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
-#include "stream_peer_winsock.h"
-#include "tcp_server_winsock.h"
+#include "version_generated.gen.h"
#include "windows_terminal_logger.h"
#include <process.h>
@@ -68,6 +69,19 @@ __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001;
#define WM_TOUCH 576
#endif
+static String format_error_message(DWORD id) {
+
+ LPWSTR messageBuffer = NULL;
+ size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
+
+ String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
+
+ LocalFree(messageBuffer);
+
+ return msg;
+}
+
extern HINSTANCE godot_hinstance;
void RedirectIOToConsole() {
@@ -143,7 +157,7 @@ int OS_Windows::get_video_driver_count() const {
}
const char *OS_Windows::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ return "GLES3";
}
int OS_Windows::get_audio_driver_count() const {
@@ -182,7 +196,7 @@ void OS_Windows::initialize_core() {
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
TCPServerWinsock::make_default();
- StreamPeerWinsock::make_default();
+ StreamPeerTCPWinsock::make_default();
PacketPeerUDPWinsock::make_default();
// We need to know how often the clock is updated
@@ -200,15 +214,6 @@ void OS_Windows::initialize_core() {
cursor_shape = CURSOR_ARROW;
}
-void OS_Windows::initialize_logger() {
- Vector<Logger *> loggers;
- loggers.push_back(memnew(WindowsTerminalLogger));
- // FIXME: Reenable once we figure out how to get this properly in user://
- // instead of littering the user's working dirs (res:// + pwd) with log files (GH-12277)
- //loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
- _set_logger(memnew(CompositeLogger(loggers)));
-}
-
bool OS_Windows::can_draw() const {
return !minimized;
@@ -218,7 +223,17 @@ bool OS_Windows::can_draw() const {
#define SIGNATURE_MASK 0xFFFFFF00
#define IsPenEvent(dw) (((dw)&SIGNATURE_MASK) == MI_WP_SIGNATURE)
-void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
+void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) {
+
+ // Defensive
+ if (touch_state.has(idx) == p_pressed)
+ return;
+
+ if (p_pressed) {
+ touch_state.insert(idx, Vector2(p_x, p_y));
+ } else {
+ touch_state.erase(idx);
+ }
Ref<InputEventScreenTouch> event;
event.instance();
@@ -231,7 +246,17 @@ void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
}
};
-void OS_Windows::_drag_event(int p_x, int p_y, int idx) {
+void OS_Windows::_drag_event(float p_x, float p_y, int idx) {
+
+ Map<int, Vector2>::Element *curr = touch_state.find(idx);
+ // Defensive
+ if (!curr)
+ return;
+
+ if (curr->get() == Vector2(p_x, p_y))
+ return;
+
+ curr->get() = Vector2(p_x, p_y);
Ref<InputEventScreenDrag> event;
event.instance();
@@ -261,6 +286,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
ReleaseCapture();
}
+
+ // Release every touch to avoid sticky points
+ for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) {
+ _touch_event(false, E->get().x, E->get().y, E->key());
+ }
+ touch_state.clear();
+
break;
}
case WM_ACTIVATE: // Watch For Window Activate Message
@@ -664,7 +696,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
print_line("input lang change");
} break;
-#if WINVER >= 0x0601 // for windows 7
case WM_TOUCH: {
BOOL bHandled = FALSE;
@@ -677,10 +708,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
//do something with each touch input entry
if (ti.dwFlags & TOUCHEVENTF_MOVE) {
- _drag_event(ti.x / 100, ti.y / 100, ti.dwID);
+ _drag_event(ti.x / 100.0f, ti.y / 100.0f, ti.dwID);
} else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) {
- _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN != 0, ti.x / 100, ti.y / 100, ti.dwID);
+ _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, ti.x / 100.0f, ti.y / 100.0f, ti.dwID);
};
}
bHandled = TRUE;
@@ -698,7 +729,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} break;
-#endif
case WM_DEVICECHANGE: {
joypad->probe_joypads();
@@ -1044,6 +1074,8 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
+
+ gl_context->set_use_vsync(video_mode.use_vsync);
#endif
visual_server = memnew(VisualServerRaster);
@@ -1052,12 +1084,6 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- if (!is_no_window_mode_enabled()) {
- ShowWindow(hWnd, SW_SHOW); // Show The Window
- SetForegroundWindow(hWnd); // Slightly Higher Priority
- SetFocus(hWnd); // Sets Keyboard Focus To
- }
-
/*
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
@@ -1088,13 +1114,19 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
- //RegisterTouchWindow(hWnd, 0); // Windows 7
+ RegisterTouchWindow(hWnd, 0);
- _ensure_data_dir();
+ _ensure_user_data_dir();
DragAcceptFiles(hWnd, true);
move_timer_id = 1;
+
+ if (!is_no_window_mode_enabled()) {
+ ShowWindow(hWnd, SW_SHOW); // Show The Window
+ SetForegroundWindow(hWnd); // Slightly Higher Priority
+ SetFocus(hWnd); // Sets Keyboard Focus To
+ }
}
void OS_Windows::set_clipboard(const String &p_text) {
@@ -1196,6 +1228,7 @@ void OS_Windows::finalize() {
memdelete(joypad);
memdelete(input);
+ touch_state.clear();
visual_server->finish();
memdelete(visual_server);
@@ -1220,7 +1253,7 @@ void OS_Windows::finalize_core() {
memdelete(process_map);
TCPServerWinsock::cleanup();
- StreamPeerWinsock::cleanup();
+ StreamPeerTCPWinsock::cleanup();
}
void OS_Windows::alert(const String &p_alert, const String &p_title) {
@@ -1565,7 +1598,7 @@ bool OS_Windows::is_window_maximized() const {
return maximized;
}
-void OS_Windows::set_borderless_window(int p_borderless) {
+void OS_Windows::set_borderless_window(bool p_borderless) {
if (video_mode.borderless_window == p_borderless)
return;
@@ -1596,10 +1629,29 @@ void OS_Windows::_update_window_style(bool repaint) {
}
}
-Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle) {
- p_library_handle = (void *)LoadLibrary(p_path.utf8().get_data());
+Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+
+ typedef DLL_DIRECTORY_COOKIE(WINAPI * PAddDllDirectory)(PCWSTR);
+ typedef BOOL(WINAPI * PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
+
+ PAddDllDirectory add_dll_directory = (PAddDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "AddDllDirectory");
+ PRemoveDllDirectory remove_dll_directory = (PRemoveDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "RemoveDllDirectory");
+
+ bool has_dll_directory_api = ((add_dll_directory != NULL) && (remove_dll_directory != NULL));
+ DLL_DIRECTORY_COOKIE cookie;
+
+ if (p_also_set_library_path && has_dll_directory_api) {
+ cookie = add_dll_directory(p_path.get_base_dir().c_str());
+ }
+
+ p_library_handle = (void *)LoadLibraryExW(p_path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
+
+ if (p_also_set_library_path && has_dll_directory_api) {
+ remove_dll_directory(cookie);
+ }
+
if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError()));
+ ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + format_error_message(GetLastError()));
ERR_FAIL_V(ERR_CANT_OPEN);
}
return OK;
@@ -1851,7 +1903,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
modstr.resize(cmdline.size());
for (int i = 0; i < cmdline.size(); i++)
modstr[i] = cmdline[i];
- int ret = CreateProcessW(NULL, modstr.ptr(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi);
+ int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi);
ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
if (p_blocking) {
@@ -1962,7 +2014,7 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) {
bool OS_Windows::has_environment(const String &p_var) const {
- return getenv(p_var.utf8().get_data()) != NULL;
+ return _wgetenv(p_var.c_str()) != NULL;
};
String OS_Windows::get_environment(const String &p_var) const {
@@ -2104,6 +2156,10 @@ void OS_Windows::swap_buffers() {
gl_context->swap_buffers();
}
+void OS_Windows::force_process_input() {
+ process_events(); // get rid of pending events
+}
+
void OS_Windows::run() {
if (!main_loop)
@@ -2131,6 +2187,43 @@ MainLoop *OS_Windows::get_main_loop() const {
return main_loop;
}
+String OS_Windows::get_config_path() const {
+
+ if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not?
+ return get_environment("XDG_CONFIG_HOME");
+ } else if (has_environment("APPDATA")) {
+ return get_environment("APPDATA");
+ } else {
+ return ".";
+ }
+}
+
+String OS_Windows::get_data_path() const {
+
+ if (has_environment("XDG_DATA_HOME")) {
+ return get_environment("XDG_DATA_HOME");
+ } else {
+ return get_config_path();
+ }
+}
+
+String OS_Windows::get_cache_path() const {
+
+ if (has_environment("XDG_CACHE_HOME")) {
+ return get_environment("XDG_CACHE_HOME");
+ } else if (has_environment("TEMP")) {
+ return get_environment("TEMP");
+ } else {
+ return get_config_path();
+ }
+}
+
+// Get properly capitalized engine name for system paths
+String OS_Windows::get_godot_dir_name() const {
+
+ return String(VERSION_SHORT_NAME).capitalize();
+}
+
String OS_Windows::get_system_dir(SystemDir p_dir) const {
int id;
@@ -2167,18 +2260,20 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const {
ERR_FAIL_COND_V(res != S_OK, String());
return String(szPath);
}
-String OS_Windows::get_data_dir() const {
- String an = get_safe_application_name();
- if (an != "") {
+String OS_Windows::get_user_data_dir() const {
- if (has_environment("APPDATA")) {
-
- bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir");
- if (!use_godot)
- return (OS::get_singleton()->get_environment("APPDATA") + "/" + an).replace("\\", "/");
- else
- return (OS::get_singleton()->get_environment("APPDATA") + "/Godot/app_userdata/" + an).replace("\\", "/");
+ String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
+ if (appname != "") {
+ bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
+ if (use_custom_dir) {
+ String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true);
+ if (custom_dir == "") {
+ custom_dir = appname;
+ }
+ return get_data_path().plus_file(custom_dir).replace("\\", "/");
+ } else {
+ return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname).replace("\\", "/");
}
}
@@ -2289,7 +2384,9 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
AudioDriverManager::add_driver(&driver_xaudio2);
#endif
- _set_logger(memnew(WindowsTerminalLogger));
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(WindowsTerminalLogger));
+ _set_logger(memnew(CompositeLogger(loggers)));
}
OS_Windows::~OS_Windows() {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index fbd60e5f0d..f2226a53a9 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -117,6 +117,7 @@ class OS_Windows : public OS {
InputDefault *input;
JoypadWindows *joypad;
+ Map<int, Vector2> touch_state;
PowerWindows *power_manager;
@@ -132,8 +133,8 @@ class OS_Windows : public OS {
CrashHandler crash_handler;
- void _drag_event(int p_x, int p_y, int idx);
- void _touch_event(bool p_pressed, int p_x, int p_y, int idx);
+ void _drag_event(float p_x, float p_y, int idx);
+ void _touch_event(bool p_pressed, float p_x, float p_y, int idx);
void _update_window_style(bool repaint = true);
@@ -145,7 +146,6 @@ protected:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -210,10 +210,10 @@ public:
virtual bool is_window_maximized() const;
virtual void request_attention();
- virtual void set_borderless_window(int p_borderless);
+ virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window();
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
virtual Error close_dynamic_library(void *p_library_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
@@ -253,8 +253,14 @@ public:
virtual void enable_for_stealing_focus(ProcessID pid);
virtual void move_window_to_foreground();
- virtual String get_data_dir() const;
+
+ virtual String get_config_path() const;
+ virtual String get_data_path() const;
+ virtual String get_cache_path() const;
+ virtual String get_godot_dir_name() const;
+
virtual String get_system_dir(SystemDir p_dir) const;
+ virtual String get_user_data_dir() const;
virtual void release_rendering_thread();
virtual void make_rendering_thread();
@@ -281,6 +287,8 @@ public:
void disable_crash_handler();
bool is_disable_crash_handler() const;
+ void force_process_input();
+
virtual Error move_to_trash(const String &p_path);
OS_Windows(HINSTANCE _hInstance);
diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp
deleted file mode 100644
index d414ec891e..0000000000
--- a/platform/windows/packet_peer_udp_winsock.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/*************************************************************************/
-/* packet_peer_udp_winsock.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "packet_peer_udp_winsock.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include "drivers/unix/socket_helpers.h"
-
-int PacketPeerUDPWinsock::get_available_packet_count() const {
-
- Error err = const_cast<PacketPeerUDPWinsock *>(this)->_poll(false);
- if (err != OK)
- return 0;
-
- return queue_count;
-}
-
-Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer, int &r_buffer_size) const {
-
- Error err = const_cast<PacketPeerUDPWinsock *>(this)->_poll(false);
- if (err != OK)
- return err;
- if (queue_count == 0)
- return ERR_UNAVAILABLE;
-
- uint32_t size;
- uint8_t type;
- rb.read(&type, 1, true);
- if (type == IP::TYPE_IPV4) {
- uint8_t ip[4];
- rb.read(ip, 4, true);
- packet_ip.set_ipv4(ip);
- } else {
- uint8_t ip[16];
- rb.read(ip, 16, true);
- packet_ip.set_ipv6(ip);
- };
- rb.read((uint8_t *)&packet_port, 4, true);
- rb.read((uint8_t *)&size, 4, true);
- rb.read(packet_buffer, size, true);
- --queue_count;
- *r_buffer = packet_buffer;
- r_buffer_size = size;
- return OK;
-}
-Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
- ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED);
-
- if (sock_type == IP::TYPE_NONE)
- sock_type = peer_addr.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
-
- int sock = _get_socket();
- ERR_FAIL_COND_V(sock == -1, FAILED);
- struct sockaddr_storage addr;
- size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type);
-
- _set_sock_blocking(blocking);
-
- errno = 0;
- int err;
- while ((err = sendto(sock, (const char *)p_buffer, p_buffer_size, 0, (struct sockaddr *)&addr, addr_size)) != p_buffer_size) {
-
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- return FAILED;
- } else if (!blocking) {
- return ERR_UNAVAILABLE;
- }
- }
-
- return OK;
-}
-
-int PacketPeerUDPWinsock::get_max_packet_size() const {
-
- return 512; // uhm maybe not
-}
-
-void PacketPeerUDPWinsock::_set_sock_blocking(bool p_blocking) {
-
- if (sock_blocking == p_blocking)
- return;
-
- sock_blocking = p_blocking;
- unsigned long par = sock_blocking ? 0 : 1;
- if (ioctlsocket(sockfd, FIONBIO, &par)) {
- perror("setting non-block mode");
- //close();
- //return -1;
- };
-}
-
-Error PacketPeerUDPWinsock::listen(int p_port, const IP_Address &p_bind_address, int p_recv_buffer_size) {
-
- ERR_FAIL_COND_V(sockfd != -1, ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
-
- sock_type = IP::TYPE_ANY;
-
- if (p_bind_address.is_valid())
- sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
-
- int sock = _get_socket();
- if (sock == -1)
- return ERR_CANT_CREATE;
-
- struct sockaddr_storage addr = { 0 };
- size_t addr_size = _set_listen_sockaddr(&addr, p_port, sock_type, IP_Address());
-
- if (bind(sock, (struct sockaddr *)&addr, addr_size) == -1) {
- close();
- return ERR_UNAVAILABLE;
- }
-
- printf("UDP Connection listening on port %i\n", p_port);
- rb.resize(nearest_shift(p_recv_buffer_size));
- return OK;
-}
-
-void PacketPeerUDPWinsock::close() {
-
- if (sockfd != -1)
- ::closesocket(sockfd);
- sockfd = -1;
- sock_type = IP::TYPE_NONE;
- rb.resize(16);
- queue_count = 0;
-}
-
-Error PacketPeerUDPWinsock::wait() {
-
- return _poll(true);
-}
-Error PacketPeerUDPWinsock::_poll(bool p_wait) {
-
- if (sockfd == -1) {
- return FAILED;
- }
-
- _set_sock_blocking(p_wait);
-
- struct sockaddr_storage from = { 0 };
- int len = sizeof(struct sockaddr_storage);
- int ret;
- while ((ret = recvfrom(sockfd, (char *)recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), 0, (struct sockaddr *)&from, &len)) > 0) {
-
- uint32_t port = 0;
-
- if (from.ss_family == AF_INET) {
- uint8_t type = (uint8_t)IP::TYPE_IPV4;
- rb.write(&type, 1);
- struct sockaddr_in *sin_from = (struct sockaddr_in *)&from;
- rb.write((uint8_t *)&sin_from->sin_addr, 4);
- port = ntohs(sin_from->sin_port);
-
- } else if (from.ss_family == AF_INET6) {
-
- uint8_t type = (uint8_t)IP::TYPE_IPV6;
- rb.write(&type, 1);
-
- struct sockaddr_in6 *s6_from = (struct sockaddr_in6 *)&from;
- rb.write((uint8_t *)&s6_from->sin6_addr, 16);
-
- port = ntohs(s6_from->sin6_port);
-
- } else {
- // WARN_PRINT("Ignoring packet with unknown address family");
- uint8_t type = (uint8_t)IP::TYPE_NONE;
- rb.write(&type, 1);
- };
-
- rb.write((uint8_t *)&port, 4);
- rb.write((uint8_t *)&ret, 4);
- rb.write(recv_buffer, ret);
-
- len = sizeof(struct sockaddr_storage);
- ++queue_count;
- if (p_wait)
- break;
- };
-
- if (ret == SOCKET_ERROR) {
- int error = WSAGetLastError();
-
- if (error == WSAEWOULDBLOCK) {
- // Expected when doing non-blocking sockets, retry later.
- } else if (error == WSAECONNRESET) {
- // If the remote target does not accept messages, this error may occur, but is harmless.
- // Once the remote target gets available, this message will disappear for new messages.
- } else {
- close();
- return FAILED;
- }
- }
-
- if (ret == 0) {
- close();
- return FAILED;
- };
-
- return OK;
-}
-
-bool PacketPeerUDPWinsock::is_listening() const {
-
- return sockfd != -1;
-}
-
-IP_Address PacketPeerUDPWinsock::get_packet_address() const {
-
- return packet_ip;
-}
-
-int PacketPeerUDPWinsock::get_packet_port() const {
-
- return packet_port;
-}
-
-int PacketPeerUDPWinsock::_get_socket() {
-
- ERR_FAIL_COND_V(sock_type == IP::TYPE_NONE, -1);
-
- if (sockfd != -1)
- return sockfd;
-
- sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP);
-
- if (sockfd != -1)
- _set_sock_blocking(false);
-
- return sockfd;
-}
-
-void PacketPeerUDPWinsock::set_dest_address(const IP_Address &p_address, int p_port) {
-
- peer_addr = p_address;
- peer_port = p_port;
-}
-
-void PacketPeerUDPWinsock::make_default() {
-
- PacketPeerUDP::_create = PacketPeerUDPWinsock::_create;
-};
-
-PacketPeerUDP *PacketPeerUDPWinsock::_create() {
-
- return memnew(PacketPeerUDPWinsock);
-};
-
-PacketPeerUDPWinsock::PacketPeerUDPWinsock() {
-
- blocking = true;
- sock_blocking = true;
- sockfd = -1;
- packet_port = 0;
- queue_count = 0;
- peer_port = 0;
- sock_type = IP::TYPE_NONE;
- rb.resize(16);
-}
-
-PacketPeerUDPWinsock::~PacketPeerUDPWinsock() {
-
- close();
-}
diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp
index 8d86f160f1..cc452d774d 100644
--- a/platform/windows/power_windows.cpp
+++ b/platform/windows/power_windows.cpp
@@ -121,8 +121,10 @@ int PowerWindows::get_power_percent_left() {
}
}
-PowerWindows::PowerWindows()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerWindows::PowerWindows() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
PowerWindows::~PowerWindows() {
diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp
deleted file mode 100644
index a9d9cb9373..0000000000
--- a/platform/windows/stream_peer_winsock.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*************************************************************************/
-/* stream_peer_winsock.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#ifdef WINDOWS_ENABLED
-
-#include "stream_peer_winsock.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include "drivers/unix/socket_helpers.h"
-
-int winsock_refcount = 0;
-
-StreamPeerTCP *StreamPeerWinsock::_create() {
-
- return memnew(StreamPeerWinsock);
-};
-
-void StreamPeerWinsock::make_default() {
-
- StreamPeerTCP::_create = StreamPeerWinsock::_create;
-
- if (winsock_refcount == 0) {
- WSADATA data;
- WSAStartup(MAKEWORD(2, 2), &data);
- };
- ++winsock_refcount;
-};
-
-void StreamPeerWinsock::cleanup() {
-
- --winsock_refcount;
- if (winsock_refcount == 0) {
-
- WSACleanup();
- };
-};
-
-Error StreamPeerWinsock::_block(int p_sockfd, bool p_read, bool p_write) const {
-
- fd_set read, write;
- FD_ZERO(&read);
- FD_ZERO(&write);
-
- if (p_read)
- FD_SET(p_sockfd, &read);
- if (p_write)
- FD_SET(p_sockfd, &write);
-
- int ret = select(p_sockfd + 1, &read, &write, NULL, NULL); // block forever
- return ret < 0 ? FAILED : OK;
-};
-
-Error StreamPeerWinsock::_poll_connection() const {
-
- ERR_FAIL_COND_V(status != STATUS_CONNECTING || sockfd == INVALID_SOCKET, FAILED);
-
- struct sockaddr_storage their_addr;
- size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port, sock_type);
-
- if (::connect(sockfd, (struct sockaddr *)&their_addr, addr_size) == SOCKET_ERROR) {
-
- int err = WSAGetLastError();
- if (err == WSAEISCONN) {
- status = STATUS_CONNECTED;
- return OK;
- };
-
- if (err == WSAEINPROGRESS || err == WSAEALREADY) {
- return OK;
- }
-
- status = STATUS_ERROR;
- return ERR_CONNECTION_ERROR;
- } else {
-
- status = STATUS_CONNECTED;
- return OK;
- };
-
- return OK;
-};
-
-Error StreamPeerWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) {
-
- if (status == STATUS_NONE || status == STATUS_ERROR) {
-
- return FAILED;
- };
-
- if (status != STATUS_CONNECTED) {
-
- if (_poll_connection() != OK) {
-
- return FAILED;
- };
-
- if (status != STATUS_CONNECTED) {
- r_sent = 0;
- return OK;
- };
- };
-
- int data_to_send = p_bytes;
- const uint8_t *offset = p_data;
- if (sockfd == -1) return FAILED;
- int total_sent = 0;
-
- while (data_to_send) {
-
- int sent_amount = send(sockfd, (const char *)offset, data_to_send, 0);
-
- if (sent_amount == -1) {
-
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
-
- perror("shit?");
- disconnect_from_host();
- ERR_PRINT("Server disconnected!\n");
- return FAILED;
- };
-
- if (!p_block) {
- r_sent = total_sent;
- return OK;
- };
-
- _block(sockfd, false, true);
- } else {
-
- data_to_send -= sent_amount;
- offset += sent_amount;
- total_sent += sent_amount;
- };
- }
-
- r_sent = total_sent;
-
- return OK;
-};
-
-Error StreamPeerWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) {
-
- if (!is_connected_to_host()) {
-
- return FAILED;
- };
-
- if (status != STATUS_CONNECTED) {
-
- if (_poll_connection() != OK) {
-
- return FAILED;
- };
-
- if (status != STATUS_CONNECTED) {
- r_received = 0;
- return OK;
- };
- };
-
- int to_read = p_bytes;
- int total_read = 0;
-
- while (to_read) {
-
- int read = recv(sockfd, (char *)p_buffer + total_read, to_read, 0);
-
- if (read == -1) {
-
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
-
- perror("shit?");
- disconnect_from_host();
- ERR_PRINT("Server disconnected!\n");
- return FAILED;
- };
-
- if (!p_block) {
-
- r_received = total_read;
- return OK;
- };
- _block(sockfd, true, false);
- } else if (read == 0) {
- disconnect_from_host();
- return ERR_FILE_EOF;
- } else {
-
- to_read -= read;
- total_read += read;
- };
- };
-
- r_received = total_read;
-
- return OK;
-};
-
-Error StreamPeerWinsock::put_data(const uint8_t *p_data, int p_bytes) {
-
- int total;
- return write(p_data, p_bytes, total, true);
-};
-
-Error StreamPeerWinsock::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
-
- return write(p_data, p_bytes, r_sent, false);
-};
-
-Error StreamPeerWinsock::get_data(uint8_t *p_buffer, int p_bytes) {
-
- int total;
- return read(p_buffer, p_bytes, total, true);
-};
-
-Error StreamPeerWinsock::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
-
- return read(p_buffer, p_bytes, r_received, false);
-};
-
-StreamPeerTCP::Status StreamPeerWinsock::get_status() const {
-
- if (status == STATUS_CONNECTING) {
- _poll_connection();
- };
-
- return status;
-};
-
-bool StreamPeerWinsock::is_connected_to_host() const {
-
- if (status == STATUS_NONE || status == STATUS_ERROR) {
-
- return false;
- };
- if (status != STATUS_CONNECTED) {
- return true;
- };
-
- return (sockfd != INVALID_SOCKET);
-};
-
-void StreamPeerWinsock::disconnect_from_host() {
-
- if (sockfd != INVALID_SOCKET)
- closesocket(sockfd);
- sockfd = INVALID_SOCKET;
- sock_type = IP::TYPE_NONE;
-
- status = STATUS_NONE;
-
- peer_host = IP_Address();
- peer_port = 0;
-};
-
-void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_sock_type) {
-
- sockfd = p_sockfd;
- sock_type = p_sock_type;
- status = STATUS_CONNECTING;
- peer_host = p_host;
- peer_port = p_port;
-};
-
-Error StreamPeerWinsock::connect_to_host(const IP_Address &p_host, uint16_t p_port) {
-
- ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
-
- sock_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
- sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP);
- if (sockfd == INVALID_SOCKET) {
- ERR_PRINT("Socket creation failed!");
- disconnect_from_host();
- //perror("socket");
- return FAILED;
- };
-
- unsigned long par = 1;
- if (ioctlsocket(sockfd, FIONBIO, &par)) {
- perror("setting non-block mode");
- disconnect_from_host();
- return FAILED;
- };
-
- struct sockaddr_storage their_addr;
- size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, sock_type);
-
- if (::connect(sockfd, (struct sockaddr *)&their_addr, addr_size) == SOCKET_ERROR) {
-
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- ERR_PRINT("Connection to remote host failed!");
- disconnect_from_host();
- return FAILED;
- };
- status = STATUS_CONNECTING;
- } else {
- status = STATUS_CONNECTED;
- };
-
- peer_host = p_host;
- peer_port = p_port;
-
- return OK;
-};
-
-void StreamPeerWinsock::set_nodelay(bool p_enabled) {
- ERR_FAIL_COND(!is_connected_to_host());
- int flag = p_enabled ? 1 : 0;
- setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
-}
-
-int StreamPeerWinsock::get_available_bytes() const {
-
- unsigned long len;
- int ret = ioctlsocket(sockfd, FIONREAD, &len);
- ERR_FAIL_COND_V(ret == -1, 0)
- return len;
-}
-
-IP_Address StreamPeerWinsock::get_connected_host() const {
-
- return peer_host;
-};
-
-uint16_t StreamPeerWinsock::get_connected_port() const {
-
- return peer_port;
-};
-
-StreamPeerWinsock::StreamPeerWinsock() {
-
- sock_type = IP::TYPE_NONE;
- sockfd = INVALID_SOCKET;
- status = STATUS_NONE;
- peer_port = 0;
-};
-
-StreamPeerWinsock::~StreamPeerWinsock() {
-
- disconnect_from_host();
-};
-
-#endif
diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp
deleted file mode 100644
index de300befa7..0000000000
--- a/platform/windows/tcp_server_winsock.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*************************************************************************/
-/* tcp_server_winsock.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#include "tcp_server_winsock.h"
-
-#include "stream_peer_winsock.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include "drivers/unix/socket_helpers.h"
-
-extern int winsock_refcount;
-
-TCP_Server *TCPServerWinsock::_create() {
-
- return memnew(TCPServerWinsock);
-};
-
-void TCPServerWinsock::make_default() {
-
- TCP_Server::_create = TCPServerWinsock::_create;
-
- if (winsock_refcount == 0) {
- WSADATA data;
- WSAStartup(MAKEWORD(2, 2), &data);
- };
- ++winsock_refcount;
-};
-
-void TCPServerWinsock::cleanup() {
-
- --winsock_refcount;
- if (winsock_refcount == 0) {
-
- WSACleanup();
- };
-};
-
-Error TCPServerWinsock::listen(uint16_t p_port, const IP_Address &p_bind_address) {
-
- ERR_FAIL_COND_V(listen_sockfd != -1, ERR_ALREADY_IN_USE);
- ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
-
- int sockfd;
- sock_type = IP::TYPE_ANY;
-
- // If the bind address is valid use its type as the socket type
- if (p_bind_address.is_valid())
- sock_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
-
- sockfd = _socket_create(sock_type, SOCK_STREAM, IPPROTO_TCP);
- ERR_FAIL_COND_V(sockfd == INVALID_SOCKET, FAILED);
-
- unsigned long par = 1;
- if (ioctlsocket(sockfd, FIONBIO, &par)) {
- perror("setting non-block mode");
- stop();
- return FAILED;
- };
-
- struct sockaddr_storage my_addr;
- size_t addr_size = _set_listen_sockaddr(&my_addr, p_port, sock_type, p_bind_address);
-
- int reuse = 1;
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0) {
-
- printf("REUSEADDR failed!");
- }
-
- if (bind(sockfd, (struct sockaddr *)&my_addr, addr_size) != SOCKET_ERROR) {
-
- if (::listen(sockfd, SOMAXCONN) == SOCKET_ERROR) {
-
- closesocket(sockfd);
- ERR_FAIL_V(FAILED);
- };
- } else {
- return ERR_ALREADY_IN_USE;
- };
-
- if (listen_sockfd != INVALID_SOCKET) {
-
- stop();
- };
-
- listen_sockfd = sockfd;
-
- return OK;
-};
-
-bool TCPServerWinsock::is_connection_available() const {
-
- if (listen_sockfd == -1) {
- return false;
- };
-
- timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- fd_set pfd;
- FD_ZERO(&pfd);
- FD_SET(listen_sockfd, &pfd);
-
- int ret = select(listen_sockfd + 1, &pfd, NULL, NULL, &timeout);
- ERR_FAIL_COND_V(ret < 0, 0);
-
- if (ret && (FD_ISSET(listen_sockfd, &pfd))) {
-
- return true;
- };
-
- return false;
-};
-
-Ref<StreamPeerTCP> TCPServerWinsock::take_connection() {
-
- if (!is_connection_available()) {
- return NULL;
- };
-
- struct sockaddr_storage their_addr;
- int sin_size = sizeof(their_addr);
- int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &sin_size);
- ERR_FAIL_COND_V(fd == INVALID_SOCKET, NULL);
-
- Ref<StreamPeerWinsock> conn = memnew(StreamPeerWinsock);
- IP_Address ip;
- int port;
- _set_ip_addr_port(ip, port, &their_addr);
-
- conn->set_socket(fd, ip, port, sock_type);
-
- return conn;
-};
-
-void TCPServerWinsock::stop() {
-
- if (listen_sockfd != INVALID_SOCKET) {
- closesocket(listen_sockfd);
- };
-
- listen_sockfd = -1;
- sock_type = IP::TYPE_NONE;
-};
-
-TCPServerWinsock::TCPServerWinsock() {
-
- listen_sockfd = INVALID_SOCKET;
- sock_type = IP::TYPE_NONE;
-};
-
-TCPServerWinsock::~TCPServerWinsock() {
-
- stop();
-};
diff --git a/platform/x11/SCsub b/platform/x11/SCsub
index aabc49149f..38dd2ddd88 100644
--- a/platform/x11/SCsub
+++ b/platform/x11/SCsub
@@ -4,9 +4,9 @@ import os
Import('env')
def make_debug(target, source, env):
- os.system('objcopy --only-keep-debug %s %s.debug' % (target[0], target[0]))
+ os.system('objcopy --only-keep-debug %s %s.debugsymbols' % (target[0], target[0]))
os.system('strip --strip-debug --strip-unneeded %s' % (target[0]))
- os.system('objcopy --add-gnu-debuglink=%s.debug %s' % (target[0], target[0]))
+ os.system('objcopy --add-gnu-debuglink=%s.debugsymbols %s' % (target[0], target[0]))
common_x11 = [
"context_gl_x11.cpp",
@@ -17,6 +17,7 @@ common_x11 = [
"power_x11.cpp",
]
-binary = env.Program('#bin/godot', ['godot_x11.cpp'] + common_x11)
+prog = env.add_program('#bin/godot', ['godot_x11.cpp'] + common_x11)
+
if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes":
- env.AddPostAction(binary, make_debug)
+ env.AddPostAction(prog, make_debug)
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 4f9d4a84b9..61c6b3c9dd 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -228,8 +228,8 @@ bool ContextGL_X11::is_using_vsync() const {
return use_vsync;
}
-ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, bool p_opengl_3_context)
- : x11_window(p_x11_window) {
+ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, bool p_opengl_3_context) :
+ x11_window(p_x11_window) {
default_video_mode = p_default_video_mode;
x11_display = p_x11_display;
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 6bd0ac8317..09bf57c5f1 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -55,6 +55,7 @@ def get_opts():
BoolVariable('pulseaudio', 'Detect & use pulseaudio', True),
BoolVariable('udev', 'Use udev for gamepad connection callbacks', False),
EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')),
+ BoolVariable('touch', 'Enable touch events', True),
]
@@ -141,6 +142,14 @@ def configure(env):
env.ParseConfig('pkg-config xinerama --cflags --libs')
env.ParseConfig('pkg-config xrandr --cflags --libs')
+ if (env['touch']):
+ x11_error = os.system("pkg-config xi --modversion > /dev/null ")
+ if (x11_error):
+ print("xi not found.. cannot build with touch. Aborting.")
+ sys.exit(255)
+ env.ParseConfig('pkg-config xi --cflags --libs')
+ env.Append(CPPFLAGS=['-DTOUCH_ENABLED'])
+
# FIXME: Check for existence of the libs before parsing their flags with pkg-config
if not env['builtin_openssl']:
@@ -149,6 +158,7 @@ def configure(env):
if not env['builtin_libwebp']:
env.ParseConfig('pkg-config libwebp --cflags --libs')
+
# freetype depends on libpng and zlib, so bundling one of them while keeping others
# as shared libraries leads to weird issues
if env['builtin_freetype'] or env['builtin_libpng'] or env['builtin_zlib']:
@@ -236,7 +246,7 @@ def configure(env):
env.ParseConfig('pkg-config zlib --cflags --libs')
env.Append(CPPPATH=['#platform/x11'])
- env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
+ env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED', '-DGLES_OVER_GL'])
env.Append(LIBS=['GL', 'pthread'])
if (platform.system() == "Linux"):
@@ -254,5 +264,10 @@ def configure(env):
env.Append(CPPFLAGS=['-m64'])
env.Append(LINKFLAGS=['-m64', '-L/usr/lib/i686-linux-gnu'])
+
+ if env["openmp"]:
+ env.Append(CPPFLAGS=['-fopenmp'])
+ env.Append(LINKFLAGS=['-fopenmp'])
+
if env['use_static_cpp']:
env.Append(LINKFLAGS=['-static-libstdc++'])
diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp
index fdb43c9ae0..1baa3e127f 100644
--- a/platform/x11/export/export.cpp
+++ b/platform/x11/export/export.cpp
@@ -44,7 +44,8 @@ void register_x11_exporter() {
logo->create_from_image(img);
platform->set_logo(logo);
platform->set_name("Linux/X11");
- platform->set_extension("bin");
+ platform->set_extension("x86");
+ platform->set_extension("x86_64", "binary_format/64_bits");
platform->set_release_32("linux_x11_32_release");
platform->set_debug_32("linux_x11_32_debug");
platform->set_release_64("linux_x11_64_release");
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index f018145d82..0c0bc1a8a3 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -132,10 +132,9 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
// Try to support IME if detectable auto-repeat is supported
if (xkb_dar == True) {
-// Xutf8LookupString will be used later instead of XmbLookupString before
-// the multibyte sequences can be converted to unicode string.
-
#ifdef X_HAVE_UTF8_STRING
+ // Xutf8LookupString will be used later instead of XmbLookupString before
+ // the multibyte sequences can be converted to unicode string.
modifiers = XSetLocaleModifiers("");
#endif
}
@@ -178,6 +177,49 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
}
}
+#ifdef TOUCH_ENABLED
+ if (!XQueryExtension(x11_display, "XInputExtension", &touch.opcode, &event_base, &error_base)) {
+ fprintf(stderr, "XInput extension not available");
+ } else {
+ // 2.2 is the first release with multitouch
+ int xi_major = 2;
+ int xi_minor = 2;
+ if (XIQueryVersion(x11_display, &xi_major, &xi_minor) != Success) {
+ fprintf(stderr, "XInput 2.2 not available (server supports %d.%d)\n", xi_major, xi_minor);
+ touch.opcode = 0;
+ } else {
+ int dev_count;
+ XIDeviceInfo *info = XIQueryDevice(x11_display, XIAllDevices, &dev_count);
+
+ for (int i = 0; i < dev_count; i++) {
+ XIDeviceInfo *dev = &info[i];
+ if (!dev->enabled)
+ continue;
+ if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave))
+ continue;
+
+ bool direct_touch = false;
+ for (int j = 0; j < dev->num_classes; j++) {
+ if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
+ direct_touch = true;
+ break;
+ }
+ }
+ if (direct_touch) {
+ touch.devices.push_back(dev->deviceid);
+ fprintf(stderr, "Using touch device: %s\n", dev->name);
+ }
+ }
+
+ XIFreeDeviceInfo(info);
+
+ if (!touch.devices.size()) {
+ fprintf(stderr, "No touch devices found\n");
+ }
+ }
+ }
+#endif
+
xim = XOpenIM(x11_display, NULL, NULL, NULL);
if (xim == NULL) {
@@ -243,6 +285,8 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
RasterizerGLES3::make_current();
+ context_gl->set_use_vsync(current_videomode.use_vsync);
+
#endif
visual_server = memnew(VisualServerRaster);
@@ -250,41 +294,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
-
- // borderless fullscreen window mode
- if (current_videomode.fullscreen) {
- // set bypass compositor hint
- Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
- unsigned long compositing_disable_on = 1;
- XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
-
- // needed for lxde/openbox, possibly others
- Hints hints;
- Atom property;
- hints.flags = 2;
- hints.decorations = 0;
- property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
- XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
- XMapRaised(x11_display, x11_window);
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa);
- XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height);
-
- // code for netwm-compliants
- XEvent xev;
- Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
- Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
-
- memset(&xev, 0, sizeof(xev));
- xev.type = ClientMessage;
- xev.xclient.window = x11_window;
- xev.xclient.message_type = wm_state;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 1;
- xev.xclient.data.l[1] = fullscreen;
- xev.xclient.data.l[2] = 0;
-
- XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+ if (current_videomode.maximized) {
+ current_videomode.maximized = false;
+ set_window_maximized(true);
+ // borderless fullscreen window mode
+ } else if (current_videomode.fullscreen) {
+ current_videomode.fullscreen = false;
+ set_window_fullscreen(true);
} else if (current_videomode.borderless_window) {
Hints hints;
Atom property;
@@ -336,6 +352,34 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
XChangeWindowAttributes(x11_display, x11_window, CWEventMask, &new_attr);
+#ifdef TOUCH_ENABLED
+ if (touch.devices.size()) {
+
+ // Must be alive after this block
+ static unsigned char mask_data[XIMaskLen(XI_LASTEVENT)] = {};
+
+ touch.event_mask.deviceid = XIAllDevices;
+ touch.event_mask.mask_len = sizeof(mask_data);
+ touch.event_mask.mask = mask_data;
+
+ XISetMask(touch.event_mask.mask, XI_TouchBegin);
+ XISetMask(touch.event_mask.mask, XI_TouchUpdate);
+ XISetMask(touch.event_mask.mask, XI_TouchEnd);
+ XISetMask(touch.event_mask.mask, XI_TouchOwnership);
+
+ XISelectEvents(x11_display, x11_window, &touch.event_mask, 1);
+
+ // Disabled by now since grabbing also blocks mouse events
+ // (they are received as extended events instead of standard events)
+ /*XIClearMask(touch.event_mask.mask, XI_TouchOwnership);
+
+ // Grab touch devices to avoid OS gesture interference
+ for (int i = 0; i < touch.devices.size(); ++i) {
+ XIGrabDevice(x11_display, touch.devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &touch.event_mask);
+ }*/
+ }
+#endif
+
/* set the titlebar name */
XStoreName(x11_display, x11_window, "Godot");
@@ -464,9 +508,17 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
#ifdef JOYDEV_ENABLED
joypad = memnew(JoypadLinux(input));
#endif
- _ensure_data_dir();
+ _ensure_user_data_dir();
power_manager = memnew(PowerX11);
+
+ XEvent xevent;
+ while (XPending(x11_display) > 0) {
+ XNextEvent(x11_display, &xevent);
+ if (xevent.type == ConfigureNotify) {
+ _window_changed(&xevent);
+ }
+ }
}
void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
@@ -497,7 +549,7 @@ void OS_X11::finalize() {
memdelete(main_loop);
main_loop = NULL;
-/*
+ /*
if (debugger_connection_console) {
memdelete(debugger_connection_console);
}
@@ -506,6 +558,10 @@ void OS_X11::finalize() {
#ifdef JOYDEV_ENABLED
memdelete(joypad);
#endif
+#ifdef TOUCH_ENABLED
+ touch.devices.clear();
+ touch.state.clear();
+#endif
memdelete(input);
visual_server->finish();
@@ -648,6 +704,9 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con
}
void OS_X11::set_wm_fullscreen(bool p_enabled) {
+ if (current_videomode.fullscreen == p_enabled)
+ return;
+
if (p_enabled && !is_window_resizable()) {
// Set the window as resizable to prevent window managers to ignore the fullscreen state flag.
XSizeHints *xsh;
@@ -971,6 +1030,9 @@ bool OS_X11::is_window_minimized() const {
}
void OS_X11::set_window_maximized(bool p_enabled) {
+ if (is_window_maximized() == p_enabled)
+ return;
+
// Using EWMH -- Extended Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
@@ -1036,7 +1098,7 @@ bool OS_X11::is_window_maximized() const {
return false;
}
-void OS_X11::set_borderless_window(int p_borderless) {
+void OS_X11::set_borderless_window(bool p_borderless) {
if (current_videomode.borderless_window == p_borderless)
return;
@@ -1417,6 +1479,20 @@ static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p
return None;
}
+void OS_X11::_window_changed(XEvent *event) {
+
+ if (xic) {
+ // Not portable.
+ set_ime_position(Point2(0, 1));
+ }
+ if ((event->xconfigure.width == current_videomode.width) &&
+ (event->xconfigure.height == current_videomode.height))
+ return;
+
+ current_videomode.width = event->xconfigure.width;
+ current_videomode.height = event->xconfigure.height;
+}
+
void OS_X11::process_xevents() {
//printf("checking events %i\n", XPending(x11_display));
@@ -1434,6 +1510,69 @@ void OS_X11::process_xevents() {
continue;
}
+#ifdef TOUCH_ENABLED
+ if (XGetEventData(x11_display, &event.xcookie)) {
+
+ if (event.xcookie.type == GenericEvent && event.xcookie.extension == touch.opcode) {
+
+ XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
+ int index = event_data->detail;
+ Vector2 pos = Vector2(event_data->event_x, event_data->event_y);
+
+ switch (event_data->evtype) {
+
+ case XI_TouchBegin: // Fall-through
+ // Disabled hand-in-hand with the grabbing
+ //XIAllowTouchEvents(x11_display, event_data->deviceid, event_data->detail, x11_window, XIAcceptTouch);
+
+ case XI_TouchEnd: {
+
+ bool is_begin = event_data->evtype == XI_TouchBegin;
+
+ Ref<InputEventScreenTouch> st;
+ st.instance();
+ st->set_index(index);
+ st->set_position(pos);
+ st->set_pressed(is_begin);
+
+ if (is_begin) {
+ if (touch.state.has(index)) // Defensive
+ break;
+ touch.state[index] = pos;
+ input->parse_input_event(st);
+ } else {
+ if (!touch.state.has(index)) // Defensive
+ break;
+ touch.state.erase(index);
+ input->parse_input_event(st);
+ }
+ } break;
+
+ case XI_TouchUpdate: {
+
+ Map<int, Vector2>::Element *curr_pos_elem = touch.state.find(index);
+ if (!curr_pos_elem) { // Defensive
+ break;
+ }
+
+ if (curr_pos_elem->value() != pos) {
+
+ Ref<InputEventScreenDrag> sd;
+ sd.instance();
+ sd->set_index(index);
+ sd->set_position(pos);
+ sd->set_relative(pos - curr_pos_elem->value());
+ input->parse_input_event(sd);
+
+ curr_pos_elem->value() = pos;
+ }
+ } break;
+ }
+ }
+ }
+ XFreeEventData(x11_display, &event.xcookie);
+#endif
+
switch (event.type) {
case Expose:
Main::force_redraw();
@@ -1476,6 +1615,12 @@ void OS_X11::process_xevents() {
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime);
}
+#ifdef TOUCH_ENABLED
+ // Grab touch devices to avoid OS gesture interference
+ /*for (int i = 0; i < touch.devices.size(); ++i) {
+ XIGrabDevice(x11_display, touch.devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &touch.event_mask);
+ }*/
+#endif
if (xic) {
XSetICFocus(xic);
}
@@ -1492,24 +1637,30 @@ void OS_X11::process_xevents() {
}
XUngrabPointer(x11_display, CurrentTime);
}
+#ifdef TOUCH_ENABLED
+ // Ungrab touch devices so input works as usual while we are unfocused
+ /*for (int i = 0; i < touch.devices.size(); ++i) {
+ XIUngrabDevice(x11_display, touch.devices[i], CurrentTime);
+ }*/
+
+ // Release every pointer to avoid sticky points
+ for (Map<int, Vector2>::Element *E = touch.state.front(); E; E = E->next()) {
+
+ Ref<InputEventScreenTouch> st;
+ st.instance();
+ st->set_index(E->key());
+ st->set_position(E->get());
+ input->parse_input_event(st);
+ }
+ touch.state.clear();
+#endif
if (xic) {
XUnsetICFocus(xic);
}
break;
case ConfigureNotify:
- if (xic) {
- // Not portable.
- set_ime_position(Point2(0, 1));
- }
- /* call resizeGLScene only if our window-size changed */
-
- if ((event.xconfigure.width == current_videomode.width) &&
- (event.xconfigure.height == current_videomode.height))
- break;
-
- current_videomode.width = event.xconfigure.width;
- current_videomode.height = event.xconfigure.height;
+ _window_changed(&event);
break;
case ButtonPress:
case ButtonRelease: {
@@ -1941,6 +2092,39 @@ bool OS_X11::_check_internal_feature_support(const String &p_feature) {
return p_feature == "pc" || p_feature == "s3tc";
}
+String OS_X11::get_config_path() const {
+
+ if (has_environment("XDG_CONFIG_HOME")) {
+ return get_environment("XDG_CONFIG_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".config");
+ } else {
+ return ".";
+ }
+}
+
+String OS_X11::get_data_path() const {
+
+ if (has_environment("XDG_DATA_HOME")) {
+ return get_environment("XDG_DATA_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".local/share");
+ } else {
+ return get_config_path();
+ }
+}
+
+String OS_X11::get_cache_path() const {
+
+ if (has_environment("XDG_CACHE_HOME")) {
+ return get_environment("XDG_CACHE_HOME");
+ } else if (has_environment("HOME")) {
+ return get_environment("HOME").plus_file(".cache");
+ } else {
+ return get_config_path();
+ }
+}
+
String OS_X11::get_system_dir(SystemDir p_dir) const {
String xdgparam;
@@ -2080,6 +2264,13 @@ void OS_X11::set_icon(const Ref<Image> &p_icon) {
XFlush(x11_display);
}
+void OS_X11::force_process_input() {
+ process_xevents(); // get rid of pending events
+#ifdef JOYDEV_ENABLED
+ joypad->process_joypads();
+#endif
+}
+
void OS_X11::run() {
force_quit = false;
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 0ea5bbfdb6..c8cea1e30c 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -48,6 +48,9 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <X11/keysym.h>
+#ifdef TOUCH_ENABLED
+#include <X11/extensions/XInput2.h>
+#endif
// Hints for X11 fullscreen
typedef struct {
@@ -117,6 +120,14 @@ class OS_X11 : public OS_Unix {
Point2i last_click_pos;
uint64_t last_click_ms;
uint32_t last_button_state;
+#ifdef TOUCH_ENABLED
+ struct {
+ int opcode;
+ Vector<int> devices;
+ XIEventMask event_mask;
+ Map<int, Vector2> state;
+ } touch;
+#endif
unsigned int get_mouse_button_state(unsigned int p_x11_state);
void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
@@ -187,6 +198,8 @@ protected:
virtual void set_main_loop(MainLoop *p_main_loop);
+ void _window_changed(XEvent *xevent);
+
public:
virtual String get_name();
@@ -213,6 +226,10 @@ public:
virtual void make_rendering_thread();
virtual void swap_buffers();
+ virtual String get_config_path() const;
+ virtual String get_data_path() const;
+ virtual String get_cache_path() const;
+
virtual String get_system_dir(SystemDir p_dir) const;
virtual Error shell_open(String p_uri);
@@ -241,7 +258,7 @@ public:
virtual bool is_window_maximized() const;
virtual void request_attention();
- virtual void set_borderless_window(int p_borderless);
+ virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window();
virtual void set_ime_position(const Point2 &p_pos);
@@ -262,6 +279,7 @@ public:
virtual bool _check_internal_feature_support(const String &p_feature);
+ virtual void force_process_input();
void run();
void disable_crash_handler();
diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp
index 76ff7f91fb..0ef2629cb0 100644
--- a/platform/x11/power_x11.cpp
+++ b/platform/x11/power_x11.cpp
@@ -542,8 +542,10 @@ bool PowerX11::UpdatePowerInfo() {
return false;
}
-PowerX11::PowerX11()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerX11::PowerX11() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
PowerX11::~PowerX11() {